Good Entry - 0xBeirao's results

The best day trading platform to make every trade entry a Good Entry.

General Information

Platform: Code4rena

Start Date: 01/08/2023

Pot Size: $91,500 USDC

Total HM: 14

Participants: 80

Period: 6 days

Judge: gzeon

Total Solo HM: 6

Id: 269

League: ETH

Good Entry

Findings Distribution

Researcher Performance

Rank: 32/80

Findings: 1

Award: $250.17

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: nemveer

Also found by: 0xBeirao, Hama, Madalad, n33k

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
duplicate-367

Awards

250.1744 USDC - $250.17

External Links

Lines of code

https://github.com/code-423n4/2023-08-goodentry/blob/71c0c0eca8af957202ccdbf5ce2f2a514ffe2e24/contracts/GeVault.sol#L247-L294

Vulnerability details

Impact

An inflation attacks can be done on the first deposit into the GeVault contract. Making the first real depositor losing his deposit.

Proof of Concept

Inflation attack steps :

  • First, Alice (the attacker) need to craft a deposit that put valueX8 = 1 => Thus liquidity will be 1e10 and Alice own 1e10 shares

  • The goal now is to make liquidity = (tSupply * valueX8) / vaultValueX8 = 1 (here) meaning that : (tSupply * valueX8) should be equal to vaultValueX8

    ⇒ tSupply = 1e10 (bod minted)

    ⇒ valueX8 is what Alice entered

    ⇒ vaultValueX8 we can deposit collateral on the right AAVE pool, get aToken and force feed the GeVault contract to make (tSupply * valueX8) equal to vaultValueX8 (note that this operation need to front run bob because we need to know valueX8 in advance)

  • Then bob let's say bod deposit 1 ETH but liquidity = (tSupply * valueX8) / vaultValueX8; return liquidity = 1 (or very few) and no token are minted

  • So now Alice can withdraw and take the bob's ETH + his initial deposit

    function deposit(
        address token,
        uint amount
    ) public payable nonReentrant returns (uint liquidity) {

        ...

        // Send deposit fee to treasury
        uint fee = (amount * getAdjustedBaseFee(token == address(token0))) /
            1e4;
        ERC20(token).safeTransfer(treasury, fee);
        uint valueX8 = (oracle.getAssetPrice(token) * (amount - fee)) /
            10 ** ERC20(token).decimals();
          //@audit valueX8 = 1

        require(tvlCap > valueX8 + getTVL(), "GEV: Max Cap Reached");

        uint vaultValueX8 = getTVL();
        uint tSupply = totalSupply();
        if (tSupply == 0 || vaultValueX8 == 0) liquidity = valueX8 * 1e10;
        // @audit liquidity = 1e10
        else {
            liquidity = (tSupply * valueX8) / vaultValueX8; //@audit can we generate <1e10 by force feeding the pool ?
        }

        rebalance();
        require(liquidity > 0, "GEV: No Liquidity Added");
        _mint(msg.sender, liquidity); // @audit liquidity = 1 at when bob deposit
        emit Deposit(msg.sender, token, amount, liquidity);
    }

What can be do is to track aToken balances internally in the GeVault contract. Force feeding this contract will no longer be possible

Assessed type

Token-Transfer

#0 - c4-pre-sort

2023-08-09T10:25:12Z

141345 marked the issue as duplicate of #367

#1 - c4-judge

2023-08-19T16:20:43Z

gzeon-c4 changed the severity to 2 (Med Risk)

#2 - c4-judge

2023-08-20T17:14:03Z

gzeon-c4 marked the issue as satisfactory

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