How Contracts and Operations Work
Each Covenants inflation contract is composed of one or more executable operations. Each operation can only circulate one token; to manage the inflation of two different tokens, two different operations are required.
An operation can involve any combination of the following:
The minting of the input token
The transferral of the input token from one address to one or more others
The swapping of the input token for one or more other tokens in one AMM
If an operation involves a swap, the input token
is the token being swapped , and the output token
is the token the input token is being swapped for. So, for example, if the operation will swap BUIDL for UniFi, BUIDL is the input token and UniFi is the output token.
If the operation involves a transfer, we have only one token, so the input-output dichotomy does not apply.
The contract is represented by the following struct in the contract:
name
-> represents the name of the contractblockInterval
-> the interval of time (expressed in blocks) that must pass between each execution of an operationlastBlock
-> the block of the most recently executed operation. Can be also used to program a delayed operation startcallerRewardPercentage
-> the reward the executor will receive. Allows the creation of an incentive for executing the operation with a public call, not only the call by the internal hosting of the contract. The executor can freely choose to be rewarded with either input or output tokens; for example, if the operation swaps BUIDL (input token) for ETH (output token), he can choose to be rewarded in either.
Every Fixed Inflation Operation has the following parameters:
inputTokenAddress
->address
of the operations' input tokeninputTokenAmount
->amount
of the input tokeninputTokenAmountIsPercentage
-> boolean value that expresses whether the amount of the input token (previous field) is expressed as a percentage value (true
) or not (false
).
If the InputTokenAmountIsPercentage
value is true
, the percentage is expressed in reference to the total supply of the input token. If the value is false
, only the amount is expressed.
ammPlugin
->address
of the AMM chosen to be used for possible token swap operations, this field is equal to0x0000000000000000000000000000000000000000
if the operation is atransfer
.liquidityPoolAddresses
-> array containing the liquidity pool tokenaddresses
of a swap operation (so this field is only populated if a swap operation is involved). The first element of the array must necessarily contain the input tokenswapPath
-> This array contains the path that the swap operation must follow (so this field is only populated if a swap operation is involved). Please refers to AMM Aggregator section for more details
So for example if you have an operation that swaps BUIDL to ETH and then to USDC, you'll have the liquidityPoolAddresses
containing BUIDL/ETH LP address
in the fist position and ETH/USDC LP address
in the second place. The swapPath
array will contain ETH in the first position and USDC in the second one.
enterInEth
-> expresses whether the input token is ETH (true
) or not (false
)exitInEth
-> expresses whether the output token is ETH (true
) or not (false
)receivers
-> array that contains the addresses of the various receivers in case of a transfer operationreceiversPercentages
-> array that contains the percentages of the various receivers in case of transfer operation. The length of this array must be equal toreceivers array length -1
, the last percentage is in fact calculated automatically.
Transfer Operations
Transfer operations are managed through the _transferTo
function, called internally at the time of execution:
erc20TokenAddress
->address
of the token on which to perform the transfer operationtotalAmount
-> token amount to transferrewardReceiver
-> address that will receive the reward for calling the execution of the operationcallerRewardPercentage
-> percentage of the transfer transaction the executor will receive as a rewardreceivers
-> array that contains theaddresses
of the receiver(s) of the transfer operationreceiversPercentages
-> array that contains the percentages of the receiver(s) of the transfer operation
The function calculates the reward amount for the executor using the _calculateRewardPercentage
function), sends it to the caller address and subtracts it from the total amount passed as totalAmount
:
Then, the amount of tokens to be sent as a fee to the Covenants DFO is calculated, sent to Covenants treasury and subtracted from the available token amount. So, at this moment, the token amount to be transferred is equal to the initial total amount - executor reward amount - DFO fee amount.
Below is the calculation of the amount of tokens to be transferred to each individual receiver via the _calculateRewardPercentage
function and sent to their respective addresses:
Swap Operations
Swap operations are managed through the _swap
function, called internally at the time of execution:
If the executor's reward is requested in input token, the amount is immediately calculated through the _calculateRewardPercentage
function.
Then, the SwapData
to be used by the AMM aggregator for swap operations is created as follow:
As you can see, the reward amount is expressed as the initial passed amount to be swapped minus the reward in case the reward is requested as input token.
Then, the swap operation is executed through the AMM Aggregator swapLiquidity
function, using the newly created swapData
:
At the end, the reward percentage
is transferred to the caller, whether it was requested in input token
or output token
Last updated