Abracadabra Mimswap - grearlake'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: 16/36

Findings: 3

Award: $443.43

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Trust

Also found by: AgileJune, Bigsam, Neon2835, grearlake

Labels

bug
2 (Med Risk)
partial-75
sponsor disputed
sufficient quality report
:robot:_37_group
duplicate-222

Awards

156.622 USDC - $156.62

External Links

Lines of code

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

Vulnerability details

Vulnerability details

Whenever any operation with the given user as a beneficiary is performed, this user's rewards are checkpointed via function _updateRewardsGlobal(), which calculates the reward checkpoint by a call to function _rewardPerToken

function _rewardPerToken(address rewardToken, uint256 lastTimeRewardApplicable_, uint256 totalSupply_) public view returns (uint256) { if (totalSupply_ == 0) { return _rewardData[rewardToken].rewardPerTokenStored; } uint256 timeElapsed = lastTimeRewardApplicable_ - _rewardData[rewardToken].lastUpdateTime; uint256 pendingRewardsPerToken = (timeElapsed * _rewardData[rewardToken].rewardRate * 1e18) / totalSupply_; return _rewardData[rewardToken].rewardPerTokenStored + pendingRewardsPerToken; }

rewardRate is set in notifyRewardAmount function as below:

reward.rewardRate = amount / _remainingRewardTime;

It is clearly that pendingRewardsPerToken can be equal to 0. Consider this mock scenario:

  • timeElapsed = 12 seconds (equal to the time of a block)
  • _rewardData[rewardToken].rewardRate = 2
  • totalSupply_ = 1e22
  • _rewardData[rewardToken].rewardPerTokenStored = x

So the result of the function is x + 12 * 2 * 1e18 / 1e22 Which is equal to x + 24e18 / 1e22 = x due to rounding down

Which is incorrect as the calculation does not account for the rewards accumulated since the last checkpoint.

Attacker can griefing attack by continously calling stake or lock function with dust amount, since they only revert when amount = 0:

