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: 51/99
Findings: 2
Award: $81.29
π 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
53.1414 USDC - $53.14
Low Severity
affiliateFee
is not cappedthere should be an upper bond of affiliateFee
, to make sure even the owner cannot maliciously or accidentally set an affiliateFee that is too high.
function setAffiliateFee(uint256 _affiliateFee) external onlyOwner { require(affiliateFee < 2000); // < 20% affiliateFee = _affiliateFee; emit LogSetAffiliateFee(block.number, _affiliateFee); }
π 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
28.1525 USDC - $28.15
fee
and isReserveEnabled
in LiquidityReserveStorage
.fee
can not be higher than base point units, and packing it with isReserveEnabled can save 1 SLAOD in functions like instantUnstake
Gas saving:
instantUnstakeReserve
: avg. 344930 β 342961 (2000 gas)StakingStorage
withdrawAmount
/ requestWithdrawAmount
donβt realistically need full 256 bit slot, packing these 2 will save gas for _withdrawFromTokemak
uint40 public timeLeftToRequestWithdrawal; // time (in seconds) before TOKE cycle ends to request withdrawal uint40 public warmUpPeriod; // amount of epochs to delay warmup vesting uint40 public coolDownPeriod; // amount of epochs to delay cooldown vesting uint40 public lastTokeCycleIndex; // last tokemak cycle index which requested withdrawals uint40 public affiliateFee; // fee to send TOKE rewards uint128 public requestWithdrawalAmount; // amount of staking tokens to request withdrawal once able to send uint128 public withdrawalAmount; // amount of stakings tokens available for withdrawal
Gas saving
claimWithdraw
: 152933 β 146400instantUnstakeReserve
: 344930 β 341710unstake
: 229140 β 221856enableLiquidityReserve
by removing redundant check and avoid using state variables2 tricks can be applied in this function:
// These 2 lines are redundent uint256 stakingTokenBalance = IERC20Upgradeable(stakingToken).balanceOf( msg.sender ); require( stakingTokenBalance >= MINIMUM_LIQUIDITY, "Not enough staking tokens" ); // ... stakingContract = _stakingContract; // only usin this is enough IERC20Upgradeable(stakingToken).safeTransferFrom( msg.sender, address(this), MINIMUM_LIQUIDITY );
_stakingContract
instead of stakingContract
in the approve line, because reading function parameter is cheaperIERC20Upgradeable(rewardToken).approve( _stakingContract, // instead of stakingContract which is state variable type(uint256).max );
Gas saving:
enableLiquidityReserve
: 187111 β 185874