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
Rank: 19/33
Findings: 1
Award: $362.29
π Selected for report: 0
π Solo Findings: 0
π Selected for report: camden
Also found by: GeekyLumberjack, kirk-baird, shw
362.2874 USDC - $362.29
GeekyLumberjack
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.
generateFLNQuote()
on a regular basis.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.
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" );
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