MagicLpAggregator always returns lower than correct answer, leading to arbitrage loss
mediumLines of code
Vulnerability details
Description
MagicLpAggregator is used to price LP tokens for "closely-tied" underlying tokens. It calculates the price below:
function latestAnswer() public view override returns (int256) {
uint256 baseAnswerNomalized = uint256(baseOracle.latestAnswer()) * (10 ** (WAD - baseOracle.decimals()));
uint256 quoteAnswerNormalized = uint256(quoteOracle.latestAnswer()) * (10 ** (WAD - quoteOracle.decimals()));
uint256 minAnswer = baseAnswerNomalized < quoteAnswerNormalized ? baseAnswerNomalized : quoteAnswerNormalized;
(uint256 baseReserve, uint256 quoteReserve) = _getReserves();
baseReserve = baseReserve * (10 ** (WAD - baseDecimals));
quoteReserve = quoteReserve * (10 ** (WAD - quoteDecimals));
return int256(minAnswer * (baseReserve + quoteReserve) / pair.totalSupply());
}
The code takes the minimal answer between the underlying oracles and considers all reserves to be worth that amount:
return int256(minAnswer * (baseReserve + quoteReserve) / pair.totalSupply());
The issue is that any difference in price between the assets represents an easy arbitrage opportunity. Suppose we have tokens (A,B), where real oracle shows:
- A = $0.99
- B = $1
The Pool has 1000000 LP tokens and contains:
- 1000000 A
- 1000000 B
The LP value would calculate as:
0.99 * 2000000 / 1000000 = $1.98
The actual value is:
(0.99 * 1000000 + 1 * 1000000) / 1000000 = $1.99
Suppose a platform trades LPs using the aggregator pricing. An attacker could:
- Buy 100,000 LP tokens at $198000
- Withdraw from the pool the underlying shares
- Sell 100,000 A, 100,000 B at $199000
- Profit $1000 from the exchange, when the difference is just $0.01 (this is very common fluctuation even with pegged assets).
The delta comes at the expense of LP holders whose position gets minimized.
Impact
Loss of value due to arbitrage of any platform using MagicLpAggregator pricing.
Tools Used
Manual audit
Recommended Mitigation Steps
Always calculate the value based on the real underlying token value multiplied by amount.
Consider creating two separate oracles for lower-bound and upper-bound results. Then a lending protocol could indeed use the lower-bound for determining collateral value.
Assessed type
MEV
