Platform: Code4rena
Start Date: 14/07/2022
Pot Size: $25,000 USDC
Total HM: 2
Participants: 63
Period: 3 days
Judge: PierrickGT
Total Solo HM: 1
Id: 147
League: ETH
Rank: 18/63
Findings: 1
Award: $59.94
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: hickuphh3
Also found by: 0x29A, 0x52, 0xNazgul, Chom, Deivitto, ElKu, Funen, IllIllI, Meera, ReyAdmirado, SooYa, TomJ, Trumpero, Waze, __141345__, ak1, asutorufos, c3phas, cRat1st0s, csanuragjain, delfin454000, exd0tpy, fatherOfBlocks, hake, hansfriese, horsefacts, hyh, karanctf, kenzo, kyteg, ladboy233, pashov, peritoflores, rajatbeladiya, rbserver, reassor, rokinot, simon135, wastewa
59.9447 USDC - $59.94
Attacker can create a vault that can never be liquidated, potentially allowing them to keep their loan for as long they desire and distort collateral-to-token balance. This will also distort the efficiency of the Witch contract and liquidation mechanism.
Attack just needs to:
give
function on the Ladle.sol
contract, with the receiver
address set to the address of the Witch.sol
contract (or any other witch in otherWitches
variable).After this no liquidator will able to call the auction
function on that vault, even if the collateral is worth less than the loan.
This is because this if-statement (show below) will throw the error VaultAlreadyUnderAuction
because the vault owner will be equal to the contract of the Witch contract (or any other witch in otherWitches
variable):
function auction(bytes12 vaultId, address to) external returns (DataTypes.Auction memory auction_) { DataTypes.Vault memory vault = cauldron.vaults(vaultId); if (vault.owner == address(this) || otherWitches[vault.owner]) { revert VaultAlreadyUnderAuction(vaultId, vault.owner); }
Forge tests inside repo
Assuming we only want to change code within the Witch contract, we should aim to change the check condition to rely on something other than ownership of vault (like start time of auction, as was done in the older Witch contract).
Old code in old Witch.sol#L91
contract:
require (auctions[vaultId].start == 0, "Vault already under auction");
We need to repeat this check for otherWitches
as well if we want to keep this in the code.
So I recommend adding a function to all Witches (keep this in some shared interface) that returns whether or not an auction is currently running under that Witch, and then doing a simple for-loop checking all Witches for that vault auction.
This fix will allow any Vaults that are supposed to be liquidated to be liquidated, regardless of whether a user has given the vault away to a Witch.
#0 - alcueca
2022-07-21T10:47:50Z
Duplicate of #108
#1 - PierrickGT
2022-07-28T17:19:24Z
Read the following comment to understand why this issue has been downgraded to QA report: https://github.com/code-423n4/2022-07-yield-findings/issues/108#issuecomment-1198424350
#2 - PierrickGT
2022-07-30T16:05:59Z
Only issue submitted by this warden, since it has been downgraded to QA report, I will remove the duplicate label and reopen it.