Overview
Last updated
Last updated
The liquidity mining staker design is comprised of one canonical position staking contract, Staker. The technical reference for this contract is and the source code is .
State:
Params:
createIncentive
creates a liquidity mining incentive program. The key used to look up an Incentive is the hash of its immutable properties.
Check:
Incentive with these params does not already exist
Timestamps: params.endTime >= params.startTime
, params.startTime >= block.timestamp
Incentive with this ID does not already exist.
Effects:
Sets incentives[key] = Incentive(totalRewardUnclaimed=totalReward, totalSecondsClaimedX128=0, rewardToken=rewardToken)
Interaction:
Transfers params.totalReward
from msg.sender
to self.
Make sure there is a check here and it fails if the transfer fails
Emits IncentiveCreated
endIncentive
can be called by anyone to end an Incentive after the endTime
has passed, transferring totalRewardUnclaimed
of rewardToken
back to refundee
.
Check:
block.timestamp > params.endTime
Incentive exists (incentive.totalRewardUnclaimed != 0
)
Effects:
deletes incentives[key]
(This is a new change)
Interactions:
safeTransfers totalRewardUnclaimed
of rewardToken
to the incentive creator msg.sender
emits IncentiveEnded
Interactions
nonfungiblePositionManager.safeTransferFrom(sender, this, tokenId)
This transfer triggers the onERC721Received hook
Check:
Make sure sender is dragonswapV2 nft
Effects:
Creates a deposit for the token setting deposit owner
to from
.
Setting owner
to from
ensures that the owner of the token also owns the deposit. Approved addresses and operators may first transfer the token to themselves before depositing for deposit ownership.
If data.length>0
, stakes the token in one or more incentives
Checks
Check that a Deposit exists for the token and that msg.sender
is the owner
on that Deposit.
Check that numberOfStakes
on that Deposit is 0.
Effects
Delete the Deposit delete deposits[tokenId]
.
Interactions
safeTransferFrom
the token to to
with data
.
emit DepositTransferred(token, deposit.owner, address(0))
Check:
deposits[params.tokenId].owner == msg.sender
Make sure incentive actually exists and has reward that could be claimed (incentive.rewardToken != address(0))
Check if this check can check totalRewardUnclaimed instead
Make sure token not already staked
Interactions
msg.sender
to withdraw all of their reward balance in a specific token to a specified to
address.
emit RewardClaimed(to, reward)
To unstake an NFT, you call unstakeToken
, which takes all the same arguments as stake
.
Checks
It checks that you are the owner of the Deposit
It checks that there exists a Stake
for the provided key (with exists=true).
Effects
Deletes the Stake.
Decrements numberOfStakes
for the Deposit by 1.
totalRewardsUnclaimed
is decremented by reward
.
totalSecondsClaimed
is incremented by seconds
.
Increments rewards[rewardToken][msg.sender]
by the amount given by getRewardInfo
.
It computes secondsInsideX128
(the total liquidity seconds for which rewards are owed) for a given Stake, by:
usingsnapshotCumulativesInside
from the DragonswapV2 core contract to get secondsPerLiquidityInRangeX128
, and subtracting secondsPerLiquidityInRangeInitialX128
.
Multiplying that by stake.liquidity
to get the total seconds accrued by the liquidity in that period
Note that X128 means it's a UQ32X128
.
It computes totalSecondsUnclaimed
by taking max(endTime, block.timestamp) - startTime
, casting it as a Q128, and subtracting totalSecondsClaimedX128
.
It computes rewardRate
for the Incentive casting incentive.totalRewardUnclaimed
as a Q128, then dividing it by totalSecondsUnclaimedX128
.
reward
is then calculated as secondsInsideX128
times the rewardRate
, scaled down to a regular uint128.