Rubicon contest - DavidGialdi's results

An order book protocol for Ethereum, built on L2s.

General Information

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

Rubicon

Findings Distribution

Researcher Performance

Rank: 89/99

Findings: 1

Award: $30.87

🌟 Selected for report: 0

🚀 Solo Findings: 0

++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

Cache Array Length Outside of Loop

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++) { ... }

Unnecessary If Condation in 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++) { ... }

Long Error messages (Long revert Strings)

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...

Use external function instead of public function

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.

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter