Frax Ether Liquid Staking contest - pashov'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: 26/133

Findings: 3

Award: $135.62

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

19.982 USDC - $19.98

Labels

bug
duplicate
2 (Med Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-09-frax/blob/8073cc4ca44d9162873494f1cd9915a5d7b46f2b/src/frxETHMinter.sol#L191

Vulnerability details

Proof of concept

In frxETHMinter.sol there is the following code

function recoverEther(uint256 amount) external onlyByOwnGov {
        (bool success,) = address(owner).call{ value: amount }("");
        require(success, "Invalid transfer");

        emit EmergencyEtherRecovered(amount);
    }

This allows the owner of the contract (bypassing timelock) to withdraw all of the submitted Ether to the contract before it was deposited to the ETH 2.0 deposit contract, esentially rugging everyone who submitted Ether to mint frxETH.

Impact

The impact of this issue is that since the protocol is ruggable, it’s reputation will suffer. Also if this is exploited then all of the users will essentially lose all of their submitted Ether

Recommendation

Remove the recoverEther functionality completely.

#0 - FortisFortuna

2022-09-25T21:14:36Z

We are well aware of the permission structure. The owner will most likely be a large multisig. We mentioned the Frax Multisig in the scope too.

#1 - joestakey

2022-09-26T16:41:28Z

Duplicate of #107

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/8073cc4ca44d9162873494f1cd9915a5d7b46f2b/src/ERC20/ERC20PermitPermissionedMint.sol#L76

Vulnerability details

Proof of concept

The code loops through the minters_array until it finds the minter_address to be removed. Every new minter will be pushed to the end of the minters_array array. In the case that there were many minters added already and an owner adds a wrong address as the minter it is possible that the for loop takes too much gas and the transaction reverts because it will hit the block gas limit.

Impact

The impact is a potential Denial of Service when trying to remove a wrong or a malicious minter.

Recommendation

Remove the minters_array since it’s not used for any critical logic in the code or instead implement the same mechanism to pop a minter from the end of the array as in OperatorRegistry.sol popValidators()

#0 - FortisFortuna

2022-09-25T22:40:51Z

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:43:44Z

Duplicate of #12

Awards

12.4859 USDC - $12.49

Labels

bug
duplicate
2 (Med Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-09-frax/blob/8073cc4ca44d9162873494f1cd9915a5d7b46f2b/src/frxETHMinter.sol#L200

Vulnerability details

Proof of concept

The frxETHMinter.sol contract has the following code

function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyByOwnGov { require(IERC20(tokenAddress).transfer(owner, tokenAmount), "recoverERC20: Transfer failed"); emit EmergencyERC20Recovered(tokenAddress, tokenAmount); }

but the way to check if the transfer is successful (with a require statement) won’t work for non-ERC20 compliant tokens like USDT because they do not return a boolean value on transfer(), so the require statement will always revert.

Impact

The impact is that the implemented recoverERC20 functionality won’t work as expected, resulting in such Non-ERC20 compliant tokens like USDT getting stuck in the contract

Recommendation

Use OpenZeppelin’s SafeERC20 library - safeTransfer & safeTransferFrom

#0 - FortisFortuna

2022-09-25T21:36:43Z

Not really medium risk. Technically you could use safeTransfer, but if someone were to accidentally send something to this contract, it would most likely be either ETH, FRAX, frxETH, or sfrxETH, all of which are transfer compliant.

#1 - joestakey

2022-09-26T16:41:53Z

Duplicate of #18

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