Behodler contest - GeekyLumberjack's results

Ethereum liquidity protocol powered by token bonding curves.

General Information

Platform: Code4rena

Start Date: 27/01/2022

Pot Size: $90,000 USDC

Total HM: 21

Participants: 33

Period: 7 days

Judge: Jack the Pug

Total Solo HM: 14

Id: 78

League: ETH

Behodler

Findings Distribution

Researcher Performance

Rank: 19/33

Findings: 1

Award: $362.29

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: camden

Also found by: GeekyLumberjack, kirk-baird, shw

Labels

bug
duplicate
2 (Med Risk)
disagree with severity

Awards

362.2874 USDC - $362.29

External Links

Handle

GeekyLumberjack

Vulnerability details

Impact

generateFLNQuote() can be used to always cause migrate() to revert. Effectively ending one of Behodler's main function's operability. Migration is core to Behodler economics.

Proof of Concept

  1. Attacker would write a script to call generateFLNQuote() on a regular basis.
  2. User would attempt to call migrate() but it would always revert.

This happens because generateFLNQuote() directly sets latestFlanQuotes[0].blockProduced. Each time generateFLNQuote() is called latestFlanQuotes[0] gets assigned to latestFlanQuotes[1]. Both are used in _ensurePriceStability() to require a certain amount of time between each check. Unfortunately generateFLNQuote() is a public function, making it possible to continuously reset latestFlanQuotes[0].blockProduced so it will never pass the require in _ensurePriceStability()

migrate() uses _ensurePriceStability() through this series of calls:

migrate() -> migrate() -> stabilizeFlan() -> ensurePriceStability() -> _ensurePriceStability()

This is verifiable in the hardhat tests as well. You can add additional await this.uniswapHelper.generateFLNQuote(); to test cases and receive an EH error code.

Tools Used

Manual analysis / hardhat

Add a require statement inside generateFLNQuote() that won't allow it to be called before it needs to be.

This may work:

require( localFlanQuotes[0].blockProduced + VARS.minQuoteWaitDuration <= block.number || localFlanQuotes[0].blockProduced == 0, "EH" );

Note on Severity

Due to the ease of exploit and high impact that this type of attack would have on the core functionality of the protocol a high severity seemed appropriate. Because there is no direct stealing of funds I believe it reduces the likelihood of exploit. Using OWASP risk rating methodology High impact * Medium likelihood = High vulnerability

#0 - gititGoro

2022-02-03T19:44:28Z

The disagreement on severity is because this attack can't steal funds and because replacing UniswapHelper with a contract that isn't vulnerable to this is not disruptive.

#1 - gititGoro

2022-02-10T04:10:45Z

duplicate of issue 102

#2 - jack-the-pug

2022-02-27T07:29:58Z

Dup #102

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