Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BondNFT.sol#claim() uses the wrong denominator #393

Closed
code423n4 opened this issue Dec 16, 2022 · 4 comments
Closed

BondNFT.sol#claim() uses the wrong denominator #393

code423n4 opened this issue Dec 16, 2022 · 4 comments
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

Comments

@code423n4
Copy link
Contributor

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 wrong

  • accRewardsPerShare might be inaccurate.
  • some users could lose reward due to wrong 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.

File: contracts/BondNFT.sol
168:     function claim(
169:         uint _id,
170:         address _claimer
171:     ) public onlyManager() returns(uint amount, address tigAsset) {
    
177:             if (bond.expired) {
178:                 uint _pendingDelta = (bond.shares * accRewardsPerShare[bond.asset][epoch[bond.asset]] / 1e18 - bondPaid[_id][bond.asset]) - (bond.shares * accRewardsPerShare[bond.asset][bond.expireEpoch-1] / 1e18 - bondPaid[_id][bond.asset]);
179:                 if (totalShares[bond.asset] > 0) {
180:                     accRewardsPerShare[bond.asset][epoch[bond.asset]] += _pendingDelta*1e18/totalShares[bond.asset];
181:                 }
182:             }
183:             bondPaid[_id][bond.asset] += amount;

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:

  • on day 1, some user mints 1 bondNFT, with shares of 900, expires 7 days later, now totalShares[tigAsset] is 1000.
  • on day 7, distribute(tigAsset, 100*1000), accRewardsPerShare[tigAsset][107] is 600.
  • on day 9, accRewardsPerShare[tigAsset][109] is 650, due to new distribute(tigAsset, 50*1000).
  • on day 9, the user calls 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 intended accRewardsPerShare[][] 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:

180:                     accRewardsPerShare[bond.asset][epoch[bond.asset]] += _pendingDelta*1e18/(totalShares[bond.asset] - bond.shares);
@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Dec 16, 2022
code423n4 added a commit that referenced this issue Dec 16, 2022
@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as duplicate of #523

@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as duplicate of #630

@c4-judge c4-judge added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value downgraded by judge Judge downgraded the risk level of this issue and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels Jan 22, 2023
@c4-judge
Copy link
Contributor

GalloDaSballo changed the severity to 2 (Med Risk)

@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label Jan 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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
Projects
None yet
Development

No branches or pull requests

2 participants