sDYSON
StakingRateModel Contract
The StakingRateModel
contract calculates the expected staking rate for locked DYSON tokens based on the duration. It uses the ABDKMath64x64 library for precision.
stakingRate
The stakingRate
function in the StakingRateModel
contract determines the expected staking rate, representing the conversion of $DYSN to $sDYSN, based on the specified lock duration. Key aspects include:
Validity Checks: The function ensures that the provided
lockDuration
falls within an acceptable range, requiring it to be more than30 minutes
but less than4 years
(1461 days).Calculation: Utilizing the ABDKMath64x64 library, the function computes and returns the $DYSN-$sDYSN conversion rate, represented in the red frame in the formula:
conversion rate (The red frame) = stakingRate * 2^(lockPeriod) / 16
The initial stakingRate, originally1e18
, is adjusted to0.0625e18
in our contract due to pre-division by 16. The stakingRate then doubles annually. LockPeriod represents the lock-up period (a year as a unit), calculated as:lockPeriod = (lockDuration + time_since_initial_time) / 1 year
Conclusions: 4 years lock-up period will get the complete conversion rate, as1e18
. 3 years lock-up period will get 50% conversion rate, as0.5e18
. 2 years lock-up period will get 25% conversion rate, as0.25e18
. 1 year lock-up period will get 12.5% conversion rate, as0.125e18
.
For a detailed understanding of the staking rate and the conversion from $DYSN to $sDYSN, please refer to the Conversion Rate section in our white paper.
function stakingRate(
uint lockDuration) external view returns (uint rate)
Parameters:
lockDuration
uint
Calculates the expected staking rate based on the lock duration and time since the initial time.
sDYSON Contract
sDYSON is an ERC20 contract for Staked $DYSON, supporting cross-chain transfers.
addMinter
Adds an address as a minter, allowing it to mint new sDYSON tokens.
function addMinter(
address _minter) external onlyOwner
Parameters:
_minter
address
Address to be added as a minter.
removeMinter
Removes an address from the list of minters, preventing it from minting new sDYSON tokens.
function removeMinter(
address _minter) external onlyOwner
Parameters:
_minter
address
Address to be removed from minters.
setUnbackedSupplyCap
Sets the cap for unbacked sDYSON supply.
function setUnbackedSupplyCap(
int256 _unbackedSupplyCap) external onlyOwner
Parameters:
_unbackedSupplyCap
int
New cap for unbacked sDYSON supply.
approve
Approves the spender to spend a specified amount of sDYSON tokens on behalf of the owner.
function approve(
address spender,
uint amount) external returns (bool)
Parameters:
spender
address
Address allowed to spend the tokens.
amount
uint
Amount of tokens to approve.
Return Values:
None
bool
Boolean indicating success.
transfer
Transfers a specified amount of sDYSON tokens to a target address.
function transfer(
address to,
uint amount) external returns (bool)
Parameters:
to
address
Address to which tokens will be transferred.
amount
uint
Amount of tokens to transfer.
Return Values:
None
bool
Boolean indicating success.
transferFrom
Transfers a specified amount of sDYSON tokens from one address to another, subject to approval.
function transferFrom(
address from,
address to,
uint amount) external returns (bool)
Parameters:
from
address
Address from which tokens will be transferred.
to
address
Address to which tokens will be transferred.
amount
uint
Amount of tokens to transfer.
Return Values:
None
bool
Boolean indicating success.
getStakingRate
Gets the staking rate based on the lock duration by calling stakingRate
function in StakingRateModel contract.
function getStakingRate(uint lockDuration) public view returns (uint rate)
Parameters:
lockDuration
uint
Duration for which DYSON tokens are locked.
Return Values:
rate
uint
Staking rate.
setStakingRateModel
Sets a new StakingRateModel contract.
function setStakingRateModel(
address newModel) external onlyOwner
Parameters:
newModel
address
Address of the new StakingRateModel contract.
setMigration
Sets a new migration contract for user vault migration.
function setMigration(
address _migration) external onlyOwner
Parameters:
_migration
address
Address of the new migration contract.
mint
This function generates unbacked sDYSON tokens for cross-chain transfers. It performs the following steps:
Verifies that the mint amount is below the
MAX_MINT_AMOUNT_LIMIT
, set at2^255
.Ensures the total unbacked supply remains under the specified
unbackedSupplyCap
after minting.Updates the unbacked supply.
Invokes the
_mint
function.
function mint(
address to,
uint amount) external returns (bool)
Parameters:
to
address
Address to receive the minted tokens.
amount
uint
Amount of tokens to mint.
Return Values:
None
bool
Boolean indicating success.
burn
Burns unbacked sDYSON tokens. This function burns unbacked sDYSON tokens for cross-chain transfers. It simply decreases unbacked supply and call _burn
function.
function burn(uint amount) external returns (bool)
Parameters:
amount
uint
Amount of tokens to burn.
Return Values:
None
bool
Boolean indicating success.
stake
This function allows users to stake DYSON tokens, earn sDYSON tokens based on the staking rate and lock duration, and records relevant details in the vault. Key actions performed by this function include:
Determining the sDYSON amount to be minted based on the staking rate and the provided lock duration.
Recording the staking details in the vault, including the amount of DYSON staked, the corresponding sDYSON amount, and the unlock time.
Updating the total DYSON amount staked and the voting power for the staker.
Minting the calculated sDYSON tokens and transferring the staked DYSON tokens to the contract.
The sDYSON amount to be minted is determined by the formula below:
sDysonAmount = getStakingRate(lockDuration) * amount / STAKING_RATE_BASE_UNIT
Here's a breakdown of the components in this formula:
amount
: The amount of DYSON tokens being staked.STAKING_RATE_BASE_UNIT
: A constant representing the base unit for the staking rate which is set as1e18
.getStakingRate(lockDuration)
: The staking rate calculated based on the lock duration using thegetStakingRate
function. It would be0 < stakingRate <= 1e18
.
function stake(
address to,
uint amount,
uint lockDuration) external returns (uint sDysonAmount)
Parameters:
to
address
Address that owns the new vault.
amount
uint
Amount of DYSON to stake.
lockDuration
uint
Duration to lock DYSON.
Return Values:
sDysonAmount
uint
Amount of sDYSON minted to the new vault.
restake
This function allows a user to stake additional DYSON tokens to an existing vault, extending the lock duration. The user can restake even when the vault is already unlocked, and the new unlock time must be greater than the old unlock time. The function calculates the additional sDYSON tokens to be minted based on the updated staking rate and the added DYSON amount.
the sDysonAmountNew
is calculated to determine the additional sDYSON tokens to be minted when a user restakes additional DYSON tokens to an existing vault. The formula used for this calculation is:
sDysonAmountNew = (vault.dysonAmount + amount) * getStakingRate(lockDuration) / STAKING_RATE_BASE_UNIT;
Here's a breakdown of the components in this formula:
vault.dysonAmount
: The current amount of DYSON tokens in the user's vault before the restake operation.amount
: The additional amount of DYSON tokens being staked in the restake operation.getStakingRate(lockDuration)
: The staking rate calculated based on the lock duration using thegetStakingRate
function.STAKING_RATE_BASE_UNIT
: A constant representing the base unit for the staking rate which is set as1e18
.
The formula combines the existing DYSON amount in the vault with the additional staked amount and adjusts it based on the calculated staking rate. The result is the new amount of sDYSON tokens to be minted and added to the user's vault.
This calculation ensures that the minted sDYSON amount accurately reflects the updated staking conditions, allowing users to receive rewards proportional to their additional stake and the adjusted staking rate.
function restake(
uint index,
uint amount,
uint lockDuration) external returns (uint sDysonAmountAdded)
Parameters:
index
uint
Index of the user's vault to restake.
amount
uint
Amount of DYSON to restake.
lockDuration
uint
Duration to lock DYSON.
Return Values:
sDysonAmountAdded
uint
Amount of new sDYSON minted to the user's vault.
unstake
This function performs the unstaking of sDYSON tokens and the corresponding withdrawal of DYSON tokens. Here are the key steps involved in the unstake
function:
Vault Retrieval & Unlock Time Check:
Retrieves the user's vault based on the provided
index
and checks if the unlock time for the vault has been reached (vault is unlocked).
Amount Calculation:
Calculates the amount of DYSON tokens to be withdrawn based on the proportion of
sDysonAmount
relative to the total sDYSON amount in the vault.
Vault Updates & Global Updates:
Updates the vault's
dysonAmount
andsDysonAmount
by subtracting the calculated amounts.Decreases the total DYSON amount staked and the user's voting power by the amounts withdrawn.
Token Transfer:
Calls the internal
_burn
function to burn the corresponding sDYSON tokens.Transfers the calculated amount of DYSON tokens from the contract to the specified
to
address.
function unstake(
address to,
uint index,
uint sDysonAmount) external returns (uint amount)
Parameters:
to
address
Address that will receive DYSON.
index
uint
Index of the user's vault to unstake.
sDysonAmount
uint
Amount of sDYSON to unstake.
Return Values:
amount
uint
Amount of DYSON transferred.
migrate
This function allows a user to migrate their vault to a new staking contract. The owner must set the migration contract before initiating migration, and the migration contract must implement the onMigrationReceived
function. The user specifies the index of the vault to migrate, and the associated DYSON and sDYSON amounts, along with the unlock time, are transferred to the migration contract. The migration contract is then notified of the migration.
function migrate(
uint index) external
Parameters:
index
uint
Index of the user's vault to migrate.
rescueERC20
function rescueERC20(
address tokenAddress,
address to,
uint256 amount) onlyOwner external
Parameters:
tokenAddress
address
Address of the ERC-20 token to be rescued.
to
address
Address that will receive the rescued tokens.
amount
uint
Amount of tokens to be rescued.
permit
Implements the EIP-2612 permit function, allowing an owner to approve token spending with a signature.
function permit(
address _owner,
address _spender,
uint256 _amount,
uint256 _deadline,
uint8 _v,
bytes32 _r,
bytes32 _s) external
Parameters:
_owner
address
Token owner's address.
_spender
address
Address allowed to spend the tokens.
_amount
uint
Amount of tokens to approve.
_deadline
uint
Deadline for the permit.
_v
uint8
Must produce a valid secp256k1 signature from the holder along with _r and _s.
_r
bytes32
Must produce a valid secp256k1 signature from the holder along with _v and _s.
_s
bytes32
Must produce a valid secp256k1 signature from the holder along with _v and _r.
Last updated