Function: unlock(uint256 tokenId)
This unlocks a specific tokenId
.
Inputs
tokenId
Control: Fully controlled by the caller.
Constraints: The owner of
tokenId
should bemsg.sender
.Impact: The ID of the token to unlock.
Branches and code coverage
Intended branches
The number of tokens to unlock for the provided
tokenId
should be greater than zero.The owner of
tokenId
should bemsg.sender
.The fee returned by
checkUnlockFee
should be sent to the vault manager.The remaining amount should be transferred to
msg.sender
, and thetokenId
should be burned.Updates the rewards for the caller and transfers the reward amount.
Deletes the mappings for the
tokenId
.
Negative behavior
Revert if the caller is not
msg.sender
.Revert if the number of tokens to unlock for the provided
tokenId
is zero.
Function call analysis
this.checkUnlockFee(tokenId) -> this.getEarlyWithdrawFee(this.tokensByTokenId[tokenId]) -> this.tranche.feesOn()
What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? Returns true if fees are on, otherwise false; return value is not in control of the user.
What happens if it reverts, reenters or does other unusual control flow? N/A.
this.checkUnlockFee(tokenId) -> this.getEarlyWithdrawFee(this.tokensByTokenId[tokenId]) -> this.vaultManager.earlyWithdrawFee()
What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? Returns the early withdrawal fees; return value is not in control of the user.
What happens if it reverts, reenters or does other unusual control flow? N/A.
this.checkUnlockFee(tokenId) -> MathUpgradeable.mulDiv(fee, timeLeft, totalTime, Rounding.Up)
What is controllable?
fee
,timeLeft
, andtotalTime
.If the return value is controllable, how is it used and how can it go wrong? The fee calculation is based on these parameters; incorrect values may lead to incorrect fee calculation.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this._claimRewards(tokenId) -> SafeERC20.safeTransfer(IERC20(this.tranche.asset()), this._ownerOf(tokenId), this.rewardsByTokenId[tokenId])
What is controllable?
this._ownerOf(tokenId)
andthis.rewardsByTokenId[tokenId]
.If the return value is controllable, how is it used and how can it go wrong? The reward amount is transferred to the owner of the token; an incorrect owner will be reverted in the previous check.
What happens if it reverts, reenters, or does other unusual control flow? If it reverts, the entire call will revert — no reentrancy scenarios.
this._claimRewards(tokenId) -> this.tranche.asset()
What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? N/A.
What happens if it reverts, reenters, or does other unusual control flow? N/A.
this.tranche.transfer(msg.sender, this.tokensByTokenId[tokenId] - fee)
What is controllable?
msg.sender
andthis.tokensByTokenId[tokenId] - fee
.If the return value is controllable, how is it used and how can it go wrong? The remaining unlocked tokens are transferred to the caller; incorrect values may lead to incorrect token transfer.
What happens if it reverts, reenters, or does other unusual control flow? If it reverts, the entire call will revert — no reentrancy scenarios.
this.tranche.transfer(address(this.vaultManager), fee)
What is controllable?
fee
.If the return value is controllable, how is it used and how can it go wrong? The fee amount is transferred to the vault manager; an incorrect fee may lead to incorrect fee transfer.
What happens if it reverts, reenters, or does other unusual control flow? If it reverts, the entire call will revert — no reentrancy scenarios.