Platform: Code4rena
Start Date: 08/06/2022
Pot Size: $115,000 USDC
Total HM: 26
Participants: 72
Period: 11 days
Judge: leastwood
Total Solo HM: 14
Id: 132
League: ETH
Rank: 66/72
Findings: 1
Award: $85.33
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 0xmint, BowTiedWardens, ElKu, Fitraldys, Funen, Kaiziron, Lambda, Metatron, MiloTruck, Randyyy, Ruhum, SmartSek, TomJ, Tomio, UnusualTurtle, Waze, _Adam, apostle0x01, asutorufos, c3phas, catchup, csanuragjain, defsec, fatherOfBlocks, hansfriese, hyh, ignacio, joestakey, k, kaden, nahnah, oyc_109, rfa, robee, sach1r0, simon135, slywaters
85.3344 USDC - $85.33
Title: Packing of variable in struct in LibConnextStorage.sol
Occurrences: https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/libraries/LibConnextStorage.sol#L38-L51 https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/libraries/LibConnextStorage.sol#L109-L310
Bool has 1 byte size, and address has 20 byte size if we put bool type var next to address, we can save storage slot (1 slot has max size 32 bytes)
Change to:
struct CallParams { address to; bytes callData; uint32 originDomain; uint32 destinationDomain; address agent; bool forceSlow; // @audit-info: Move bool here near address bool receiveLocal; address recovery; address callback; uint256 callbackFee; uint256 relayerFee; uint256 slippageTol; }
Title: Better way to do increment
Using ++ var is more efficient than doing += 1 increment Change to:
++s.nonce;
It can save 17 gas execution fee
Title: Avoid SLOAD to emit XCalled
We can increase s.nonce by 1 and dong MSTORE at the same line:
uint _sNonce = s.nonce++ //@audit-info: caching s.nonce and do increment emit XCalled(transferId, _args, eventArgs, _sNonce, message, msg.sender); // MLOAD instead SLOAD
By doing this way we can save 162 gas execution
Title: Using unchecked and prefix increment for i
Change to:
for (uint256 i; i < numFacets;) { address facetAddress_ = ds.facetAddresses[i]; facets_[i].facetAddress = facetAddress_; facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors; unchecked{++i;} }
Title: Using storage for struct
Instead of caching s.adoptedToCanonical[adopted] into memory, using storage is more gas efficient. It's just called once in the function
ConnextMessage.TokenId storage canonical = s.adoptedToCanonical[adopted];
It saves 2176 gas execution gas fee
Title: Emitting block.timestamp is better
Instead of doin SLOAD to emit RouterOwnershipRenunciationProposed
, we can use block.timestamp
emit RouterOwnershipRenunciationProposed(block.timestamp);
Title: Using delete statement to set to default value
https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L272 https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L283 https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L288 https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L166 https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L323-L324 https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L379 https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L445-L447
Using delete statement can save 4 gas on setting value to default value
delete s._routerOwnershipTimestamp;
Title: Avoid SLOAD while emitting OwnershipProposed
By using newlyProposed
var we can save gas by avoiding SLOAD
emit OwnershipProposed(newlyProposed);
#0 - liu-zhipeng
2022-07-01T03:36:01Z