code-423n4 / 2023-08-dopex-findings

3 stars 3 forks source link

WETH leftovers from add liquidity can not be withdrawn from reLP contract #1143

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/reLP/ReLPContract.sol#L202-L307

Vulnerability details

Impact

reLP contract can have WETH leftovers while adding liquidity. This amount can be a dust (very small) or can be a considerably big amount depending on the liquidity of the V2 pool and the "reLPFactor" variable. reLP contract has no functionality to handle these leftover WETHs which is lowering the efficiency of the reLP'ing process.

Proof of Concept

In UniswapV2 add liquidity is performed as follows: https://github.com/Uniswap/v2-periphery/blob/0335e8f7e1bd1e8d8329fd300aea2ef2f36dd19f/contracts/UniswapV2Router02.sol#L33-L60 https://github.com/Uniswap/v2-core/blob/ee547b17853e71ed4e0101ccfd52e70d5acded58/contracts/UniswapV2Pair.sol#L110-L131

So, if reserves of a hypothetical pool are 100tokenA and 50tokenB and if we need to add 10 tokenA then we exactly need 5 tokenB too. https://github.com/Uniswap/v2-periphery/blob/0335e8f7e1bd1e8d8329fd300aea2ef2f36dd19f/contracts/libraries/UniswapV2Library.sol#L36-L40

Now, let's assume the V2 pool has 1000rDPX, 100WETH, 6 * 1e18 totalSupply and rDPX reserve has 1000rDPX. https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/reLP/ReLPContract.sol#L217-L237 we will calculate the lpToRemove as 0.06 and removing 0.06 LP tokens will give us: 1.13WETH 11.38rDPX

The UniV2 pool now has: 98.87WETH 988.62rDPX

Now we will swap half of the WETH to rDPX: 98.87 988.62 = k (98.87 + (1.13 / 2)) (988.62 - dx) = k dx = 5.617 rDPX.

Now the contract holds 0.565WETH and 5.617rDPX which will be added liquidity back to UniV2 pool. UniV2 pool latest reservs were: 99.435WETH 983rDPX

When we follow the add liquidity steps in UniV2 the contract will add liquidity with the following amounts: full amount of rDPX, which is 5.617 rDPX and 0.563WETH. 0.002WETH will be idle in the contract. This can happen more often if the liquidity to be removen or reLPFactor being very high or very low. Idle WETH should be sweeped to Core contract in these cases.

Tools Used

Recommended Mitigation Steps

Add a sweep functionality for WETH to handle leftover WETH's.

Assessed type

Uniswap

c4-pre-sort commented 1 year ago

bytes032 marked the issue as duplicate of #1286

c4-pre-sort commented 1 year ago

bytes032 marked the issue as sufficient quality report

c4-judge commented 11 months ago

GalloDaSballo marked the issue as satisfactory