The _checkCap
function is missing a check
Description
The depositCap
state variable in the PreDeposit contract is used to represent the maximum deposit amount of the contract.
In the PreDeposit::_checkCap
function, there is no check to ensure that totalUserDepositValue > 0
.
function _checkCap(address[] memory tokens, uint256[] memory amounts) private view {
uint256 totalUserDepositValue;
for (uint256 i = 0; i < tokens.length; i++) {
address token = tokens[i];
uint256 price = balancerOracleAdapter.getOraclePrice(token, ETH);
totalUserDepositValue += (amounts[i] * price) / 1e18;
}
if (totalUserDepositValue + currentPredepositTotal() > depositCap) revert DepositCapReached();
}
Impact
This may cause problems in some edge cases. Assuming depositCap
is 1,000 Ether, when Chainlink price for TOKEN1
is 0, users may deposit more TOKEN1
than the depositCap
limit.
Here is a proof-of-concept scenario:
First, user 1 deposits 99,999,900 Ether
TOKEN1
(Chainlink price forTOKEN1
is 0).Then, user 2 deposits 100 Ether
TOKEN2
(TOKEN2
price is not 0).Since user 2 deposits 100 Ether
TOKEN2
, the_snapshotCapValue
in thecreatePool
function is not 0, and thecreatePool
function can be successfully executed.
// change TOKEN1_PRICE to 0 in PreDeposit.t.sol
function test_poc_CreatePool() public {
console2.log("before deposit ,,, depositCap: ", preDeposit.depositCap());
vm.startPrank(user1);
token1.approve(address(preDeposit), type(uint256).max);
address[] memory tokens = new address[](1);
tokens[0] = address(token1);
uint256[] memory amounts = new uint256[](1);
amounts[0] = 99999900 ether;
preDeposit.deposit(tokens, amounts);
vm.stopPrank();
// user2 deposit 100 ether
vm.startPrank(user2);
token2.approve(address(preDeposit), type(uint256).max);
address[] memory tokens2 = new address[](1);
tokens2[0] = address(token2);
uint256[] memory amounts2 = new uint256[](1);
amounts2[0] = 100 ether;
preDeposit.deposit(tokens2, amounts2);
vm.stopPrank();
vm.startPrank(governance);
vm.warp(block.timestamp + 7 days + 1);
preDeposit.setBondAndLeverageAmount(BOND_AMOUNT, LEVERAGE_AMOUNT);
vm.warp(depositEndTime + 1 days); // After deposit period
poolFactory.grantRole(poolFactory.POOL_ROLE(), address(preDeposit));
bytes32 salt = bytes32("salt");
vm.recordLogs();
preDeposit.createPool(salt);
vm.stopPrank();
}
Recommendations
Consider adding a check in the _checkCap
function to ensure that totalUserDepositValue
is greater than zero.
Remediation
This issue has been acknowledged by Plaza Finance, and a fix was implemented in commit cc43695d↗.