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: 51/246
Findings: 2
Award: $107.57
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: rbserver
Also found by: 0xAgro, DadeKuma, DeStinE21, HollaDieWaldfee, IgorZuk, J4de, P7N8ZK, Parad0x, Stiglitz, bytes032, carrotsmuggler, csanuragjain, dec3ntraliz3d, kaden, koxuan, lukris02, rvierdiiev, tnevler
58.9366 USDC - $58.94
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L63
function stake() external payable { // --skip-- for (uint i = 0; i < derivativeCount; i++) underlyingValue += [1]-> (derivatives[i].ethPerDerivative(derivatives[i].balance()) * derivatives[i].balance()) / 10 ** 18; // --skip-- function unstake(uint256 _safEthAmount) external { // --skip-- for (uint256 i = 0; i < derivativeCount; i++) { // withdraw a percentage of each asset based on the amount of safETH uint256 derivativeAmount = (derivatives[i].balance() * _safEthAmount) / safEthTotalSupply; if (derivativeAmount == 0) continue; // if derivative empty ignore [2]-> derivatives[i].withdraw(derivativeAmount); }
Both the stake and unstake operations in the SafEth contract need to traverse each derivative for processing, such as code [1] and code [2]. And each derivative contract may depend on other three-party contracts.
The problem here is that there is no interface provided to delete the derivative, resulting in a problem with any derivative (although the probability is very small) may cause the entire contract to be unusable.
manual audit
It is recommended to add an interface to delete derivative.
#0 - c4-pre-sort
2023-04-03T10:57:05Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T17:33:18Z
0xSorryNotSorry marked the issue as duplicate of #703
#2 - c4-judge
2023-04-21T15:06:44Z
Picodes marked the issue as satisfactory
#3 - c4-judge
2023-04-24T19:36:09Z
Picodes changed the severity to 3 (High Risk)
🌟 Selected for report: ladboy233
Also found by: 0xkazim, 0xnev, Bauer, J4de, Matin, UniversalCrypto, cryptothemex, jasonxiale, juancito, koxuan, latt1ce, neumo
48.6252 USDC - $48.63
function withdraw(uint256 _amount) external onlyOwner { // --skip-- [1]-> uint256 minOut = (((ethPerDerivative(_amount) * _amount) / 10 ** 18) * (10 ** 18 - maxSlippage)) / 10 ** 18; IFrxEthEthPool(FRX_ETH_CRV_POOL_ADDRESS).exchange( 1, 0, frxEthBalance, minOut ); // solhint-disable-next-line (bool sent, ) = address(msg.sender).call{value: address(this).balance}( "" ); require(sent, "Failed to send Ether"); }
Code 1, first divides 10**18
and then multiplies 10**18 - maxSlippage
, and this creates an unnecessary loss of precision. This may result in a decrease of up to 1 ETH in the minimum required received ETH.
manual audit
It is recommended to multiply first and then divide.
#0 - c4-pre-sort
2023-04-03T10:49:59Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-04-04T16:41:10Z
0xSorryNotSorry marked the issue as duplicate of #1044
#2 - c4-judge
2023-04-22T10:33:32Z
Picodes marked the issue as satisfactory