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

Findings: 1

Award: $1,941.03

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Lambda

Also found by: Critical, bin2chen

Labels

bug
duplicate
3 (High Risk)
in discussion
syncRewards wrong nextRewards

Awards

1941.0279 USDC - $1,941.03

External Links

Lines of code

https://github.com/code-423n4/2022-09-frax/blob/55ea6b1ef3857a277e2f47d42029bc0f3d6f9173/src/sfrxETH.sol#L48-L51

Vulnerability details

Impact

The withdrawal amount will be counted as part of the surplus asset balance mistakenly if block.timestamp >= rewardsCycleEnd.

Proof of Concept

https://github.com/code-423n4/2022-09-frax/blob/55ea6b1ef3857a277e2f47d42029bc0f3d6f9173/src/sfrxETH.sol#L48-L51

    function beforeWithdraw(uint256 assets, uint256 shares) internal override {
        super.beforeWithdraw(assets, shares); // call xERC4626's beforeWithdraw first
        if (block.timestamp >= rewardsCycleEnd) { syncRewards(); } 
    }

storedTotalAssets will be deducted by the withdrawal amount in xERC4626.sol#beforeWithdraw().

At sfrxETH.sol#L50, when block.timestamp >= rewardsCycleEnd, syncRewards() will be called AFTER storedTotalAssets -= amount; (xERC4626.sol#L67).

https://github.com/corddry/ERC4626/blob/6cf2bee5d784169acb02cc6ac0489ca197a4f149/src/xERC4626.sol#L65-L101

In syncRewards(), storedTotalAssets will be used to calculate the rewards.

All surplus asset balance of the contract over the internal balance becomes queued for the next cycle.

uint256 storedTotalAssets_ = storedTotalAssets;
uint256 nextRewards = asset.balanceOf(address(this)) - storedTotalAssets_ - lastRewardAmount_;

storedTotalAssets = storedTotalAssets_ + lastRewardAmount_; // SSTORE

Tools Used

Consider calling syncRewards() before call xERC4626's beforeWithdraw.

#0 - FortisFortuna

2022-09-26T03:20:13Z

#1 - 0xean

2022-10-14T00:09:01Z

closing as dupe of #15

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