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: 1/63
Findings: 3
Award: $11,252.55
🌟 Selected for report: 1
🚀 Solo Findings: 1
🌟 Selected for report: csanuragjain
11184.2105 USDC - $11,184.21
https://github.com/code-423n4/2022-07-yield/blob/main/contracts/Witch.sol#L232
It was observed that the debt and collateral which moves for Auction is calculated incorrectly. In case where line.proportion is set to small value, chances are art will become lower than min debt. This causes whole collateral to go for auction, which was not expected
Assume line.proportion is set to 10% which is a valid value
Auction is started on Vault associated with collateral & base representing line from Step 1
Now debt and collateral to be sold are calculated in _calcAuction
uint128 art = uint256(balances.art).wmul(line.proportion).u128(); if (art < debt.min * (10**debt.dec)) art = balances.art; uint128 ink = (art == balances.art) ? balances.ink : uint256(balances.ink).wmul(line.proportion).u128();
Now lets say debt (art) on this vault was amount 10, collateral (ink) was amount 9, debt.min * (10**debt.dec) was amount 2
Below calculation occurs
uint128 art = uint256(balances.art).wmul(line.proportion).u128(); // which makes art = 10*10% =1 if (art < debt.min * (10**debt.dec)) art = balances.art; // since 1<2 so art=10 uint128 ink = (art == balances.art) // Since art is 10 so ink=9 ? balances.ink : uint256(balances.ink).wmul(line.proportion).u128();
Revise the calculation like below
uint128 art = uint256(balances.art).wmul(line.proportion).u128(); uint128 ink=0; if (art < debt.min * (10**debt.dec)) { art = debt.min * (10**debt.dec); (balances.ink<art) ? (ink=balances.ink) : (ink=art) } else { ink=uint256(balances.ink).wmul(line.proportion).u128(); }
#0 - HickupHH3
2022-07-18T14:11:37Z
debt.min * (10**debt.dec) was amount 2
Only way for this to happen is for the token's decimals to be 0, which is an edge case.
Anyway, the issue is invalid because it is intended for the full collateral to be offered if it is below the minimum debt amount, ie. vault proportion is to be disregarded: // We store the proportion of the vault to auction, which is the whole vault if the debt would be below dust.
#1 - alcueca
2022-07-21T11:06:13Z
The finding is valid, but it is a bit complicated.
The behaviour should be:
dust
, increase to dust
.dust
, increase to 100%.#2 - PierrickGT
2022-08-03T16:33:11Z
This is the second most critical vulnerability found during the audit. This issue is less critical than #116 since the protocol would not take on bad debts but users may lose their entire collateral when only part of their collateral should have been put to auction.
🌟 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
39.3794 USDC - $39.38
Contract: https://github.com/code-423n4/2022-07-yield/blob/main/contracts/Witch.sol#L176
Issue: Check that auctioneer address is not 0. This mean the funds would be lost while paying the auctioneer cut once someone pay the debt
Recommendation: Add below check in auction function
require(to!=address(0), "Invalid address");
Contract: https://github.com/code-423n4/2022-07-yield/blob/main/contracts/Witch.sol
Issue: If contract is under attack and Auctioned Vault interaction for buying collateral need to be stopped, then currently there is no way.
Recommendation: Add a pause modifier which allows Admin to stop interaction with Auctioned Vault function like payBase in case of emergency
Contract: https://github.com/code-423n4/2022-07-yield/blob/main/contracts/Witch.sol#L150
Issue: If setIgnoredPair function is called to ignore a pair on which a auction is already live then it has no impact on live auction
Recommendation: Display an error to Admin mentioning that pair is already running live auction in a vault. If still required then have a boolean param which can forcefully ignore this pair
#0 - alcueca
2022-07-22T14:42:35Z
One useful
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, Aymen0909, Chom, Deivitto, ElKu, JC, JohnSmith, Kaiziron, Limbooo, MadWookie, Meera, ReyAdmirado, Rohan16, Sm4rty, SooYa, TomJ, Trumpero, Waze, __141345__, ajtra, ak1, antonttc, bulej93, c3phas, cRat1st0s, csanuragjain, defsec, durianSausage, fatherOfBlocks, gogo, hake, hickuphh3, ignacio, joestakey, karanctf, kyteg, m_Rassska, pashov, rajatbeladiya, rbserver, robee, rokinot, samruna, sashik_eth, simon135, tofunmi
28.9634 USDC - $28.96
Contract: https://github.com/code-423n4/2022-07-yield/blob/main/contracts/Witch.sol#L180
Issue: auction function will fail at later stage even if vault id provided by user does not exist. This waste gas
Recommendation: Add below check:
DataTypes.Vault memory vault = cauldron.vaults(vaultId); require(vault.owner!=address(0), "Vault not found");
Contract: https://github.com/code-423n4/2022-07-yield/blob/main/contracts/Witch.sol#L286
Issue: If maxBaseIn is provided 0 value while calling payBase function, it means user is paying for 0 debt which does not make sense and should be reverted immediately to prevent gas. Same applies for payFYToken function
Recommendation: Add below check
require(maxBaseIn!=0,"Incorrect value");