Pair
FeeModel Contract
The FeeModel contract is specifically crafted to facilitate the calculation of trading fees, incorporating our economic formula.
_getFeeRatioStored
Get the stored variables including fee ratio and last update time of token0 and token1.
Return Values:
Name | Type | Description |
---|---|---|
_feeRatio0 | uint64 | Stored fee ratio of token0 |
_feeRatio1 | uint64 | Stored fee ratio of token1 |
_lastUpdateTime0 | uint64 | Stored last update time of token0 |
_lastUpdateTime1 | uint64 | Stored last update time of token1 |
_calcFeeRatioAdded
Calculate new fee ratio when fee ratio is increased.
Whenever a swap occurs that results in a y% decrease in the reserve of token0 in the pool, the system sets a fee of y% on token0. If the pool already had an x% fee at the time, an additional y% fee is added. For the new fee calculation formula please refer to below:
Formula: newFeeRatio = 1 - (1 - x%)(1 - y%)
Breaking down the formula, we can rearrange it as 1 - (1 - a)(1 - b) = a + b - ab
, reflecting the logic newFeeRatio = before + added - before * added
. Translating this formula into code, we get:
_newFeeRatio = uint64(before + added - before * added / MAX_FEE_RATIO);
MAX_FEE_RATIO
: In a typical scenario, the maximum fee ratio would be 1. However, in this context, we set the max fee ratio to2**64
due to limitations in the Solidity language (which does not support decimal numbers) and for the sake of simpler calculations. You'll notice that every time we calculate a feeRatio for a swap fee, we use the formula:fee = swapAmount * feeRatio / MAX_FEE_RATIO
.
Explore the Trading Fee Calculation section in our white paper for comprehensive insights into the fee calculation mechanism.
Parameters:
Name | Type | Description |
---|---|---|
_feeRatioBefore | uint64 | Fee ratio before the increase |
_feeRatioAdded | uint64 | Fee ratio increased |
Return Values:
Name | Type | Description |
---|---|---|
_newFeeRatio | uint64 | New fee ratio |
_updateFeeRatio0
Update feeRatio0
by calling _calcFeeRatioAdded
and last update timestamp of token0.
Parameters:
Name | Type | Description |
---|---|---|
_feeRatioBefore | uint64 | Fee ratio before the increase |
_feeRatioAdded | uint64 | Fee ratio increased |
_updateFeeRatio1
Update feeRatio1
by calling _calcFeeRatioAdded
and last update timestamp of token1.
Parameters:
Name | Type | Description |
---|---|---|
_feeRatioBefore | uint64 | Fee ratio before the increase |
_feeRatioAdded | uint64 | Fee ratio increased |
calcNewFeeRatio
Calculate new fee ratio as time elapsed.
For users, when a trade happens, the fee ratio will increase immediately and it will reduce the gap as time goes on. The change will keep going until the trading fee reduces to zero. Assuming the parameter of half-life is t, it means the trading fee will become times of the original every x
seconds.
Explore the Half-life t section in our white paper for comprehensive insights into the fee calculation mechanism.
Parameters:
Name | Type | Description |
---|---|---|
_oldFeeRatio | uint64 | Fee ratio from last update |
_elapsedTime | uint | Time since last update |
Return Values:
Name | Type | Description |
---|---|---|
_newFeeRatio | uint64 | New fee ratio |
getFeeRatio
Get the fee ratios after halving update using calcNewFeeRatio
.
Return Values:
Name | Type | Description |
---|---|---|
_feeRatio0 | uint64 | Fee ratio of token0 after halving update |
_feeRatio1 | uint64 | Fee ratio of token1 after halving update |
Feeswap Contract
The Feeswap contract, inheriting from the FeeModel contract, is crafted to implement virtual swap logic and manage trading fees.
initialize
Initialize the contract with token0 and token1 addresses.
Parameters:
Name | Type | Description |
---|---|---|
_token0 | address | token0 address |
_token1 | address | token1 address |
getReserves
Retrieve the current reserves for both token0 and token1. The reserves are calculated by subtracting the accumulatedFee from the pool token balance.
In our future vision, following each trade, 50% of the generated trading fees will be retained in the pool as Protocol Controlled Value (PCV). The yet-to-be-collected trading fee revenue is referred to as accumulatedFee. For instance, the formula to determine the token0 reserve in the pair is expressed as follows:
reserve0 = IERC20(token0).balanceOf(address(this)) - accumulatedFee0;
Explore the Fee Revenue Sharing section in our white paper for comprehensive insights into the fee calculation mechanism.
Return Values:
Name | Type | Description |
---|---|---|
reserve0 | uint | Current reserve of token0 |
reserve1 | uint | Current reserve of token1 |
_swap0in
Compute the swap fee and output amount based on the input amount, pool reserve, and fee ratio. Please note that this internal function solely handles the calculation and does not execute an actual swap.
Parameters:
Name | Type | Description |
---|---|---|
input | uint | Amount of token0 to swap |
minOutput | uint | Minimum amount of token1 expected to receive |
Return values:
Name | Type | Description |
---|---|---|
fee | uint | Amount of token0 as fee |
output | uint | Amount of token1 swapped |
_swap1in
Compute the swap fee and output amount based on the input amount, pool reserve, and fee ratio. Please note that this internal function solely handles the calculation and does not execute an actual swap.
Parameters:
Name | Type | Description |
---|---|---|
input | uint | Amount of token1 to swap |
minOutput | uint | Minimum amount of token0 expected to receive |
Return values:
Name | Type | Description |
---|---|---|
fee | uint | Amount of token1 as fee |
output | uint | Amount of token0 swapped |
swap0in
Execute a swap from token0 to token1 by following these steps:
Invoke the
_swap0in
function to obtain the fee and output amount.If the
feeTo
address in the contract is set, updateaccumulatedFee0
by incorporating half of the fee into it.Execute the actual swap.
Parameters:
Name | Type | Description |
---|---|---|
to | address | Address to receive swapped token1 |
input | uint | Amount of token0 to swap |
minOutput | uint | Minimum amount of token1 expected to receive |
Return Values
Name | Type | Description |
---|---|---|
output | uint | Amount of token1 swapped |
swap1in
Execute a swap from token1 to token0 by following these steps:
Invoke the
_swap1in
function to obtain the fee and output amount.If the
feeTo
address in the contract is set, updateaccumulatedFee1
by incorporating half of the fee into it.Execute the actual swap.
Parameters:
Name | Type | Description |
---|---|---|
to | address | Address to receive swapped token0 |
input | uint | Amount of token1 to swap |
minOutput | uint | Minimum amount of token0 expected to receive |
Return Valus:
Name | Type | Description |
---|---|---|
output | uint | Amount of token0 swapped |
collectFee
Collect accumulated fees and transfer to the fee recipient.
This function transfers the accumulatedFee0
and accumulatedFee1
of token0 and token1 to the feeTo
address if feeTo
is configured in the pair contract. After fee collection, both accumulatedFee0
and accumulatedFee1
will reset to zero.
Pair Contract
Pair, which inherits Feeswap contract, represents the pool contract in Dyson Finance. The Dyson Finance V1 supports WETH-USDC and DYSON-USDC pools.
getPremium
Calculate premium
based on the lock time of a dual investment deposit. The governance, or controller of the factory contract, has the authority to set the volatility, impacting the premium. The formula is expressed as follows:
Premium = volatility * sqrt(time / 365 days) * 0.4
Let's break down the formula using an example of investing for 1 day. In code, it looks like this:
premium = basis * 20936956903608548 / PREMIUM_BASE_UNIT
basis
: Represents the chosen volatility set by the governance.20936956903608548
: This is a pre-calculated result, representing the square root of (time / 365 days) * 0.4. This pre-calculation is done in advance to optimize gas usage.PREMIUM_BASE_UNIT
: It serves as a scaling factor, ensuring the correct scale is applied (set as 1e18).
You can explore the Dual Investment Premium calculation section in our white paper for comprehensive insights into the premium calculation mechanism.
Parameters:
Name | Type | Description |
---|---|---|
time | uint | Lock time. It can be either 1 day, 3 days, 7 days or 30 days |
Return Valus:
Name | Type | Description |
---|---|---|
premium | uint | Premium |
setBasis
Set the basis (volatility) parameter by the governance.
setHalfLife
Set the half-life parameter by the governance.
setFarm
Set the farm contract address by the governance.
setFeeTo
Set the fee recipient address by the governance.
rescueERC20
rescue token stucked in this contract
Parameters:
Name | Type | Description |
---|---|---|
tokenAddress | address | Address of token to be rescued |
to | address | Address that will receive token |
amount | uint | Amount of token to be rescued |
_addNote
Add new deposit note with adjusted amounts and due time.
This function computes the token0 and token1 amounts, inclusive of premiums, and stores them along with the deposit due time in a note within the Pair contract.
Parameters:
Name | Type | Description |
---|---|---|
to | address | Address of the user who will own the created note. |
depositToken0 | bool | A boolean indicating whether the deposit is in token0. |
token0Amt | uint | Amount of token0 deposited. |
token1Amt | uint | Amount of token1 deposited. |
time | uint | Lock time for the deposit. |
premium | uint | Premium, calculated based on the lock time. |
_grantSP
A Dyson Finance member depositing tokens for dual-investment earns SP, referred to as "Point" in our white paper. This function calculates the "localPoint" amount for the depositor using the formula:
localPoint = sqrt(input * output) * (premium / PREMIUM_BASE_UNIT)
.
For insights into premium calculation details, please refer to the Premium Base Unit. Once the localPoint is determined, the function calls farm.grantSP()
to convert it into actual points. For further understanding of point calculation, explore the grantSP section in the Farm contract.
Parameters:
Name | Type | Description |
---|---|---|
to | address | Address of the user to whom SP will be granted. |
input | uint | Input amount of the deposit. |
output | uint | Output amount of the deposit. |
premium | uint | Premium, calculated based on the lock time. |
deposit0
User deposit token0. This function execute the following steps:
Call
_swap0in()
to calculate swap fee and output (token1) amount.Call
_addNote()
to create a note for depositor.Calculate swap fee. Half of the swap fee goes to
feeTo
iffeeTo
is set.Transfer token0 in.
Call
_grantSP()
to generate SP for depositor.
Parameters:
Name | Type | Description |
---|---|---|
to | address | Address that owns the note |
input | uint | Amount of token0 to deposit |
minOutput | uint | Minimum amount of token1 expected to receive if the swap is performed |
time | uint | Lock time |
Return Values:
Name | Type | Description |
---|---|---|
output | uint | Amount of token1 received if the swap is performed |
deposit1
User deposit token1. This function execute the following steps:
Call
_swap1in()
to calculate swap fee and output (token0) amount.Call
_addNote()
to create a note for depositor.Calculate swap fee. Half of the swap fee goes to
feeTo
iffeeTo
is set.Transfer token1 in.
Call
_grantSP()
to generate SP for depositor.
Parameters:
Name | Type | Description |
---|---|---|
to | address | Address that owns the note |
input | uint | Amount of token1 to deposit |
minOutput | uint | Minimum amount of token0 expected to receive if the swap is performed |
time | uint | Lock time |
Return values:
Name | Type | Description |
---|---|---|
output | uint | Amount of token0 received if the swap is performed |
_withdraw
This internal function handles the withdrawal of funds represented by a specific note from the Dyson pair contract. It calculates the amounts of token0
and token1
to be withdrawn based on the stored note information and market conditions.
Parameters:
Name | Type | Description |
---|---|---|
from | address | Address of the user withdrawing |
index | uint | Index of the note to be withdrawn. |
to | address | Address to receive the redeemed token0 or token1 |
Return Values:
Name | Type | Description |
---|---|---|
token0Amt | address | Amount of token0 withdrawn |
token1Amt | uint | Amount of token1 withdrawn |
withdraw
This external function allows a user to withdraw funds represented by a specific note. It calls the internal _withdraw
function after acquiring a lock to prevent re-entrancy.
Parameters:
Name | Type | Description |
---|---|---|
index | uint | Index of the note to be withdrawn. |
to | address | Address to receive the redeemed token0 or token1 |
Return values:
Name | Type | Description |
---|---|---|
token0Amt | address | Amount of token0 withdrawn |
token1Amt | uint | Amount of token1 withdrawn |
withdrawFrom
This external function allows an approved operator to withdraw funds represented by a specific note on behalf of a user. It calls the internal _withdraw
function. Please refer to Perform a withdrawal to learn more about withdrawFrom
.
Parameters:
Name | Type | Description |
---|---|---|
from | address | Address of the user withdrawing |
index | uint | Index of the note to be withdrawn. |
to | address | Address to receive the redeemed token0 or token1 |
Return Values:
Name | Type | Description |
---|---|---|
token0Amt | address | Amount of token0 withdrawn |
token1Amt | uint | Amount of token1 withdrawn |
setApprovalForAllWithSig
This external function allows a user to approve or revoke an operator's ability to withdraw notes on their behalf using a signature. The signature must be valid and provided by the owner. Please refer to Perform a withdrawal to learn more about setApprovalForAllWithSig
.
Parameters:
Name | Type | Description |
---|---|---|
owner | address | Address of the user who owns the note |
operator | address | Address of the operator |
approved | bool | A boolean indicating whether to approve (true) or revoke (false) the operator. |
deadline | uint | Deadline for the approval signature. |
sig | bytes | The approval signature. |
setApprovalForAll
This external function allows a user to approve or revoke an operator's ability to withdraw notes on their behalf without using a signature. Please refer to Perform a withdrawal to learn more about setApprovalForAllWithSig
.
Parameters:
Name | Type | Description |
---|---|---|
operator | address | Address of the operator to be approved or revoked. |
approved | bool | A boolean indicating whether to approve (true) or revoke (false) the operator. |
Last updated