Return to site
Return to site

Bug Deep Dive #10

Asymmetric liquidity provision to geometric pool can allow attacker to purchase at flat oracle price, irrespective of trade size - $4480

· Bug Deep Dive
Section image

The geometric pool reflects passive orders centered at the oracle price, independent of pool balances.

Prices across levels are spaced by a fixed tick spacing and order sizes follow a geometric ratio of remaining inventory.

Section image

The problem here is that asymmetric liquidity provision allows performing a virtual swap, that is effectively at oracle price, that ignores the spacing and geometric ratio parameters, this allows effectively purchasing up to the entire liquidity in the pool, bypassing the price increase applied by the geometric pool for increasing liquidity.

Initial State

Suppose we have a geometric pool consisting of 10 ETH and 20000 USDC. The price is 1 ETH = 2000 USDC and the swap fee is 0.1%.

An attacker wants to swap 1 ETH for USDC in this pool.

Path 1

They can call add_liquidity with 2.222 ETH. They then immediately burn the LP tokens via withdraw_liquidity to withdraw some ETH and USDC, realizing their virtual swap performed during the asymmetric deposit.

USD value of virtual swap: x = 4444 * 20000 / (20000 + 20000 + 4444) = 2000

FeeRate = 2000 * 0.001 / 4444 = ​0.00045
ETH = (1 - 0.00045) * (44,444 / 40,000 - 1) * (44,444 / 40,000)⁻¹ * 12.2222 = 1.2215
USDC = (1 - 0.00045) × (44444 / 40000 - 1) * (44,444 / 40,000)⁻¹ * 20000 = 1999

Noticeably, we can always obtain a 1 ETH to 2000 USDC trade from the geometric pool irregardless of the params.spacing and params.ratio.

Path 2

In comparison, suppose our params.ratio is 0.05 and the params.spacing is 100 USD.
We obtain the following relevant price bands:
0.5 ETH @ 1998 USDC
0.475 ETH @ 1898 USDC
0.45125 ETH @ 1798 USDC
To fill our 1 ETH ask, we execute the orders 0.5 ETH @ 1998 USDC, 0.475 ETH @ 1898 USDC and 0.025 ETH @ 1798 USDC, this yields ~1946 USDC. As seen, performing the asymmetric liquidity provision exploit can allow bypassing the price bands of the geometric pool and allow obtaining a better swap for at the flat oracle price.

Conclusion

This finding would earn you $4480, and is another example of thinking critically about how can the outcome be achieved in the system in a cheaper way? In this case, the single sided liquidity provision is abused to then withdraw USDC, simulating a swap with better pricing.

Full Report
Codebase

Subscribe
Previous
Bug Deep Dive #9
Next
Bug Deep Dive #11
 Return to site
Cookie Use
We use cookies to improve browsing experience, security, and data collection. By accepting, you agree to the use of cookies for advertising and analytics. You can change your cookie settings at any time. Learn More
Accept all
Settings
Decline All
Cookie Settings
Necessary Cookies
These cookies enable core functionality such as security, network management, and accessibility. These cookies can’t be switched off.
Analytics Cookies
These cookies help us better understand how visitors interact with our website and help us discover errors.
Preferences Cookies
These cookies allow the website to remember choices you've made to provide enhanced functionality and personalization.
Save