As per docs :
Assuming
flagShort()
was successful,
firstLiquidationTime
is 10hrs,secondLiquidationTime
is 12hrs,resetLiquidationTime
is 16hrs (these are modifiable)Between
updatedAt
andfirstLiquidationTime
,liquidate()
isn't callable.
Between
firstLiquidationTime
andsecondLiquidationTime
,liquidate()
is only callable byshort.flagger
.
The last point can be incorrectly revoked by the protocol under the normal flow of events, violating flagger's priority liquidation time-window.
Imagine the following flow of events:
#1. shortRecord_1
is flagged by flagger1
at timestamp ts
. This short now has 10 hours. If cRatio
is still less than primaryLiquidationCR
after 10 hours, flagger1
has a 2 hour window to liquidate the short. The code sets shortRecord_1.flaggerId
as 1. Read about flaggerId
here:
Note: Instead of saving the flagger address, a ShortRecord saves the flaggerId instead. This is done to save space in the struct. A mapping from id to address (flagMapping) is used to lookup the address instead. There is also a corresponding AssetUser.g_flaggerId to lookup a user's flagId.
#2. 10 hours pass. shortRecord_1
is now eligible for liquidation by flagger1
. Right about now, a different short record, shortRecord_2
is flagged by flagger2
.
#3. Due to a logic bug in the function setFlagger(), the code sets shortRecord_2.flaggerId
as 1 too, since it attempts to re-use the "inactive" flaggerId.
#4. The above point means that as per code, both shortRecord_1
and shortRecord_2
are now considered to be flagged by flagger2
.
#5. Since shortRecord_1
is still in its primary liquidation window, flagger1
attempts to margin call it only to find that it reverts for him!
#6. Due to the above logic fallacy, flagger2
actually now has the power to liquidate shortRecord_1
. He margin calls shortRecord_1
immediately and receives the rewards.
The current check to see if a flaggerId
is "inactive" or not is incorrect. The protocol currently waits for a duration of firstLiquidationTime
to pass for determining this. It should rather wait for secondLiquidationTime
.
Create a file inside test/
folder by the name of TwoFlaggers.t.sol
and paste the following code. Run it via forge test --mt test_TwoFlaggers -vv
:
Manual review, foundry.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.