Abracadabra Mimswap - AgileJune's results

General Information

Platform: Code4rena

Start Date: 07/03/2024

Pot Size: $63,000 USDC

Total HM: 20

Participants: 36

Period: 5 days

Judge: cccz

Total Solo HM: 11

Id: 349

League: BLAST

Abracadabra Money

Findings Distribution

Researcher Performance

Rank: 21/36

Findings: 1

Award: $208.83

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Trust

Also found by: AgileJune, Bigsam, Neon2835, grearlake

Labels

bug
2 (Med Risk)
satisfactory
:robot:_44_group
duplicate-222

Awards

208.8293 USDC - $208.83

External Links

Lines of code

https://github.com/code-423n4/2024-03-abracadabra-money/blob/main/src/staking/LockingMultiRewards.sol#L388

Vulnerability details

Impact

LockingMultiRewards.sol, Users can get rewards less than expected amount because of rounding error on calculation of rewardRate. If rewardToken is token of low decimals, like GUSD, which is stablecoin token with 2 decimals.

Proof of Concept

In LockingMultiRewards.sol::notifyRewardAmount, rewardRate is calculated as following.

reward.rewardRate = amount / _remainingRewardTime;

The maximum of _remainingRewardTime is 7 * 24 * 3600 = 604_800, so if operator tries to notify GUSD reward amount less than 604800 ($6048) at the start of epoch, it always reverts with the line (https://github.com/code-423n4/2024-03-abracadabra-money/blob/main/src/staking/LockingMultiRewards.sol#L384)

Even though reward amount is greater than 604800($6048), there will be precision issue, that is, real rewarded amount is less than notified amount.

POC example:

let's say that only a user staked and all rewards will be awarded to the user. reward amount: 1_000_000 remainingRewardTime: 604_800 reward period: 604_800 rewardRate = 1_000_000 / 604_800 = 1 real reward = rewardRate * 604_800 = 604_800 diff = 1_000_000 - 604_800 = 395200 ($3952)

It will affect the protocol's reputation, so we need to add precision value

Tools Used

Manual Review

We need to add precision value.

function notifyRewardAmount(address rewardToken, uint256 amount, uint minRemainingTime) public onlyOperators { ...... - amount += _remainingRewardTime * reward.rewardRate; + amount += _remainingRewardTime * reward.rewardRate / 10 ** 18; ...... - reward.rewardRate = amount / _remainingRewardTime; + reward.rewardRate = amount * 10 ** 18 / _remainingRewardTime; ...... } function rewardsForDuration(address rewardToken) external view returns (uint256) { - return _rewardData[rewardToken].rewardRate * rewardsDuration; + return _rewardData[rewardToken].rewardRate * rewardsDuration / 10 ** 18; } function _rewardPerToken(address rewardToken, uint256 lastTimeRewardApplicable_, uint256 totalSupply_) public view returns (uint256) { ...... - uint256 pendingRewardsPerToken = (timeElapsed * _rewardData[rewardToken].rewardRate * 1e18) / totalSupply_; + uint256 pendingRewardsPerToken = (timeElapsed * _rewardData[rewardToken].rewardRate) / totalSupply_; ...... }

Assessed type

Math

#0 - c4-pre-sort

2024-03-15T12:55:17Z

141345 marked the issue as duplicate of #166

#1 - 141345

2024-03-15T12:55:59Z

low decimal token results in small amount

#2 - c4-judge

2024-03-29T13:30:35Z

thereksfour changed the severity to QA (Quality Assurance)

#3 - c4-judge

2024-03-29T16:52:20Z

thereksfour marked the issue as grade-c

#4 - c4-judge

2024-04-07T08:52:26Z

This previously downgraded issue has been upgraded by thereksfour

#5 - c4-judge

2024-04-07T08:56:29Z

thereksfour marked the issue as satisfactory

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter