sherlock-audit / 2023-05-USSD-judging

9 stars 7 forks source link

theOwl - Wrong Uniswap pool reserve calculation can affect rebalance process #964

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

theOwl

high

Wrong Uniswap pool reserve calculation can affect rebalance process

Summary

If the getOwnValuation function does not provide correct price estimations, the conditionals may not execute as intended. This could lead to incorrect decisions being made in the rebalance function, potentially impacting the rebalancing process and the behavior of the contract.

Vulnerability Detail

In function getOwnValuation from, the calculation of the price variable is incorrect. It squares the sqrtPriceX96 value, but then divides it by 1e6 and right-shifts it by 96 * 2. This operation might not yield the desired result.

Impact

Wrong calculation of the pool price can make the rebalance function taking the wrong decision between buying and selling USSD, by selling the USSD when it's under-pegged and buying USSD when it's over-pegged doing the opposite of what it is intend to do.

Code Snippet

https://github.com/sherlock-audit/2023-05-USSD/blob/6d7a9fdfb1f1ed838632c25b6e1b01748d0bafda/ussd-contracts/contracts/USSDRebalancer.sol#L95 https://github.com/sherlock-audit/2023-05-USSD/blob/6d7a9fdfb1f1ed838632c25b6e1b01748d0bafda/ussd-contracts/contracts/USSDRebalancer.sol#L98 https://github.com/sherlock-audit/2023-05-USSD-valentincraciun99/blob/1cdd8da2b9bbbe5a8d728ff9da4791fafd18a73d/ussd-contracts/contracts/USSDRebalancer.sol#L74

Tool used

Manual Review

Recommendation

Use the OracleLibrary.getQuoteAtTick function from the Uniswap v3 library to calculate the price in terms of DAI (assuming DAI is the quote token). The function takes the tick value (priceX96), the base token decimals (1e6 for USSD), and the quote token decimals (1e18 for DAI) to accurately compute the price.

import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
import "@uniswap/v3-periphery/contracts/libraries/OracleLibrary.sol";

function getOwnValuation(address uniPoolAddress, address tokenAddress) public view returns (uint256 price) {
    IUniswapV3Pool uniPool = IUniswapV3Pool(uniPoolAddress);
    (uint160 sqrtPriceX96,,,) = uniPool.slot0();

    uint256 priceX96 = uint256(sqrtPriceX96).mul(uint256(sqrtPriceX96));

    if (uniPool.token0() == tokenAddress) {
        price = OracleLibrary.getQuoteAtTick(priceX96, 1e6, 1e18);
    } else {
        price = OracleLibrary.getQuoteAtTick(1e12, priceX96, 1e18);
    }
}

Duplicate of #222