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:
_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:
_feeRatioBefore
uint64
Fee ratio before the increase
_feeRatioAdded
uint64
Fee ratio increased
Return Values:
_newFeeRatio
uint64
New fee ratio
_updateFeeRatio0
Update feeRatio0
by calling _calcFeeRatioAdded
and last update timestamp of token0.
Parameters:
_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:
_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:
_oldFeeRatio
uint64
Fee ratio from last update
_elapsedTime
uint
Time since last update
Return Values:
_newFeeRatio
uint64
New fee ratio
getFeeRatio
Get the fee ratios after halving update using calcNewFeeRatio
.
Return Values:
_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:
_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:
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:
input
uint
Amount of token0 to swap
minOutput
uint
Minimum amount of token1 expected to receive
Return values:
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:
input
uint
Amount of token1 to swap
minOutput
uint
Minimum amount of token0 expected to receive
Return values:
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:
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
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:
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:
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:
time
uint
Lock time. It can be either 1 day, 3 days, 7 days or 30 days
Return Valus:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
index
uint
Index of the note to be withdrawn.
to
address
Address to receive the redeemed token0 or token1
Return values:
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:
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:
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:
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:
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