code-423n4 / 2024-05-predy-findings

10 stars 9 forks source link

Use of slot0 can lead to price manipulations #278

Closed howlbot-integration[bot] closed 2 months ago

howlbot-integration[bot] commented 2 months ago

Lines of code

https://github.com/code-423n4/2024-05-predy/blob/a9246db5f874a91fb71c296aac6a66902289306a/src/libraries/UniHelper.sol#L12-L14

Vulnerability details

Impact

In the UniHelper.sol library, the functions getSqrtPrice and getSqrtTWAP use the slot0 function of the IUniswapV3Pool interface to get the value of sqrtPriceX96. The sqrtPriceX96 obtained from UniswapV3.slot0 represents the most recent data point and can be easily manipulated via MEV (Miner Extractable Value) bots and flash loans. This manipulation can lead to sandwich attacks, where the price is artificially inflated or deflated before and after a transaction, causing a loss of funds when interacting with Uniswap's swap functions or any other logic that relies on the manipulated price data.

Proof of Concept

You can see the getSqrtPrice function in the UniHelper.sol:

https://github.com/code-423n4/2024-05-predy/blob/a9246db5f874a91fb71c296aac6a66902289306a/src/libraries/UniHelper.sol#L12-L14

function getSqrtPrice(address uniswapPoolAddress) internal view returns (uint160 sqrtPrice) {
    (sqrtPrice,,,,,,) = IUniswapV3Pool(uniswapPoolAddress).slot0();
}

The function uses the sqrtPrice obtained from Uniswap.slot0.

Getting prices using slot0 is highly frowned upon. An attacker can simply manipulate the sqrtPrice by using MEV bots or flash loans. If any function relying on getSqrtPrice or getSqrtTWAP is called with the manipulated sqrtPrice, the token will be bought or sold at an artificially inflated or deflated price. The attacker can then back-run the transaction to sell or buy back the tokens at the manipulated price, thereby making a profit while causing a loss to whoever called those functions.

The value if manipulated is used in convertSqrtPrice of UniHelper and this convertSqrtPrice is queried by getSqrtPrice function in Trade.sol.

getSqrtPrice is used during the execution of trades to determine the current price of a trading pair in the Uniswap pool. This price is essential for calculating how much of one token a user receives when swapping another token, ensuring that the trade is executed at a fair market rate according to the liquidity available in the pool. So as we can see, any value gotten as a result of a manipulated Slot0 goes a long way to corrupt the protocol.

Tools used

Recommended Mitigation Steps

Use The TWAP to get the value of sqrtPrice.

Assessed type

Uniswap

c4-judge commented 2 months ago

alex-ppg marked the issue as satisfactory