function _stakeFor(address account, uint256 amount, bool lock_) internal { if (amount == 0) { revert ErrZeroAmount(); // <--- } function lock(uint256 amount) public whenNotPaused { if (amount == 0) { revert ErrZeroAmount(); // <-- }

Impact

Incorrect checkpoint value being stored for the beneficiary, which will affect future reward calculations for this beneficiary.

Tools Used

Manual review

Use validation checks to ensure that the required calculation doesn't round down to zero:

require(pendingRewardsPerToken >= totalSupply_, "rounding down to 0")

Assessed type

Other

#0 - c4-pre-sort

2024-03-15T12:53:33Z

141345 marked the issue as primary issue

#1 - 141345

2024-03-15T12:53:47Z

low decimal with big totalSupply group several reports on the same block of code, but some dup only addresses low decimal, or only totalSupply

#2 - c4-pre-sort

2024-03-15T12:53:49Z

141345 marked the issue as sufficient quality report

#3 - 0xCalibur

2024-03-17T04:36:36Z

no factor

#4 - c4-sponsor

2024-03-28T17:13:51Z

0xCalibur (sponsor) disputed

#5 - thereksfour

2024-03-29T13:30:23Z

I would think it's dust loss, the rewardRate in the example is very small

#6 - c4-judge

2024-03-29T13:30:36Z

thereksfour changed the severity to QA (Quality Assurance)

#7 - c4-judge

2024-04-07T08:52:26Z

This previously downgraded issue has been upgraded by thereksfour

#8 - c4-judge

2024-04-07T08:53:03Z

thereksfour marked issue #222 as primary and marked this issue as a duplicate of 222

#9 - c4-judge

2024-04-07T08:55:25Z

thereksfour marked the issue as partial-75

Findings Information

🌟 Selected for report: grearlake

Also found by: Breeje, blutorque, hals, roguereggiant

Labels

bug
2 (Med Risk)
primary issue
satisfactory
selected for report
sponsor acknowledged
sufficient quality report
edited-by-warden
:robot:_36_group
M-09

Awards

271.4781 USDC - $271.48

External Links

Lines of code

https://github.com/code-423n4/2024-03-abracadabra-money/blob/main/src/mimswap/MagicLP.sol#L470-#L510 https://github.com/code-423n4/2024-03-abracadabra-money/blob/main/src/mimswap/MagicLP.sol#L244-#L265

Vulnerability details

Vulnerability details

Because MagicLP is forked from DODO, we will check DODO documentation to understand this contract. From DODO documentation, the "I" is the "i" value in here and it is directly related with the output amount a trader will receive when selling a quote/base token:

img

Adjusting the value of "I" directly by calling setParameters() function will influence the price. This can be exploited by a MEV bot, simply by trading just before the setParameters() function and exiting right after the price change. The profit gained from this operation essentially represents potential losses for the liquidity providers who supplied liquidity to the pool.

Impact

Since the price will change, the MEV bot can simply sandwich the tx and get profit.

Another note on this is that even though the adjustPrice called by onlyImplementationOwner without getting frontrunned, it still creates a big price difference which requires immediate arbitrages. Usually these type of parameter changes that impacts the trades are setted by time via ramping to mitigate the unfair advantages that it can occur during the price update.

Tools Used

Manual review

Acknowledge the issue and use private RPC's to eliminate front-running or slowly ramp up the "I" so that the arbitrage opportunity is fair

Assessed type

MEV

#0 - c4-pre-sort

2024-03-15T12:30:27Z

141345 marked the issue as primary issue

#1 - c4-pre-sort

2024-03-15T12:30:35Z

141345 marked the issue as sufficient quality report

#2 - 141345

2024-03-15T12:31:15Z

admin func to change "I" needs time lock

#3 - c4-sponsor

2024-03-17T04:41:29Z

0xCalibur (sponsor) acknowledged

#4 - 0xCalibur

2024-03-17T04:42:18Z

Fixed in main https://github.com/Abracadabra-money/abracadabra-money-contracts/

We now have protocol own pool and can disable trading for our own pools, changing the parameters and make sure the pool is in good state before enabling it back.

#5 - c4-judge

2024-03-29T13:16:27Z

thereksfour marked the issue as satisfactory

#6 - c4-judge

2024-03-31T06:44:17Z

thereksfour marked the issue as selected for report

Awards

15.328 USDC - $15.33

Labels

bug
downgraded by judge
grade-b
primary issue
QA (Quality Assurance)
sponsor disputed
sufficient quality report
:robot:_40_group
Q-11

External Links

Lines of code

https://github.com/code-423n4/2024-03-abracadabra-money/blob/main/src/blast/BlastOnboarding.sol#L132

Vulnerability details

Vulnerability details

From the contest documentation:

People who deposited unlocked into the LLE can withdraw at any time during and after

BlastOnboarding.withdraw() function:

function withdraw(address token, uint256 amount) external whenNotPaused onlySupportedTokens(token) { balances[msg.sender][token].unlocked -= amount; balances[msg.sender][token].total -= amount; totals[token].unlocked -= amount; totals[token].total -= amount; token.safeTransfer(msg.sender, amount); emit LogWithdraw(msg.sender, token, amount); }

However, due to the whenNotPaused modifier in the BlastOnboarding.withdraw() function, users who have deposit unlocked will not be able to withdraw their funds. If the protocol is paused, it will fail, causing the transaction to revert and preventing users from withdrawing their funds.

Tools Used

Manual review

Remove whenNotPaused modifier from withdraw() function:

- function withdraw(address token, uint256 amount) external whenNotPaused onlySupportedTokens(token) + function withdraw(address token, uint256 amount) external onlySupportedTokens(token)

Assessed type

Other

#0 - c4-pre-sort

2024-03-15T12:47:11Z

141345 marked the issue as primary issue

#1 - c4-pre-sort

2024-03-15T12:47:22Z

141345 marked the issue as sufficient quality report

#2 - 141345

2024-03-15T12:47:44Z

can not withdraw if the contract is paused, contradict the doc

#3 - 0xCalibur

2024-03-17T04:33:29Z

no factor

#4 - c4-sponsor

2024-03-28T17:13:30Z

0xCalibur (sponsor) disputed

#5 - c4-judge

2024-03-29T13:34:57Z

thereksfour changed the severity to QA (Quality Assurance)

#6 - c4-judge

2024-03-29T16:31:57Z

thereksfour marked the issue as grade-b

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