code-423n4 / 2024-06-vultisig-findings

2 stars 0 forks source link

The `sqrtRatioUpperX96` should be greater than the `initialPoolPriceX96` when initializing the `ILOPool` in the `ILOManager.initILOPool` #22

Closed c4-bot-10 closed 5 months ago

c4-bot-10 commented 5 months ago

Lines of code

https://github.com/code-423n4/2024-06-vultisig/blob/0957ff9e50441cd6de6b4f6e28c7ea93f5cffa85/src/ILOManager.sol#L184-L261

Vulnerability details

Impact

The sqrtRatioUpperX96, which is the upper price of the WETH/VULT pool, should be greater than the initialPoolPriceX96, which is the initial price of the pool. If not, the swap cannot be done because of a lack of liquidity in the price range.

Proof of Concept

The administrator of the project can initialize the ILOPool by calling initILOPool function. To add liquidity to the WETH/VULT pool of Uniswap, it sets the upper tick and lower tick of the position(L88-104).

File: src\ILOManager.sol
072:     function initILOPool(InitPoolParams calldata params) external override onlyProjectAdmin(params.uniV3Pool) returns (address iloPoolAddress) {
             [...]
087: 
088:         uint160 sqrtRatioLowerX96 = TickMath.getSqrtRatioAtTick(params.tickLower);
089:         uint160 sqrtRatioUpperX96 = TickMath.getSqrtRatioAtTick(params.tickUpper);
090: @>      require(sqrtRatioLowerX96 < _project.initialPoolPriceX96 && sqrtRatioLowerX96 < sqrtRatioUpperX96, "RANGE");
091: 
092:         IILOPool.InitPoolParams memory initParams = IILOPool.InitPoolParams({
093:             uniV3Pool: params.uniV3Pool,
094:             tickLower: params.tickLower,
095:             tickUpper: params.tickUpper,
096:             sqrtRatioLowerX96: sqrtRatioLowerX96,
097:             sqrtRatioUpperX96: sqrtRatioUpperX96,
098:             hardCap: params.hardCap,
099:             softCap: params.softCap,
100:             maxCapPerUser: params.maxCapPerUser,
101:             start: params.start,
102:             end: params.end,
103:             vestingConfigs: params.vestingConfigs
104:         });
105:         IILOPool(iloPoolAddress).initialize(initParams);
106:         _initializedILOPools[params.uniV3Pool].push(iloPoolAddress);
107:     }

When the ILOPool is successfully launched, it provides liquidity into the range [sqrtRatioLowerX96, sqrtRatioUpperX96]. If the initialPoolPriceX96 is greater than the sqrtRatioUpperX96, there is no liquidity around the price initialPoolPriceX96. As a result, whitelisted users are unable to swap WETH to VULT because of a lack of liquidity.

Tools Used

Manual Review

Recommended Mitigation Steps

The initialPoolPriceX96 should be in the interval [sqrtRatioLowerX96, sqrtRatioUpperX96].

File: src\ILOManager.sol
072:     function initILOPool(InitPoolParams calldata params) external override onlyProjectAdmin(params.uniV3Pool) returns (address iloPoolAddress) {
             [...]
087: 
088:         uint160 sqrtRatioLowerX96 = TickMath.getSqrtRatioAtTick(params.tickLower);
089:         uint160 sqrtRatioUpperX96 = TickMath.getSqrtRatioAtTick(params.tickUpper);
-            require(sqrtRatioLowerX96 < _project.initialPoolPriceX96 && sqrtRatioLowerX96 < sqrtRatioUpperX96, "RANGE");
+            require(sqrtRatioLowerX96 < _project.initialPoolPriceX96 && _project.initialPoolPriceX96 < sqrtRatioUpperX96, "RANGE");
091: 
092:         IILOPool.InitPoolParams memory initParams = IILOPool.InitPoolParams({
093:             uniV3Pool: params.uniV3Pool,
094:             tickLower: params.tickLower,
095:             tickUpper: params.tickUpper,
096:             sqrtRatioLowerX96: sqrtRatioLowerX96,
097:             sqrtRatioUpperX96: sqrtRatioUpperX96,
098:             hardCap: params.hardCap,
099:             softCap: params.softCap,
100:             maxCapPerUser: params.maxCapPerUser,
101:             start: params.start,
102:             end: params.end,
103:             vestingConfigs: params.vestingConfigs
104:         });
105:         IILOPool(iloPoolAddress).initialize(initParams);
106:         _initializedILOPools[params.uniV3Pool].push(iloPoolAddress);
107:     }

Assessed type

Other

c4-judge commented 4 months ago

alex-ppg marked the issue as unsatisfactory: Insufficient quality