code-423n4 / 2021-04-maple-findings

0 stars 0 forks source link

MPL reward claims of balancer pools can be exploited #90

Open code423n4 opened 3 years ago

code423n4 commented 3 years ago

Handle

@cmichelio

Vulnerability details

Vulnerability Details

When MPL tokens are added as liquidity to the Balancer pool, the Balancer pool is the owner of those tokens, which are accruing USDC interest.

Anyone can send the USDC interest to the balancer pool by calling withdrawFundsOnBehalf(balancerPool).

An attacker can abuse this to capture part of this interest by doing the following steps in a single transaction:

  1. Deposit MPT/USDC to the balancer pool (the initial liquidity can also be acquired by a flash loan)
  2. Send USDC to the pool by calling withdrawFundsOnBehalf(bPool), call gulp.
  3. Withdraw liquidity again, the attacker will receive their initial deposit + a share of the USDC interest proportional to their LP tokens.

Impact

USDC interest that was supposed to go to MPT balancer pool stakers is stolen by attackers. Funds might be locked forever.

Recommended Mitigation Steps

This is hard to prevent completely because you're sending free money to the pool. One way to reduce the risk is to only allow claiming interest by the governor / trusted parties. This would disallow attacker to perform this in a risk-free way in a single transaction, but the same attack would still be possible for miners.

Consider alternative ways of distributing the interest of balancer pools like transferring it to all MPT holders instead of liquidity providers, because:

  1. it's currently not fair anyway because only the LPs that are in the pool at the time withdrawFundsOnBehalf was called will benefit, regardless of how long they have been providing this liquidity.
  2. External arbitrageurs are the ones that benefit from this short-term pool price imbalance the most and a good chunk of the USDC interest will go to them
lucas-manuel commented 3 years ago

Not a bug, distributeToHolders and withdrawFundsOnBehalfOf will always be called atomically by the governor.

Arachnid commented 3 years ago

Without code to ensure that withdrawFundsOnBehalfOf is called immediately afterdistributeToHolders`, this bug can still occur. I'm considering this Likelihood=Low,Impact=Medium => Severity=Low.