code-423n4 / 2023-07-tapioca-findings

13 stars 9 forks source link

Oracle Manipulation using Uniswap V3 pool that is not yet deployed #175

Open code423n4 opened 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/Tapioca-DAO/tapioca-periph-audit/blob/023751a4e987cf7c203ab25d3abba58f7344f213/contracts/Swapper/UniswapV3Swapper.sol#L38 https://github.com/Tapioca-DAO/tapioca-periph-audit/blob/023751a4e987cf7c203ab25d3abba58f7344f213/contracts/Swapper/UniswapV3Swapper.sol#L61 https://github.com/Tapioca-DAO/tapioca-periph-audit/blob/023751a4e987cf7c203ab25d3abba58f7344f213/contracts/Swapper/UniswapV3Swapper.sol#L96 https://github.com/Tapioca-DAO/tapioca-yieldbox-strategies-audit/blob/05ba7108a83c66dada98bc5bc75cf18004f2a49b/contracts/stargate/StargateSwapperV3.sol#L29

Vulnerability details

Impact

If the UniswapV3Swapper.sol.poolFee is set to the value of the pool that is not yet deployed, an attacker can deploy & initialize the pool with his desired price, then the oracle will get the rate from that manipulated pool.

Proof of Concept

In the UniswapV3Swapper.sol, value of poolFee is coded to 3000 and is changeable by UniswapV3Swapper.sol.setPoolFee method. this value is used in the UniswapV3Factory to find pool and get best rate for swap. because uniswapv3 is using the fee value to find the address of a pool.

    address pool = factory.getPool(tokenIn, tokenOut, poolFee);

    (int24 tick, ) = OracleLibrary.consult(pool, 60);
    amountIn = OracleLibrary.getQuoteAtTick(
        tick,
        uint128(amountOut),
        tokenOut,
        tokenIn
    );

Uniswap v3 introduces multiple pools for each token pair, each with a different swapping fee. Liquidity providers may initially create pools at three fee levels: 0.05%, 0.30%, and 1%. More fee levels may be added by UNI governance, e.g. the 0.01% fee level added by this governance proposal in November 2021, as executed here. According to https://docs.uniswap.org/concepts/protocol/fees#pool-fees-tiers

an attacker could check the defaultFee of the StargateSwapperV3.sol and then check what tokens tapioca markets have in it's balance, if there is a right match where the defaultFee for a token pair does not exist, attacker could deploy and initialized it with his desired price.

https://github.com/Uniswap/v3-core/blob/d8b1c635c275d2a9450bd6a78f3fa2484fef73eb/contracts/UniswapV3Factory.sol#L35 https://github.com/Uniswap/v3-core/blob/d8b1c635c275d2a9450bd6a78f3fa2484fef73eb/contracts/UniswapV3Factory.sol#L20

Tools Used

Manually

Recommended Mitigation Steps

recommend the protocol valid the pool exists with token0 and token1 and fee setting before using the oracle when deploying the price oracle contract.

Assessed type

Invalid Validation

c4-pre-sort commented 1 year ago

minhquanym marked the issue as primary issue

c4-sponsor commented 1 year ago

0xRektora marked the issue as disagree with severity

0xRektora commented 1 year ago

Severity is right, plugin won't undo, should be medium.

c4-sponsor commented 1 year ago

0xRektora marked the issue as sponsor confirmed

c4-judge commented 1 year ago

dmvt marked the issue as satisfactory

c4-judge commented 1 year ago

dmvt marked the issue as selected for report