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

2 stars 0 forks source link

Possible DOS in `launch()` and `claimRefund()` functions because unbounded loop can run out of gas. #118

Closed howlbot-integration[bot] closed 3 months ago

howlbot-integration[bot] commented 3 months ago

Lines of code

https://github.com/code-423n4/2024-06-vultisig/blob/cb72b1e9053c02a58d874ff376359a83dc3f0742/src/ILOManager.sol#L187 https://github.com/code-423n4/2024-06-vultisig/blob/cb72b1e9053c02a58d874ff376359a83dc3f0742/src/ILOManager.sol#L193 https://github.com/code-423n4/2024-06-vultisig/blob/cb72b1e9053c02a58d874ff376359a83dc3f0742/src/ILOManager.sol#L201 https://github.com/code-423n4/2024-06-vultisig/blob/cb72b1e9053c02a58d874ff376359a83dc3f0742/src/ILOManager.sol#L204

Vulnerability details

Impact

The functions launch() and claimRefund() in ILOManager.sol may fail due to unbounded loop over initializedPools.length.

the array of addresses initializedPools can get very big due to the function initILOPool which pushes many iloPoolAddress inside _initializedILOPools[params.uniV3Pool]. There is no restriction on how may addresses can be pushed.

_initializedILOPools[uniV3PoolAddress] can get very huge and may cause dos condition where no projects can be launched due to exceed of gas limit.Similar with the claimRefund() function.

Proof of Concept

dos in launch()


function launch(address uniV3PoolAddress) external override {
require(block.timestamp > _cachedProject[uniV3PoolAddress].launchTime, "LT");
(uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(uniV3PoolAddress).slot0();
require(_cachedProject[uniV3PoolAddress].initialPoolPriceX96 == sqrtPriceX96, "UV3P");
address[] memory initializedPools = _initializedILOPools[uniV3PoolAddress];
require(initializedPools.length > 0, "NP");
//@audit dos, unbounded for lop
for (uint256 i = 0; i < initializedPools.length; i++) {
IILOPool(initializedPools[i]).launch();
}
    emit ProjectLaunch(uniV3PoolAddress);
}
>dos in `claimRefund()`
```javascript
  function claimRefund(address uniV3PoolAddress) external override onlyProjectAdmin(uniV3PoolAddress) returns(uint256 totalRefundAmount) {
        require(_cachedProject[uniV3PoolAddress].refundDeadline < block.timestamp, "RFT");
        address[] memory initializedPools = _initializedILOPools[uniV3PoolAddress];
        for (uint256 i = 0; i < initializedPools.length; i++) {
            totalRefundAmount += IILOPool(initializedPools[i]).claimProjectRefund(_cachedProject[uniV3PoolAddress].admin);
        }
      //@audit is any event mising  + yes, projectRefund event
}

Tools Used

Manual Review

Recommended Mitigation Steps

Setting an limit on how many addresses can be pushed inside _initializedILOPools[uniV3PoolAddress] should work.

Assessed type

DoS

c4-judge commented 2 months ago

alex-ppg changed the severity to QA (Quality Assurance)

c4-judge commented 2 months ago

alex-ppg marked the issue as grade-c