Good Entry - nemveer'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: 30/80

Findings: 1

Award: $325.23

🌟 Selected for report: 1

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: nemveer

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

Labels

bug
2 (Med Risk)
disagree with severity
downgraded by judge
primary issue
satisfactory
selected for report
sponsor confirmed
M-04

Awards

325.2267 USDC - $325.23

External Links

Lines of code

https://github.com/code-423n4/2023-08-goodentry/blob/71c0c0eca8af957202ccdbf5ce2f2a514ffe2e24/contracts/GeVault.sol#L271-L278 https://github.com/code-423n4/2023-08-goodentry/blob/71c0c0eca8af957202ccdbf5ce2f2a514ffe2e24/contracts/GeVault.sol#L420-L424

Vulnerability details

Impact

In GeVault, while depositing tokens in the pool, liquidity tokens are minted to the users.

Calculation of liquidity tokens to mint uses balanceOf(address(this)) which makes it susceptible to first deposit share price manipulation attack.

deposit calls getTVL, which calls getTickBalance

GeVault.deposit#L271-L278

uint vaultValueX8 = getTVL(); uint tSupply = totalSupply(); // initial liquidity at 1e18 token ~ $1 if (tSupply == 0 || vaultValueX8 == 0) liquidity = valueX8 * 1e10; else { liquidity = tSupply * valueX8 / vaultValueX8; }

GeVault.getTVL#L392-L398

function getTVL() public view returns (uint valueX8){ for(uint k=0; k<ticks.length; k++){ TokenisableRange t = ticks[k]; uint bal = getTickBalance(k); valueX8 += bal * t.latestAnswer() / 1e18; } }

GeVault.getTickBalance#L420-L424

function getTickBalance(uint index) public view returns (uint liquidity) { TokenisableRange t = ticks[index]; address aTokenAddress = lendingPool.getReserveData(address(t)).aTokenAddress; liquidity = ERC20(aTokenAddress).balanceOf(address(this)); }

Although there is a condition on line 281 that liquidity to be minted must be greater than 0, User's funds can be at risk.

Proof of Concept

When totalSupply is zero, an attacker can go ahead and execute following steps.

  1. Calls deposit function with 1 wei amount of underlying as argument. To that, he will be minted some amount of liquidity share depending on the price of underlying.
  2. Withdraw all except one wei of shares.
  3. Transfer some X amount of underlying directly to pool contract address. So, now 1 wei of share worths X underlying tokens. Attacker won't have any problem making this X as big as possible. Because he'll always be able to redeem it with 1 wei of share.

Impact

  1. Almost 1/4th of first deposit can be frontrun and stolen.
  • Let's assume there is a first user trying to deposit with z dollars worth of tokens
  • An attacker can see this transaction in mempool and carry out the above-described attack with x = (z/2 + 1).
  • This means the user gets 1 Wei of share which is only worth ~ 3x/4 of tokens.
  • Here, the percentage of the user funds lost depends on how much capital the attacker has. let's say a attacker keeps 2 wei in the share initially instead of 1 (this makes doubles capital requirement), they can get away with 33% of the user's funds.
  1. DOS to users who tries to deposit less than X because of this check
require(liquidity > 0, "GEV: No Liquidity Added");

Tools Used

Manual Review

  • Burn some MINIMUM_LIQUIDITY during first deposit

Assessed type

Math

#0 - c4-pre-sort

2023-08-09T09:47:10Z

141345 marked the issue as primary issue

#1 - 141345

2023-08-09T09:47:56Z

medium might be more appropriate

#2 - c4-sponsor

2023-08-15T00:46:20Z

Keref marked the issue as sponsor disputed

#3 - c4-sponsor

2023-08-15T00:48:05Z

Keref marked the issue as sponsor acknowledged

#4 - c4-sponsor

2023-08-15T00:50:32Z

Keref marked the issue as sponsor confirmed

#5 - c4-sponsor

2023-08-15T00:50:38Z

Keref marked the issue as disagree with severity

#6 - c4-sponsor

2023-08-17T09:31:08Z

Keref marked the issue as sponsor disputed

#7 - c4-sponsor

2023-08-17T09:32:16Z

Keref marked the issue as sponsor confirmed

#8 - Keref

2023-08-17T09:36:01Z

Issue is medium severity as easily preventable and only affects GE team when deploying a new vault

#9 - c4-judge

2023-08-19T16:20:45Z

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

#10 - c4-judge

2023-08-19T16:20:50Z

gzeon-c4 marked the issue as satisfactory

#11 - c4-judge

2023-08-19T16:21:56Z

gzeon-c4 marked the issue as selected for report

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