Closed c4-bot-5 closed 6 months ago
0xEVom marked the issue as sufficient quality report
This issue is based on incorrect understanding of AMM price mechanics:
The basic thing to understand is that if you buy token A with token B, the price of token A is increasing the more you buy (starting at "current price").
In this case assuming the price is correct (which is validated by the oracle when you borrow) 1 USDC = 1 DAI, as you swap DAI for USDC the price of USDC increases so you would never reach a price of 0.1 DAI = 10000 USDC in that direction.
In other words: "NFT position that only kick in when price reach 10000 USDC = 0.1 DAI" The imagined can not be created when the current price is "1 USDC = 1 DAI" It could only be created when the price is completely off to begin with, because the current price is "on the other side" of the position it would only allow you to swap 10000 USD for 0.1 DAI and not the other way around.
Yet another way to look at this is that what you are proposing would require a liquidity distribution where at the same time the pool has a correct current price, but there exits also another amount of liquidity that could be arbitraged against the current price. This state of a pool is not possible.
kalinbas (sponsor) disputed
I cannot understand the attack scenario described by the warden. I feel the warden has mistaken the price direction of the swap,just like the sponsor said above, making the entire PoC very confusing. If you want the oracle to think your position is worth 10,000 USDC, you should now be on a tick with the opposite sign.
jhsagd76 marked the issue as unsatisfactory: Insufficient proof
Lines of code
https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/V3Vault.sol#L427-L475
Vulnerability details
V3Vault.sol
allow user deposit any uniswapNFT and borrow against them. As long as oracle can calculate these NFT worth.But some pool like
(USDC,DAI,fee = 10000)
exist with no liquidity. https://etherscan.io/address/0x6958686b6348c3D6d5f2dCA3106A5C09C156873a#codeV3Vault.sol
check this low liquidity pool have similar price as other pool with high liquidity as valid. It use same chainlink and TWAP oracle feeds to calculate value of this low liquidity pool. But what it cant do is checking if some extreme price tick position can be instantly reached due to low liquidity.This allow attacker use this low liquidity pool to create extreme NFT uniswap position and borrow against it then trading with unfair price in manipulated pool for profit.
Impact
User steal money from Vault using uniswapV3 mechanism of low liquidity pool and positions in single block.
Proof of Concept
Using this low liquidity pool
(USDC,DAI,fee = 10000)
Making absurd UniswapNFT positions holding (10000 USDC, 0.1 DAI) in this low liquidity pool. Exploiter can create NFT position that only kick in when price reach 10000 USDC = 0.1 DAI.
The pool exchange price still 1 DAI = 1 USDC. Except the liquidity in tick 1 DAI = 1 USDC is just 5$ of liquidity. While liquidity in tick 0.1 DAI = 10000 USDC is 10000$ of liquidity.
V3Vault
use oracle and consider this position worth 10000$ and can borrow 8000$ USDC against it.Attacker transfer this NFT and borrow 8000 USDC against it. Then swap ~10 DAI for 8000 USDC. This UniswapNFT position now worth (2000 USDC, 10 DAI). Exploiter just profit 6000 USDC from Vault.
Step by step
V3Vault.sol
accept any uniswapNFT positions as collateral. Even when it hold wrong non-supported token. https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/V3Vault.sol#L427-L475V3Oracle.sol
to calculate how much token this position hold. https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/V3Vault.sol#L591-L593 https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/V3Vault.sol#L1270-L1279V3Oracle.sol
use UniswapPool to calculate holding of this NFT position. It get how much token this position is holding depend on tick price and tick position. https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/V3Oracle.sol#L101-L102V3Vault
andV3Oracle
will accept this NFT with extreme tick position as having fair priceV3Vault
allow user borrow 8000 USDC against this NFT position.Tools Used
Recommended Mitigation Steps
To deny NFT from pool with low liquidity. Whitelist acceptable UniswapNFT pool seem like easiest options.
It is not viable for Oracle to check both pool both price and liquidity as reasonable.
Assessed type
Uniswap