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: 24/246
Findings: 3
Award: $286.82
🌟 Selected for report: 0
🚀 Solo Findings: 0
236.4864 USDC - $236.49
Function SfrxEth.ethPerDerivative
in order to calculate the value of Sfrx
derivative in ETH
first gets amount of frx
that can be retrieved by using convertToAssets
function and then executes following calculation:
return ((10 ** 18 * frxAmount) / IFrxEthEthPool(FRX_ETH_CRV_POOL_ADDRESS).price_oracle());
This is incorrect since price_oracle
returns the value of the asset in ETH
thus the correct calculation is:
(frxAmount * IFrxEthEthPool(FRX_ETH_CRV_POOL_ADDRESS).price_oracle()) / 1e18;
Manual Review / VSCode
It is recommended to fix the calculation:
(frxAmount * IFrxEthEthPool(FRX_ETH_CRV_POOL_ADDRESS).price_oracle()) / 1e18;
#0 - c4-pre-sort
2023-04-04T16:49:05Z
0xSorryNotSorry marked the issue as duplicate of #698
#1 - c4-judge
2023-04-21T16:04:53Z
Picodes marked the issue as satisfactory
#2 - c4-judge
2023-04-21T16:05:13Z
Picodes marked the issue as not a duplicate
#3 - c4-judge
2023-04-21T16:05:25Z
Picodes marked the issue as duplicate of #641
🌟 Selected for report: __141345__
Also found by: 0xWaitress, 0xbepresent, AkshaySrivastav, Bauer, Haipls, HollaDieWaldfee, Lirios, MiloTruck, SaeedAlipoor01988, UdarTeam, adriro, bytes032, ck, d3e4, hihen, hl_, kaden, ladboy233, lopotras, m_Rassska, peanuts, reassor, volodya
8.2654 USDC - $8.27
Function SfrxEth.deposit
uses external Frax contract frxETHMinter
to deposit ether via submitAndDeposit
.
function submitAndDeposit(address recipient) external payable returns (uint256 shares) { // Give the frxETH to this contract after it is generated _submit(address(this)); // Approve frxETH to sfrxETH for staking frxETHToken.approve(address(sfrxETHToken), msg.value); // Deposit the frxETH and give the generated sfrxETH to the final recipient uint256 sfrxeth_recieved = sfrxETHToken.deposit(msg.value, recipient); require(sfrxeth_recieved > 0, 'No sfrxETH was returned'); return sfrxeth_recieved; }
Execution starts with triggering internal function _submit
that has a check if submitting is not paused:
function _submit(address recipient) internal nonReentrant { // Initial pause and value checks require(!submitPaused, "Submit is paused"); require(msg.value != 0, "Cannot submit 0"); // Give the sender frxETH frxETHToken.minter_mint(recipient, msg.value); // Track the amount of ETH that we are keeping uint256 withheld_amt = 0; if (withholdRatio != 0) { withheld_amt = (msg.value * withholdRatio) / RATIO_PRECISION; currentWithheldETH += withheld_amt; } emit ETHSubmitted(msg.sender, recipient, msg.value, withheld_amt); }
The issue is that depositing will fail in case Frax's submitting is paused which leads to denial of service vulnerability.
Manual Review / VSCode
It is recommended to check if submitting is paused via frxETHMinter.submitPaused()
in SfrxEth.deposit
function. In addition consider using Curve's pool to get Frax
if direct deposit is not possible (in a similar way as for Rocket Pool).
#0 - c4-pre-sort
2023-04-04T22:01:42Z
0xSorryNotSorry marked the issue as duplicate of #328
#1 - c4-judge
2023-04-21T10:47:07Z
Picodes marked the issue as duplicate of #770
#2 - c4-judge
2023-04-24T18:30:20Z
Picodes marked the issue as satisfactory
🌟 Selected for report: brgltd
Also found by: 0x3b, 0xAgro, 0xGusMcCrae, 0xNorman, 0xRajkumar, 0xSmartContract, 0xTraub, 0xWagmi, 0xWaitress, 0xffchain, 0xhacksmithh, 0xkazim, 0xnev, 3dgeville, ArbitraryExecution, Aymen0909, BRONZEDISC, Bason, Bloqarl, BlueAlder, Brenzee, CodeFoxInc, CodingNameKiki, Cryptor, DadeKuma, DevABDee, Diana, Dug, Englave, Gde, Haipls, HollaDieWaldfee, Ignite, Infect3d, Jerry0x, Josiah, Kaysoft, Koko1912, KrisApostolov, Lavishq, LeoGold, Madalad, PNS, Rappie, RaymondFam, RedTiger, Rickard, Rolezn, Sathish9098, SunSec, T1MOH, UdarTeam, Udsen, Viktor_Cortess, Wander, adriro, ak1, alejandrocovrr, alexzoid, arialblack14, ayden, bin2chen, brevis, btk, c3phas, carlitox477, catellatech, ch0bu, chaduke, ck, climber2002, codeslide, descharre, dingo2077, ernestognw, fatherOfBlocks, favelanky, georgits, helios, hl_, inmarelibero, juancito, ks__xxxxx, lopotras, lukris02, m_Rassska, mahdirostami, maxper, nadin, navinavu, nemveer, p_crypt0, peanuts, pipoca, pixpi, qpzm, rbserver, reassor, roelio, rotcivegaf, scokaf, siddhpurakaran, slvDev, smaul, tnevler, tsvetanovv, turvy_fuzz, vagrant, wen, yac, zzzitron
42.0604 USDC - $42.06
Low
Contract Reth
implements multiple private functions that do not follow correct naming convention. This makes code less readable and more prone to errors. Private function names should start with underscore _
.
Reth.sol
:
It is recommended to start naming of all private functions with underscore _
.
Low
Function SafEth.setMaxSlippage
is missing validation of _slippage
parameter which might be accidentally set to incorrect value.
It is recommended to add validation to parameter _slippage
to ensure that its value is between well defined range.
Low
Changing critical addresses such as ownership should be a two-step process where the first transaction (from the old/current address) registers the new address (i.e. grants ownership) and the second transaction (from the new address) replaces the old address with the new one. This gives an opportunity to recover from incorrect addresses mistakenly used in the first step. If not, contract functionality might become inaccessible.
SafEth.sol
:
Manual Review / VSCode
It is recommended to implement two-step process for changing ownership.
Low
Functions SafEth.setMinAmount
and SafEth.setMaxAmount
are missing validation for the _minAmount
and _maxAmount
parameters which might be accidentally set to incorrect values.
It is recommended to validate parameters _minAmount
and _maxAmount
to make sure that their values are in well defined ranges.
Low
The protocol works on derivatives that mapping index keep increasing on adding new derivative. This might lead to denial of service conditions since protocol in functions such as stake
or unstake
iterates over all derivatives, also over these that were removed and their weight was set to 0
.
Consider redesigning protocol in a away it will be not iterating over large number of derivatives.
Low
All derivatives contracts are not implementing events for critical functions. Lack of events emission makes it difficult for off-chain applications to monitor the protocol.
Reth.sol
:
SfrxEth.sol
:
WstEth.sol
:
Manual Review / VSCode
It is recommended to add missing events to listed functions.
Non-Critical
Contract Reth
implements functions poolPrice
and poolCanDeposit
that have confusing names which makes code less readable and might lead to errors. Function poolPrice
refers to the price from the uniswap pool, while poolCanDeposit
checks if its possible to deposit to the Rocket Pool.
It is recommended to change the name of the functions so they reflect which pools they refer to.
Non-Critical
Multiple contracts are missing natspec comments which makes code more difficult to read and prone to errors.
SafEth.sol
Reth.sol
:
@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L47-L50@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L62-L66@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L75-L83@param amount
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L104-L107@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L116-L120@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L152-L156@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L206-L211@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L218-L221@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L225-L228SfrxEth.sol
:
@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/SfrxEth.sol#L41-L44@param _slippage
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/SfrxEth.sol#L48-L51@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/SfrxEth.sol#L90-L94@param _amount
and @return
params - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/SfrxEth.sol#L108-L111@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/SfrxEth.sol#L119-L122WstEth.sol
:
@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/WstEth.sol#L38-L41@param _slippage
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/WstEth.sol#L45-L48@param _amount
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/WstEth.sol#L52-L56@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/WstEth.sol#L69-L73@param _amount
and @return
params - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/WstEth.sol#L83-L86@return
param - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/WstEth.sol#L90-L93Manual Review / VSCode
It is recommended to add missing natspec comments.
Non-Critical
As different compiler versions have critical behavior specifics if the contract gets accidentally deployed using another compiler version compared to one they tested with, various types of undesired behavior can be introduced.
SafEth.sol
- ^0.8.13
- https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/SafEth.sol#L2Reth.sol
- ^0.8.13
- https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L2SfrxEth.sol
- ^0.8.13
- https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/SfrxEth.sol#L2WstEth.sol
- ^0.8.13
- https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/WstEth.sol#L2Manual Review / VSCode
Consider locking compiler version, for example pragma solidity 0.8.17
.
Non-Critical
All contracts are using math calculations to express big numbers instead of using scientific notation.
SafEth.sol
:
Reth.sol
:
SfrxEth.sol
:
WstEth.sol
:
Manual Review / VSCode
It is recommended to use scientific notation, for example: 1e18
.
Non-Critical
The protocol is using a lot of "magic numbers" which makes code less readable and more prone to errors.
SafEth.sol
:
0.5 ether
and 200 ether
- https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/SafEth.sol#L54-L55Reth.sol
:
POOL_FEE
constant - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L180POOL_FEE
constant - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L238SfrxEth.sol
:
ETH=0
and FRX=1
for exchange - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/SfrxEth.sol#L77-L82ETH=0
and STETH=1
for exchange - https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/WstEth.sol#L61Consider adding constant variables with self-explanatory names.
Non-Critical
The protocol is using short names for derivatives such as "Lido" or "Frax" which might lead to confusion.
Consider adding more detailed names for derivatives.
Non-Critical
The protocol supports only derivatives that use 18 decimals. This assumption is carried in all calculation performed by the protocol.
SafEth.sol
:
Manual Review / VSCode
Consider adding support for derivatives with different number of decimals.
#0 - c4-sponsor
2023-04-10T19:42:52Z
toshiSat marked the issue as sponsor acknowledged
#1 - c4-judge
2023-04-24T18:34:59Z
Picodes marked the issue as grade-a