PoolTogether contest - neko_nyaa's results

A no-loss prize-savings protocol.

General Information

Platform: Code4rena

Start Date: 01/12/2022

Pot Size: $26,900 USDC

Total HM: 3

Participants: 19

Period: 4 days

Judge: GalloDaSballo

Id: 188

League: ETH

PoolTogether

Findings Distribution

Researcher Performance

Rank: 14/19

Findings: 1

Award: $338.92

Gas:
grade-a

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Tricko

Also found by: 0x4non, AkshaySrivastav, Madalad, Rolezn, adriro, cryptonue, neko_nyaa

Labels

bug
G (Gas Optimization)
grade-a
G-02

Awards

338.9167 USDC - $338.92

External Links

Per the sponsor's requirements, each optimization's actual gas report will be included. All gas findings are tested independently of each other, without taking other findings into account.

Initial gas report:

Final gas report (after applying all listed findings):

Gas optimizations list

NumberDetailsInstances
[G-01]nonce can be uint96 to optimize storage read/writes2
[G-02]Increments can be unchecked (and made postfix)4

[G-01] nonce can be uint96 to optimize storage read/writes

Two applicable instances:

File: src/ethereum-optimism/EthereumToOptimismRelayer.sol

29:   uint256 internal nonce;
File: src/ethereum-arbitrum/EthereumToArbitrumRelayer.sol

40:   uint256 internal nonce;

The current storage layout for CrossChainRelayerArbitrum and CrossChainRelayerOptimism are as follow:

ICrossChainExecutor public executor; // storage slot 1
uint256 internal nonce; // storage slot 2

Interfaces are stored as an address in the storage, taking 160 bits. Therefore we can change nonce data type to uint96 to fit in one storage slot.

ICrossChainExecutor public executor; // storage slot 1
uint96 internal nonce; // still storage slot 1

The change brings the following optimizations to relayCalls():

  • Saves ~$20000$ gas for the first message by avoiding a Gsset, for the slot is already non-zero with an executor.
  • For CrossChainRelayerOptimism, saves a further ~$2000$ gas by replacing a Gcoldsload with Gwarmaccess, for both executor and nonce are accessed.

This also should not bring any security issues, given the maximum value for uint96 is approx. $10^{27}$, which is more than enough.

Gas report for G-01: https://gist.github.com/midori-fuse/df2a7b756502d159b254c64a212c39b3

[G-02] Increments can be unchecked (and made postfix)

This finding builds upon [GAS-4] of C4 automated tool.

Four applicable instances (same with [GAS-4]):

File: src/ethereum-arbitrum/EthereumToArbitrumRelayer.sol

78:     nonce++;
File: src/ethereum-optimism/EthereumToOptimismRelayer.sol

60:     nonce++;
File: src/ethereum-polygon/EthereumToPolygonRelayer.sol

56:     nonce++;
File: src/libraries/CallLib.sol

61:     for (uint256 _callIndex; _callIndex < _callsLength; _callIndex++) {
  • For each nonce instance, simply replaces with unchecked{++nonce;}.
  • For the CallLib loop, change to:
for (uint256 _callIndex; _callIndex < _callsLength;) {
    // for loop content
    unchecked{++_callsLength;}
}

Saves about ~$40$ gas per unchecked operations. If call data's length is long, the gas saved will be significant.

Gas report for G-02 (not counting G-01): https://gist.github.com/midori-fuse/996c6e5f56b2678ed9acdc6ff01b1b80

#0 - GalloDaSballo

2022-12-15T00:38:48Z

[G-01] nonce can be uint96 to optimize storage read/writes

Sweet find, awarding 5k for a non-zero write as that's what it will save in practice

[G-02] Increments can be unchecked (and made postfix)

100

5.1k

#1 - c4-judge

2022-12-26T23:14:07Z

GalloDaSballo marked the issue as grade-a

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