Platform: Code4rena
Start Date: 21/06/2022
Pot Size: $50,000 USDC
Total HM: 31
Participants: 99
Period: 5 days
Judges: moose-code, JasoonS, denhampreen
Total Solo HM: 17
Id: 139
League: ETH
Rank: 48/99
Findings: 2
Award: $81.32
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1337, 0x1f8b, 0x29A, 0x52, 0xDjango, 0xNazgul, 0xNineDec, 0xc0ffEE, 0xf15ers, 0xmint, Bnke0x0, BowTiedWardens, Chom, ElKu, FudgyDRS, Funen, GalloDaSballo, GimelSec, JC, Kaiziron, Lambda, Limbooo, Metatron, MiloTruck, Noah3o6, Picodes, PumpkingWok, PwnedNoMore, Sm4rty, StErMi, TomJ, TrungOre, UnusualTurtle, Waze, _Adam, aga7hokakological, ak1, antonttc, berndartmueller, cccz, cryptphi, csanuragjain, defsec, delfin454000, dipp, elprofesor, exd0tpy, fatherOfBlocks, hake, hansfriese, hubble, joestakey, kenta, ladboy233, mics, oyc_109, pashov, pedr02b2, reassor, robee, samruna, scaraven, shung, sikorico, simon135, sseefried, tchkvsky, unforgiven, zzzitron
54.6089 USDC - $54.61
Generally, I found the code quite easy to understand and well commented throughout with only a few very minor issues
safeTransferFrom
instead of transferFrom
In case something unexepected happens, use safeTransferFrom
instead of transferFrom
.
__gap[]
after defining storage variablesThis applies to all the ...Storage.sol
contracts, as they are inherited with other contracts e.g. ERC20PermitUpgradeable
, if the developers ever want to add a new storage variable then it will shift all other storage variables causing inconsistencies and potentially break the contracts.
See here for more info
🌟 Selected for report: BowTiedWardens
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 0xmint, 8olidity, ACai, Bnke0x0, Chom, ElKu, Fabble, Fitraldys, FudgyDRS, Funen, GalloDaSballo, GimelSec, IllIllI, JC, Kaiziron, Lambda, Limbooo, MiloTruck, Noah3o6, Nyamcil, Picodes, PwnedNoMore, Randyyy, RedOneN, Sm4rty, StErMi, TomJ, Tomio, TrungOre, UnusualTurtle, Waze, _Adam, aga7hokakological, ajtra, antonttc, asutorufos, bardamu, c3phas, defsec, delfin454000, exd0tpy, fatherOfBlocks, hansfriese, ignacio, joestakey, kenta, ladboy233, m_Rassska, mics, minhquanym, oyc_109, pashov, reassor, robee, s3cunda, sach1r0, saian, sashik_eth, scaraven, sikorico, simon135, slywaters
26.7051 USDC - $26.71
https://github.com/shapeshift/foxy/blob/ff815e5ac85cda363b3979cac78646770759a146/src/contracts/Yieldy.sol#L192
Can be unchecked as a inequality check was already made previously
64
gas diff
https://github.com/shapeshift/foxy/blob/ff815e5ac85cda363b3979cac78646770759a146/src/contracts/Yieldy.sol#L212
Exact same situation as above
64
gas diff
uint256 creditAmount = _amount * rebasingCreditsPerToken; uint256 currentCredits = creditBalances[_address]; require(currentCredits >= creditAmount, "Not enough balance"); creditBalances[_address] = creditBalances[_address] - creditAmount; rebasingCredits = rebasingCredits - creditAmount; _totalSupply = _totalSupply - _amount;
We can place an unchecked expression around this block of code as a require
check was made above
This also applies to totalSupply
because totalSupply = rebasingCredits / rebasingCreditsPerToken
so if rebasingCredits >= creditAmount
it follows that totalSupply >= amount
64*3
gas diff
Additionally, creditBalances[_address]
is cached with currentCredits
so reusing that variable will use one less SLOAD
operation which costs less gas (even if the slot if warm)
84
gas diff
The block should be:
uint256 creditAmount = _amount * rebasingCreditsPerToken; uint256 currentCredits = creditBalances[_address]; require(currentCredits >= creditAmount, "Not enough balance"); unchecked { creditBalances[_address] = currentCredits - creditAmount; rebasingCredits = rebasingCredits - creditAmount; _totalSupply = _totalSupply - _amount; }
https://github.com/shapeshift/foxy/blob/ff815e5ac85cda363b3979cac78646770759a146/src/contracts/Yieldy.sol#L252-L253
As rebasingCredits >=
creditBalances[_address]`, we can swap the two lines and the second addition can be unchecked
64
gas diff
Change
creditBalances[_address] = creditBalances[_address] + creditAmount; rebasingCredits = rebasingCredits + creditAmount;
to
rebasingCredits = rebasingCredits + creditAmount; unchecked { creditBalances[_address] = creditBalances[_address] + creditAmount; }
https://github.com/shapeshift/foxy/blob/ff815e5ac85cda363b3979cac78646770759a146/src/contracts/Staking.sol#L494
withdrawalAmount
is always larger than equal to info.amount
therefore this subtraction can be unchecked
64
gas diff
~ 532
gas should be saved
This is estimated using solidity 0.8.9
and optimisations with 200
runs