Platform: Code4rena
Start Date: 18/02/2022
Pot Size: $125,000 USDC
Total HM: 13
Participants: 24
Period: 14 days
Judge: GalloDaSballo
Total Solo HM: 6
Id: 88
League: ETH
Rank: 18/24
Findings: 2
Award: $530.38
π Selected for report: 0
π Solo Findings: 0
skalenetwork/ima-c4-audit
1 a wrong Indentation.
https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/schain/TokenManagerLinker.sol#L99
#0 - DimaStebaev
2022-03-14T15:29:01Z
Agreed.
#1 - GalloDaSballo
2022-05-05T14:44:57Z
Finding is valid and non-critical
π Selected for report: IllIllI
Also found by: 0x1f8b, CertoraInc, TerrierLover, Tomio, WatchPug, d4rk, gzeon, kenta, kyliek, m_smirnova2020, rfa, robee, saian, ye0lde
skalenetwork/ima-c4-audit gas optimization
1 use cache for storage in registerExtraContractForAll and removeExtraContractForAll.
https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/MessageProxy.sol#L174-L175 https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/MessageProxy.sol#L188-L189
EnumerableSetUpgradeable.AddressSet storage registryContracts = _getRegistryContracts()[bytes32(0)]; require(!registryContracts.contains(extraContract), "Extra contract is already registered"); registryContracts.add(extraContract);
EnumerableSetUpgradeable.AddressSet storage registryContracts = _getRegistryContracts()[bytes32(0)]; require(registryContracts.contains(extraContract), "Extra contract is not registered"); registryContracts.remove(extraContract);
2 use unchecked. from < to is already checked so you can use unchecked for the following line to save gas.
https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/MessageProxy.sol#L220
Unchecked { contractsInRange = new address[](to -from); }
3 use cache for storage in postOutgoingMessage.
https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/MessageProxy.sol#L291-L302
ConnectedChainInfo storage _connectedChain = connectedChains[targetChainHash]; require(_connectedChain.inited, "Destination chain is not initialized"); _authorizeOutgoingMessageSender(targetChainHash);
emit OutgoingMessage( targetChainHash, _connectedChain.outgoingMessageCounter, msg.sender, targetContract, data ); _connectedChain.outgoingMessageCounter += 1;
4 use cache for storage in _registerExtraContract and _removeExtraContract
https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/MessageProxy.sol#L365-L371 https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/MessageProxy.sol#L389-L390
5 Input must be checked earlier to save gas. The following line can be checked at the beginning of the function to save gas.
https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/schain/TokenManager.sol#L192
6 Use initial value for uint256 and ++i in loop in TokenManagerLinker.sol
https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/schain/TokenManagerLinker.sol#L122 https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/schain/TokenManagerLinker.sol#L151 https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/schain/TokenManagerLinker.sol#L166 https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/schain/TokenManagerLinker.sol#L178 https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/schain/TokenManagerLinker.sol#L192
7 use unchecked. balance < MINIMUM_BALANCE is already checked in if sentence, so you can use unchecked.
uint missingAmount; unchecked { missingAmount = MINIMUM_BALANCE - balance; }
8 No need to use cache. _outgoingMessageDataHash[message.dstChainHash][message.msgCounter] Is used only one time in function so you donβt use cache
if (_outgoingMessageDataHash[message.dstChainHash][message.msgCounter] == _hashOfMessage(message)) isValidMessage = true;
#0 - yavrsky
2022-03-14T18:22:15Z
Only marginal gas improvements.
#1 - GalloDaSballo
2022-04-28T17:32:24Z
Not convinced this will save gas as you're still dealing with storage pointers
Saves 20g
Same as 1, caching a storage pointer won't save gas
Same as 1
Don't think it makes much difference
3 * 5 * 2 = 30
This would save 20 gas
Would save 6 gas
Total Gas Saved 76