Platform: Code4rena
Start Date: 23/05/2022
Pot Size: $50,000 USDC
Total HM: 44
Participants: 99
Period: 5 days
Judge: hickuphh3
Total Solo HM: 11
Id: 129
League: ETH
Rank: 89/99
Findings: 1
Award: $30.87
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xf15ers, 0xkatana, Chom, DavidGialdi, Dravee, ElKu, FSchmoede, Fitraldys, Funen, GimelSec, JC, Kaiziron, MaratCerby, Metatron, MiloTruck, Picodes, Randyyy, RoiEvenHaim, SmartSek, Tomio, UnusualTurtle, WatchPug, Waze, _Adam, antonttc, asutorufos, berndartmueller, blackscale, blockdev, c3phas, catchup, csanuragjain, defsec, delfin454000, ellahi, fatherOfBlocks, gzeon, hansfriese, ilan, joestakey, minhquanym, oyc_109, pauliax, pedroais, reassor, rfa, rotcivegaf, sach1r0, samruna, sashik_eth, simon135, z3s
30.8734 USDC - $30.87
++i
is cheaper than i++
Use prefix increment instead of postfix increment.
!= 0
is cheaper than > 0
(unsigned integers)When dealing with unsigned integers the != 0
comparison is equivalent to > 0
comparison. It is also cheaper, therefore you should use it instead.
For instance:
replace: BathToken.sol:634 bonusTokens.length > 0
with bonusTokens.length != 0
You can optimize for loops that iterate over array elements by caching the array length in a local variable. This will reduce the number of MLOADs and will save gas. For example:
for (uint256 i = 0; i < array.length; i++) { ... }
can be optimized to:
uint256 length = array.length; for (uint256 i = 0; i < length; i++) { ... }
As you did in BathPair.batchMarketMakingTrades
:
uint256 quantity = askNumerators.length; for (uint256 index = 0; index < quantity; index++) { ... }
BathToken.634
I recommend to remove the 'IF Condation' , becuase there is the same checking in the for. Instead:
if (bonusTokens.length > 0) { for (uint256 index = 0; index < bonusTokens.length; index++) { ... } }
Replace:
for (uint256 index = 0; index < bonusTokens.length; index++) { ... }
I recommend to reduce the error message in order to fit 32 bytes to save gas.
Revert strings that are longer than 32 bytes require at least one additional mstore, along with additional overhead for computing memory offset, etc.
Therefore change those revert string:
_offer.buy_gem.transferFrom(msg.sender, _offer.owner, spend) failed - check that you can pay the fee
_offer.pay_gem.transfer(msg.sender, quantity) failed
Offer was deleted or taken, or never existed.
Offer can not be cancelled because user is not owner, and market is open, and offer sells required amount of tokens.
must send as much ETH as max_fill_withFee
trying to cancel a non WETH order
must send enough native ETH to pay as weth and account for fee
VestingWallet: beneficiary is zero address
Caller is not the Bath Token beneficiary of these rewards
ERC20: transfer from the zero address
ERC20: transfer to the zero address
ERC20: transfer amount exceeds balance
ERC20: burn from the zero address
ERC20: burn amount exceeds balance
etc...
Function that not called internally (but can call only externally) can be declared as external that consume less gas than public.
This is due to the fact that solidity copies arguments to memory on a public
function, while external
read from calldata which is cheaper than memory allocation.
Therefore I suggest to change the declaration of the function Rubicon Router.get BookFromPair
to external.