Asymmetry contest - eyexploit's results

A protocol to help diversify and decentralize liquid staking derivatives.

General Information

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

Asymmetry Finance

Findings Distribution

Researcher Performance

Rank: 83/246

Findings: 3

Award: $54.02

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

4.5426 USDC - $4.54

Labels

bug
3 (High Risk)
satisfactory
duplicate-588

External Links

Lines of code

https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/WstEth.sol#L86-L88 https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/SafEth.sol#L71-L75 https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/SafEth.sol#L92-L95

Vulnerability details

Impact

WstEth contract is expected to receive derivative price in ETH when call to ethPerDerivative. But the function returns the price of WstETH in terms of stETH. And since, stETH does not have the same value as ETH the output price return is incorrect.

Consider the mentioned comments for WstETH derivative,

    function stake() external payable {
        ...
        // Getting underlying value in terms of ETH for each derivative
        for (uint i = 0; i < derivativeCount; i++)
            underlyingValue +=
                (derivatives[i].ethPerDerivative(derivatives[i].balance()) *
                    derivatives[i].balance()) /
                10 ** 18;  // @audit 01: returns stETH amount not the ETH actually

        ...
        if (totalSupply == 0)
            preDepositPrice = 10 ** 18; // initializes with a price of 1
        else preDepositPrice = (10 ** 18 * underlyingValue) / totalSupply;  // @audit 02: effects the safETH token price here 

        ...
        // mintAmount represents a percentage of the total assets in the system
        uint256 mintAmount = (totalStakeValueEth * 10 ** 18) / preDepositPrice; // @audit 03: totalStakeValueEth holds the stETH value not ETH, minting incorrect amount of safETH token.
        _mint(msg.sender, mintAmount);
        emit Staked(msg.sender, msg.value, mintAmount);
    }

Proof of Concept

The function getStETHByWstETH() only converts WstETH to stETH. Thus, price() returns the value of WstETH in terms of stETH, check comment.

    /**
        @notice - Get price of derivative in terms of ETH
     */
    function ethPerDerivative(uint256 _amount) public view returns (uint256) {
        return IWStETH(WST_ETH).getStETHByWstETH(10 ** 18); 
    }

Tools Used

Manual review

Use stEth/ETH curve pool for price, the same way its doing SfrxETH.sol

#0 - c4-pre-sort

2023-04-04T17:21:12Z

0xSorryNotSorry marked the issue as duplicate of #588

#1 - c4-judge

2023-04-21T17:09:18Z

Picodes marked the issue as satisfactory

#2 - c4-judge

2023-04-22T09:03:14Z

Picodes marked the issue as partial-25

#3 - Picodes

2023-04-22T09:03:20Z

No PoC or impact

#4 - c4-judge

2023-04-24T20:45:25Z

Picodes marked the issue as satisfactory

Findings Information

Labels

bug
2 (Med Risk)
low quality report
satisfactory
duplicate-932

Awards

40.6368 USDC - $40.64

External Links

Lines of code

https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/derivatives/Reth.sol#L91-L100

Vulnerability details

Impact

While making a swap, AMM provide their user a deadline parameter which make sure the swap txn will only be executed under that deadline timestamp.

If no deadline is passed, the txn can be pending and will be executed in a long time after the user submit the transaction. At that time, the trade can be done in a poor price, which harms user's position.

Proof of Concept

For proof of concept, there is mentioned a similar issue here, with consequences of missing deadline check and like also how the similar txn can exploited maliciously through MEV.

Tools Used

Manual review

It is recommended the protocol to add deadline.

#0 - c4-pre-sort

2023-04-02T18:50:30Z

0xSorryNotSorry marked the issue as low quality report

#1 - c4-pre-sort

2023-04-04T14:49:49Z

0xSorryNotSorry marked the issue as duplicate of #1087

#2 - c4-judge

2023-04-22T10:18:36Z

Picodes marked the issue as satisfactory

Findings Information

Awards

8.8405 USDC - $8.84

Labels

bug
2 (Med Risk)
low quality report
partial-50
duplicate-152

External Links

Lines of code

https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/SafEth.sol#L88

Vulnerability details

Impact

User stake ETH to the main contract SafEth.sol, the sent ETH amount is diversify between derivatives based on the weights[derivativeIndex]. Each weight for individual derivative constitute the totalWeight, if some irregualar weight or user sent ETH amount with upto large decimal. There will always be left some unused ETH into the contract.

Proof of Concept

Add this test to test/SafEth.test.ts

it("POC", async () => {
  // divided weight into 3 derivatives
  // 1e18, 1e18, 1e18  
  const preEthBalance = await ethers.provider.getBalance(safEthProxy.address);
  await safEthProxy.stake({value: ethers.utils.parseEther("1")});
  const postEthBalance = await ethers.provider.getBalance(safEthProxy.address);

  expect(Number(postEthBalance.sub(preEthBalance))).to.be.greaterThan(0); 
})

Tools Used

Manula review

After making the deposit, transfer left dust back to the user .

#0 - c4-pre-sort

2023-04-02T16:35:56Z

0xSorryNotSorry marked the issue as low quality report

#1 - c4-pre-sort

2023-04-04T16:28:05Z

0xSorryNotSorry marked the issue as duplicate of #455

#2 - c4-judge

2023-04-24T21:08:30Z

Picodes marked the issue as satisfactory

#3 - c4-judge

2023-04-24T21:08:35Z

Picodes marked the issue as partial-50

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