Platform: Code4rena
Start Date: 24/03/2023
Pot Size: $49,200 USDC
Total HM: 20
Participants: 246
Period: 6 days
Judge: Picodes
Total Solo HM: 1
Id: 226
League: ETH
Rank: 203/246
Findings: 1
Award: $11.13
🌟 Selected for report: 0
🚀 Solo Findings: 0
11.1318 USDC - $11.13
Calling stake() payable function when state variables are derivativeCount = 0 and pauseStaking = false can cause division by zero exception or msg.sender will receive 0 amount of SafETH tokens for his ETH (posible diapason from 0.5 up to 200 ETH).
Let's say contract deployed, but derivativeCount = 0 (it's initial value) and staking not paused pauseStaking = false (it's initial value).
@audit comments provided in the code below
@audit For example, we call function with msg.value in diapason from 0.5 up to 200 ETH, but derivativeCount = 0, pauseStaking = false function stake() external payable { require(pauseStaking == false, "staking is paused"); require(msg.value >= minAmount, "amount too low"); require(msg.value <= maxAmount, "amount too high"); @audit We pass all requires uint256 underlyingValue = 0; // Getting underlying value in terms of ETH for each derivative @audit derivativeCount = 0 , so we skip for loop below and don't compute underlyingValue which in this case equal zero for (uint i = 0; i < derivativeCount; i++) underlyingValue += (derivatives[i].ethPerDerivative(derivatives[i].balance()) * derivatives[i].balance()) / 10 ** 18; uint256 totalSupply = totalSupply(); uint256 preDepositPrice; // Price of safETH in regards to ETH if (totalSupply == 0) preDepositPrice = 10 ** 18; // initializes with a price of 1 else preDepositPrice = (10 ** 18 * underlyingValue) / totalSupply; @audit if totalSupply > 0 then preDepositPrice = 0 because of underlyingValue = 0, preDepositPrice = 0 can cause division by zero in line 98 uint256 totalStakeValueEth = 0; // total amount of derivatives worth of ETH in system @audit in case derivativeCount = 0 we skip for loop below and we don't calculate totalStakeValueEth = 0; for (uint i = 0; i < derivativeCount; i++) { uint256 weight = weights[i]; IDerivative derivative = derivatives[i]; if (weight == 0) continue; uint256 ethAmount = (msg.value * weight) / totalWeight; // This is slightly less than ethAmount because slippage uint256 depositAmount = derivative.deposit{value: ethAmount}(); uint derivativeReceivedEthValue = (derivative.ethPerDerivative( depositAmount ) * depositAmount) / 10 ** 18; totalStakeValueEth += derivativeReceivedEthValue; } // mintAmount represents a percentage of the total assets in the system @audit Here will be exception if preDepositPrice = 0 or result minAmount = 0, because of totalStakeValueEth = 0 uint256 mintAmount = (totalStakeValueEth * 10 ** 18) / preDepositPrice; @audit Line 98 _mint(msg.sender, mintAmount); @audit If in the line 98 we don't have an exception we receives 0 safEth for 0.5 up to 200 ETH. emit Staked(msg.sender, msg.value, mintAmount); }
Use additional require statement: require(derivativeCount != 0, "no derivatives");
#0 - c4-pre-sort
2023-04-03T07:27:59Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T19:19:43Z
0xSorryNotSorry marked the issue as duplicate of #363
#2 - c4-judge
2023-04-21T16:31:45Z
Picodes marked the issue as satisfactory