Platform: Code4rena
Start Date: 15/03/2024
Pot Size: $60,500 USDC
Total HM: 16
Participants: 43
Period: 21 days
Judge: hansfriese
Total Solo HM: 5
Id: 348
League: ETH
Rank: 28/43
Findings: 1
Award: $67.25
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Infect3d
Also found by: Evo, LinKenji, XDZIBECX, falconhoof, foxb868, ilchovski, klau5, nonseodion
67.2468 USDC - $67.25
Adding a short while the market is in recovery mode.
Assuming the current oracle price at the moment for the deth
in dusd
is too low (assetCR is very low) then the market now is in Recovery Mode.
checkRecoveryModeViolation
is checking if a shorter is able to create a short order or not according to shortRecord CR. if shortRecord CR is too low then shorter shouldn't be able to create a short.
uint256 assetCR = Asset.dethCollateral.div(oraclePrice.mul(Asset.ercDebt)); if (assetCR < recoveryCR) { // Market is in recovery mode and shortRecord CR too low return true; }
A shorter can avoid checkRecoveryModeViolation
by relying on an oracle savedPrice. let's say the current oracle price represent a recovery mode for the market but the old saved oracle price doesn't. since the shorter relied on previous saved oracle price (the price was healthy), he will be able to create short order and violate the market recovery mode.
How oracle price could be savedPrice when checkRecoveryModeViolation
is called?
getSavedOrSpotOraclePrice is being called before checkRecoveryModeViolation
method and p.oraclePrice passed to it. In getSavedOrSpotOraclePrice
a check is happening, that if we should update the oracle price according to creationTime of the asset (which gets updated when reading from Oracle) if (LibOrders.getOffsetTime() - getTime(asset) < 15 minutes), if It doesn't cross 15 mins then it will return getPrice which is the last saved oracle price not the current oracle price that comes from getOraclePrice
.
As result a savedPrice
can cause an issue for the market and allow a shorter to create a short while the market according to the current oracle price is in recovery mode.
Manual Review
Use the current oracle price method getOraclePrice
for checkRecoveryModeViolation
instead of getSavedOrSpotOraclePrice
so it skips the 15 mins delay.
Other
#0 - c4-pre-sort
2024-04-07T05:04:43Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-04-07T05:05:03Z
raymondfam marked the issue as duplicate of #114
#2 - raymondfam
2024-04-07T05:06:04Z
Same root cause as in #114 leading to a differing outcome.
#3 - c4-judge
2024-04-11T16:12:36Z
hansfriese marked the issue as satisfactory