code-423n4 / 2024-03-acala-findings

0 stars 0 forks source link

An attacker user can frontrun and stake a large amount of LP tokens before AccumulatePeriod, to claim the majority share of the reward pool #47

Closed c4-bot-6 closed 7 months ago

c4-bot-6 commented 7 months ago

Lines of code

https://github.com/code-423n4/2024-03-acala/blob/main/src/modules/incentives/src/lib.rs#L230 https://github.com/code-423n4/2024-03-acala/blob/main/src/modules/incentives/src/lib.rs#L248

Vulnerability details

Impact

A malicious user can claim majority of the reward pool, by front-running and staking a large amount of LP tokens before the reward is accumulated (i.e accumulating period). Afterwards when the rewards gets accumulated and gets deposited to the pool, the malicious user can withdraw it. This guarentees that the malicious user will receive a majority chunk of the reward, than the rest of previously staked users. The user can use this method, to claim majority chunk of the reward pool for every reward accumulate period.

It also impacts the rest of the staked user. As they will lose maximum percent of their share of the reward.

Proof of Concept

Consider the scenerio below, and for simplicity, we will consider reward accumulated in single reward_currency

  1. Attacker saw that AccumulatePeriod will start. So either he stakes before that or he front-runs the accumulate_incentives function, and then stake
  2. Attacker stakes a very large amount (compared to other staked users) of LP tokens, by calling deposit_dex_share, just before the AccumulatePeriod
  3. This will increase the reward_inflation variable by a significant amount, which in-turn will increase the total_reward and total_withdrawn_reward variable. Furthermore withdrawn_reward is also increased.
  4. Now the AccumulatePeriod starts, and rewards gets deposited. This will increase the total_reward variable of the pool by the reward amount accumulated.
  5. Afterwards, we will call the withdraw_dex_share function, with our staked LP token amount. This will return our staked LP token, along with the majority share of the reward, that was accumulated.

Hence a direct POC is : deposit_dex_share(origin, lp_currency_id, amount) - where amount is a very large amount of LP tokens AccumulatePeriod starts and rewards get accumulated. total_reward of the pool increased withdraw_dex_share(origin, lp_currency_id, amount) - where amount is the staked LP token

User will now receive a larger share of the reward. I was able to get a 90% share of the reward using this vulnerability.

Tools Used

Manual review

Recommended Mitigation Steps

It is recommended to implement delays while staking and unstaking

Assessed type

Other

c4-pre-sort commented 7 months ago

DadeKuma marked the issue as duplicate of #10

c4-pre-sort commented 7 months ago

DadeKuma marked the issue as sufficient quality report

c4-pre-sort commented 7 months ago

DadeKuma marked the issue as duplicate of #88

c4-judge commented 7 months ago

OpenCoreCH marked the issue as selected for report

c4-judge commented 7 months ago

OpenCoreCH marked issue #48 as primary and marked this issue as a duplicate of 48

c4-judge commented 7 months ago

OpenCoreCH changed the severity to 2 (Med Risk)

c4-judge commented 7 months ago

OpenCoreCH marked the issue as satisfactory