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: 65/99
Findings: 2
Award: $79.72
🌟 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
Identical code is repeated in Staking.sol lines 84-87 and 88-91, as shown below:
IERC20Upgradeable(YIELDY_TOKEN).approve( LIQUIDITY_RESERVE, type(uint256).max ); IERC20Upgradeable(YIELDY_TOKEN).approve( LIQUIDITY_RESERVE, type(uint256).max );
Recommendation: Remove duplicate code
🌟 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.5777 USDC - $26.58
Require
revert string is too longThe revert strings below can be shortened to 32 characters or fewer (as shown) to save gas
libraries/ERC20Upgradeable.sol: L189-192
require( currentAllowance >= amount, "ERC20: transfer amount exceeds allowance" );
Change message to ERC20: transfer amt > allowance
libraries/ERC20Upgradeable.sol: L245-248
require( currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero" );
Change message to ERC20: decreased allowance < 0
libraries/ERC20Upgradeable.sol: L275
require(sender != address(0), "ERC20: transfer from the zero address");
Change message to ERC20: xfer from the 0 address
libraries/ERC20Upgradeable.sol: L276
require(recipient != address(0), "ERC20: transfer to the zero address");
Change message to ERC20: xfer to the zero address
libraries/ERC20Upgradeable.sol: L281-284
require( senderBalance >= amount, "ERC20: transfer amount exceeds balance" );
Change message to ERC20: transfer amount > balance
libraries/ERC20Upgradeable.sol: L328
require(account != address(0), "ERC20: burn from the zero address");
Change message to ERC20: burn from the 0 address
libraries/ERC20Upgradeable.sol: L333
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
Change message to ERC20: burn amount > balance
libraries/ERC20Upgradeable.sol: L362
require(owner != address(0), "ERC20: approve from the zero address");
Change message to ERC20: approve from zero address
libraries/ERC20Upgradeable.sol: L363
require(spender != address(0), "ERC20: approve to the zero address");
Change message to ERC20: approve to the 0 address
require
functionSplitting such functions into separate require()
statements (instead of using '&&') saves gas
require( _stakingToken != address(0) && _yieldyToken != address(0) && _tokeToken != address(0) && _tokePool != address(0) && _tokeManager != address(0) && _tokeReward != address(0) && _liquidityReserve != address(0), "Invalid address" );
Recommendation:
require(_stakingToken != address(0), "Invalid address"); require(_yieldyToken != address(0), "Invalid address"); require(_tokeToken != address(0), "Invalid address"); require(_tokePool != address(0), "Invalid address"); require(_tokeManager != address(0), "Invalid address"); require(_tokeReward != address(0), "Invalid address"); require(_liquidityReserve != address(0), "Invalid address");
The require function shown below occurs twice:
contracts/Staking.sol: L574-577 contracts/Staking.sol: L611-614
require( !isUnstakingPaused && !isInstantUnstakingPaused, "Unstaking is paused" );
Recommendation:
require(!isUnstakingPaused, "Unstaking is paused"); require(!isInstantUnstakingPaused, "Unstaking is paused");
contracts/Staking.sol: L605-609
require( CURVE_POOL != address(0) && (curvePoolFrom == 1 || curvePoolTo == 1), "Invalid Curve Pool" );
Recommendation:
require(CURVE_POOL != address(0), "Invalid Curve Pool"); require(curvePoolFrom == 1 || curvePoolTo == 1, "Invalid Curve Pool");
contracts/Migration.sol: L20-23
require( _oldContract != address(0) && _newContract != address(0), "Invalid address" );
Recommendation:
require(_oldContract != address(0), "Invalid address"); require(_newContract != address(0), "Invalid address");
contracts/LiquidityReserve.sol: L44-47
require( _stakingToken != address(0) && _rewardToken != address(0), "Invalid address" );
Recommendation:
require(_stakingToken != address(0), "Invalid address"); require(_rewardToken != address(0), "Invalid address");
!= 0
instead of > 0
in a require
statement if variable is an unsigned integer (uint
)!= 0
should be used where possible since > 0
costs more gas
require(_recipient.amount > 0, "Must enter valid amount");
Change _recipient.amount > 0
to _recipient.amount != 0
Identical require
condition occurs in all three lines below:
Example:
require(_amount > 0, "Must have valid amount");
Change _amount > 0
to _amount != 0
in each case
require(_totalSupply > 0, "Can't rebase if not circulating");
Change _totalSupply > 0
to _totalSupply != 0
require(rebasingCreditsPerToken > 0, "Invalid change in supply");
Change rebasingCreditsPerToken > 0
to rebasingCreditsPerToken != 0
Storage of uints or ints smaller than 32 bytes incurs overhead. Instead, use size of at least 32, then downcast where needed
Recommendation: Increase size from uint8
to at least uint32
in the lines referenced below:
uint8 _v,
uint8 _decimal
libraries/ERC20PermitUpgradeable.sol: L70
uint8 v,