Frax Ether Liquid Staking contest - lukris02's results

A liquid ETH staking derivative designed to uniquely leverage the Frax Finance ecosystem.

General Information

Platform: Code4rena

Start Date: 22/09/2022

Pot Size: $30,000 USDC

Total HM: 12

Participants: 133

Period: 3 days

Judge: 0xean

Total Solo HM: 2

Id: 165

League: ETH

Frax Finance

Findings Distribution

Researcher Performance

Rank: 19/133

Findings: 4

Award: $184.14

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: oyc_109

Also found by: 0x4non, Chom, Lambda, Respx, V_B, ladboy233, lukris02, pashov

Labels

bug
duplicate
2 (Med Risk)

Awards

103.1542 USDC - $103.15

External Links

Lines of code

https://github.com/code-423n4/2022-09-frax/blob/main/src/ERC20/ERC20PermitPermissionedMint.sol#L84-L89

Vulnerability details

Impact

The size of minters_array is never reduced because when a minter is "removed", the corresponding element is simply set to zero address. At some point, the loop can run out of gas, and the removeMinter() function becomes unavailable.

Proof of Concept

minters_array is not limited in size.

Tools Used

Manual review.

  • It may be possible not to use minters_array at all, since the minters' addresses are already stored in the mapping minters.
  • Maybe shift the elements of the array (then the indices will change).
  • Maybe write new addresses in place of deleted array elements.
  • Or limit the maximum size of the minters_array.

#0 - FortisFortuna

2022-09-25T22:41:00Z

Technically correct, but in practice, the number of minters will always remain low. If it becomes an issue, we can designate one minter as a "pre-minter" that has a batch of tokens minted to it beforehand, then auxiliary contracts can connect to that instead of ERC20PermitPermissionedMint.sol instead.

#1 - joestakey

2022-09-26T16:22:24Z

Duplicate of #12

Findings Information

🌟 Selected for report: Lambda

Also found by: 0x52, Bahurum, Bnke0x0, KIntern_NA, Respx, Soosh, TomJ, Trust, V_B, lukris02, rbserver, rotcivegaf, yixxas

Labels

bug
duplicate
2 (Med Risk)
sponsor confirmed
depositEther OOG
1 (Low Risk)

Awards

39.1574 USDC - $39.16

External Links

Lines of code

https://github.com/code-423n4/2022-09-frax/blob/main/src/frxETHMinter.sol#L125-L154

Vulnerability details

Impact

The number of iterations in the loop depends on the balance of the contract. The larger the balance of the contract, the more iterations will be in the loop, and then:

  1. The loop can cause out of gas error and the function depositEther() will revert.
  2. And/or, the number of validators may not be enough for all iterations and the function depositEther() will revert. (getNextValidator(); // Will revert if there are not enough free validators)

So, the function depositEther() will become unavailable until the contract balance is decreased and/or new validators are added.

Proof of Concept

https://github.com/code-423n4/2022-09-frax/blob/main/src/frxETHMinter.sol#L125-L154

Tools Used

Manual review.

Consider limiting the number of iterations per function call.
For example, you can declare the constant MAX_NUM_DEPOSITS and add the if-statement before the loop:

if (numDeposits > MAX_NUM_DEPOSITS) { numDeposits = MAX_NUM_DEPOSITS; }

Then, in case of a large contract balance, the function will not get stuck.

#0 - FortisFortuna

2022-09-26T16:30:05Z

Adding a maxLoops parameter or similar can help mitigate this for sure.

#1 - FortisFortuna

2022-09-26T17:21:58Z

QA Report for Frax Ether Liquid Staking contest

Overview

During the audit, 3 low and 4 non-critical issues were found.

β„–TitleRisk RatingInstance Count
L-1Large number of elements may cause out-of-gas errorLow3
L-2Check zero denominatorLow1
L-3Missing checkLow1
NC-1Order of LayoutNon-Critical3
NC-2Floating pragmaNon-Critical6
NC-3Missing NatSpecNon-Critical7
NC-4Public functions can be externalNon-Critical10

Low Risk Findings (3)

L-1. Large number of elements may cause out-of-gas error

Description

Loops that do not have a fixed number of iterations, for example, loops that depend on storage values, have to be used carefully: Due to the block gas limit, transactions can only consume a certain amount of gas. Either explicitly or just due to normal operation, the number of iterations in a loop can grow beyond the block gas limit, which can cause the complete contract to be stalled at a certain point.

Instances
Recommendation

Restrict the maximum number of elements.

L-2. Check zero denominator

Description

If the input parameter is equal to zero, this will cause the call failure on division.

Instances
Recommendation

Add the check to prevent function call failure.

L-3. Missing check

Description

No check that times <= validators.length. Without check, the function will try to pop more elements than there are in the array.

Instances
Recommendation

Add require statement or custom error - times <= validators.length.

Non-Critical Risk Findings (4)

NC-1. Order of Layout

Description

According to Order of Layout, inside each contract, library or interface, use the following order:

  1. Type declarations
  2. State variables
  3. Events
  4. Modifiers
  5. Functions
Instances

Events should not be at the end of the contract:

Recommendation

Place events before modifiers.

NC-2. Floating pragma

Description

Contracts should be deployed with the same compiler version. It helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.

Instances
Recommendation

According to SWC-103, pragma version should be locked.

NC-3. Missing NatSpec

Description

NatSpec is missing for 7 functions in 2 contracts.

Instances
Recommendation

Add NatSpec for all functions.

NC-4. Public functions can be external

Description

If functions are not called by the contract where they are defined, they can be declared external.

Instances
Recommendation

Make public functions external, where possible.

Gas Optimizations Report for Frax Ether Liquid Staking contest

Overview

During the audit, 8 gas issues were found.

Gas Optimizations Findings (8)

G-1. Postfix increment

Description

Prefix increment costs less gas than postfix.

Instances
Recommendation

Consider using prefix increment where it is relevant.

G-2. <>.length in loops

Description

Reading the length of an array at each iteration of the loop consumes extra gas.

Instances
Recommendation

Store the length of an array in a variable before the loop, and use it.

G-3. Initializing variables with default value

Description

It costs gas to initialize integer variables with 0 or bool variables with false but it is not necessary.

Instances
Recommendation

Remove initialization for default values.
For example: for (uint256 i; i < array.length; ++i) {

G-4. > 0 is more expensive than =! 0

Instances
Recommendation

Use =! 0 instead of > 0, where possible.

G-5. x += y is more expensive than x = x + y

Instances
Recommendation

Use x = x + y instead of x += y. Use x = x - y instead of x -= y.

G-6. Using unchecked blocks saves gas

Description

In Solidity 0.8+, there’s a default overflow and underflow check on unsigned integers. When an overflow or underflow isn’t possible, some gas can be saved by using unchecked blocks.

Instances
Recommendation

Change:

for (uint256 i; i < n; ++i) { // ... }

to:

for (uint256 i; i < n;) { // ... unchecked { ++i; } }

G-7. Public is more expensive than private for constants

Instances
Recommendation

Use private constants instead of public, where possible.

G-8. Custom errors may be used

Description

Custom errors from Solidity 0.8.4 are cheaper than revert strings.

Instances
Recommendation

Use pragma 0.8.4+, and for example, change:

require(msg.sender == timelock_address || msg.sender == owner, "Not owner or timelock");

to:

error NotOwnerOrTimelock(); ... if (!(msg.sender == timelock_address || msg.sender == owner)) revert NotOwnerOrTimelock();
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