Asymmetry contest - codetilda's results

A protocol to help diversify and decentralize liquid staking derivatives.

General Information

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

Asymmetry Finance

Findings Distribution

Researcher Performance

Rank: 203/246

Findings: 1

Award: $11.13

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

11.1318 USDC - $11.13

Labels

bug
2 (Med Risk)
low quality report
satisfactory
duplicate-363

External Links

Lines of code

https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/SafEth.sol#L63-L101

Vulnerability details

Impact

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).

Proof of Concept

SafETH.sol L63-101

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

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter