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: 23/63
Findings: 2
Award: $56.53
🌟 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
39.0407 USDC - $39.04
Undercollateralized
The bidding functions ( payBase and payFYToken ) should check if the vault is still Undercollateralized
before proceeding with the Auction.
Currently, the auction can only be cancelled via the cancel
function. This external function has to be called manually for checking if the vault is not Undercollateralized and cancel the auction.
Mitigation:
Make the cancel function public and call it from the two bidding functions.
The Governance variables such as lines, limit, auctioneerReward etc.. can be changed during an ongoing Auction. Even though this cannot be misused by a malicious user, it will cause inconsistencies in the calculation of variables like liquidatorCut
and auctioneerCut
(Calculated in _calcPayout function ).
Mitigation:
Store the line mapping and auctioneerReward in the Auction structure and use it in the bidding functions ( payBase and payFYToken ).
#0 - alcueca
2022-07-22T14:22:50Z
Thanks for the typos, regarding the other suggestions, no thank you.
🌟 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
17.4918 USDC - $17.49
uint256 inkAtEnd = uint256(artIn).wdiv(auction_.art).wmul(auction_.ink);
can be rearranged as follows. LinkinkAtEnd = uint256(artIn).wdiv(auction_.art).wmul(auction_.ink) = ( ( (artIn * 1e18) / auction_.art ) * auction_.ink ) / 1e18; = (artIn * auction_.ink) / auction_.art;
There is no need to use WMul and Wdiv in this specific case.
So final equation will be:
uint256 inkAtEnd = (artIn * auction_.ink) / auction_.art
;
uint256(1e18 - initialProportion).wmul(elapsed.wdiv(duration))
can be rearranged as follows.uint256(1e18 - initialProportion).wmul(elapsed.wdiv(duration)) = ( uint256(1e18 - initialProportion) * ((elapsed * 1e18) / duration) ) / 1e18 = ( uint256(1e18 - initialProportion) * elapsed) / duration
Since the above multiplication can never overflow we can safely put them in an unchecked block.
So 3 lines of equation here can be re-written as follows:
unchecked { proportionNow = uint256(initialProportion) + ( uint256(1e18 - initialProportion) * elapsed) / duration }
Function Name | Original Cost(A) | Optmized Code cost(B) | Gas Saved(A-B) |
---|---|---|---|
Deployment Cost | 3076398 | 3071190 | 5208 |
calcPayout | 10420 | 9806 | 614 |
payBase | 20431 | 19890 | 541 |
payFYToken | 19219 | 18678 | 541 |