BondNFT.sol: claim function distributes rewards of expired bond across too many shares #71
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-630
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2022-12-tigris/blob/496e1974ee3838be8759e7b4096dbee1b8795593/contracts/BondNFT.sol#L168-L187
Vulnerability details
Impact
Note: I have submitted a different issue (issue 68) that originates from the same code section. However these are different issues with even somewhat counteracting consequences. By reading both issues closely it should become clear that the issues are different.
The
BondNFT.claim
function (https://github.com/code-423n4/2022-12-tigris/blob/496e1974ee3838be8759e7b4096dbee1b8795593/contracts/BondNFT.sol#L168-L187) distributes rewards that are accumulated for an expired bond across all shares.The issue is that the rewards are distributed across ALL shares when instead they should be distributed across ALL shares minus the shares of the bond that is expired. This is because clearly the shares of the bond are expired and can no longer earn rewards.
This causes the
accRewardsPerShare
to be lower than it should be and results in a loss for all shareholders.Proof of Concept
The vulnerable code is this:
In the last line,
_pendingDelta
is distributed acrosstotalShares[bond.asset]
. This however includesbond.shares
, i.e. the shares of the expired bond. However since the bond is expired, there are now less shares that are able to earn rewards (totalShares[bond.asset] - bond.shares
).There are two paths that
BondNFT.claim
can be called.The first path is
Lock.release
->BondNFT.release
->BondNFT.claim
. In this case, thetotalShares[bond.asset]
are adjusted inBondNFT.release
beforeBondNFT.claim
is called:So this path is not vulnerable.
However there is another path:
Lock.claim
->BondNFT.claim
. On this path,totalShares[bond.asset]
is not reduced. So this is the path that causes the issue.Tools Used
VSCode
Recommended Mitigation Steps
Change the code in the
BondNFT.claim
function like this:And move the line
totalShares[bond.asset] -= bond.shares;
inBondNFT.release
below the call to claim:Now both paths work with the correct amount of shares.
The text was updated successfully, but these errors were encountered: