BondNFT.sol#claim()
uses the wrong denominator
#393
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/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/BondNFT.sol#L180
Vulnerability details
Impact
In
BondNFT.sol#claim()
,accRewardsPerShare[][]
is amended to reflect the expired shares. But the current formula used is wrongaccRewardsPerShare
might be inaccurate.accRewardsPerShare
, some users might receive undeserved rewards.Proof of Concept
The rationale behind the unchecked block below seems to take into account the shares of reward of the expired bond. However, the denominator is wrong.
Assuming, on day 0,
epoch[tigAsset]
is 100,accRewardsPerShare[tigAsset][100]
is 500.totalShares[tigAsset]
is 100. (decimal calculation will be omitted for simplicity)Some user will do the following:
totalShares[tigAsset]
is 1000.distribute(tigAsset, 100*1000)
,accRewardsPerShare[tigAsset][107]
is 600.accRewardsPerShare[tigAsset][109]
is 650, due to newdistribute(tigAsset, 50*1000)
.Lock.sol#claim(id)
._pendingDelta
will be 900 * 650 - 900 * 600 = 45000.According to line 180,
accRewardsPerShare[tigAsset][109]
will be increased by 45000 / 1000 = 45, change from 650 to 695.Since the 900 shares is expired, this portion should not be counted in the
accRewardsPerShare[][]
reward update. So the intendedaccRewardsPerShare[][]
increase should be 50*1000 / 100 = 500,accRewardsPerShare[tigAsset][109]
should be 600 + 500 = 1100 instead of 695.The reason is, in line 180, the denominator still includes the expired shares, which should be excluded.
Tools Used
Manual analysis.
Recommended Mitigation Steps
Change the denominator:
The text was updated successfully, but these errors were encountered: