Axelar Network contest - 0xkatana's results

Decentralized interoperability network.

General Information

Platform: Code4rena

Start Date: 07/04/2022

Pot Size: $50,000 USDC

Total HM: 5

Participants: 19

Period: 5 days

Judge: 0xean

Total Solo HM: 4

Id: 109

League: COSMOS

Axelar Network

Findings Distribution

Researcher Performance

Rank: 13/19

Findings: 1

Award: $197.36

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: IllIllI

Also found by: 0v3rf10w, 0xNazgul, 0xkatana, CertoraInc, Chom, Dravee, Funen, Hawkeye, Tomio, ilan, nahnah, rayn, rfa

Labels

bug
G (Gas Optimization)

Awards

197.3645 USDC - $197.36

External Links

1. Use != 0 instead of > 0

Impact

Using > 0 uses slightly more gas than using != 0. Use != 0 when comparing uint variables to zero, which cannot hold values below zero

Proof of Concept

One instance of this gas savings was found https://github.com/code-423n4/2022-04-axelar/blob/main/src/AxelarGateway.sol#L269

Tools Used

grep

Replace > 0 with != 0 to save gas

2. Use prefix not postfix in loops

Impact

Using a prefix increment (++i) instead of a postfix increment (i++) saves gas for each loop cycle, so it can have a big gas impact when the loop executes on a large number of elements.

Proof of Concept

Prefix is used in some for loops, but these locations use postfix:

util/AddressFormat.sol:14: for (uint256 i = 0; i < data.length; i++) { AxelarGatewayMultisig.sol:118: for (uint256 i; i < accounts.length; i++) { AxelarGatewayMultisig.sol:140: for (uint256 i; i < ownerCount; i++) { AxelarGatewayMultisig.sol:181: for (uint256 i; i < accountLength; i++) { AxelarGatewayMultisig.sol:271: for (uint256 i; i < accounts.length; i++) { AxelarGatewayMultisig.sol:293: for (uint256 i; i < operatorCount; i++) { AxelarGatewayMultisig.sol:332: for (uint256 i; i < accountLength; i++) { AxelarGatewayMultisig.sol:495: for (uint256 i; i < signatureCount; i++) { AxelarGatewayMultisig.sol:526: for (uint256 i; i < commandsLength; i++) { AdminMultisigBase.sol:51: for (uint256 i; i < adminCount; i++) { AdminMultisigBase.sol:158: for (uint256 i; i < adminLength; i++) { AxelarGatewaySinglesig.sol:269: for (uint256 i; i < commandsLength; i++) { AxelarGateway.sol:225: for (uint256 i; i < adminCount; i++) {

Tools Used

grep

Use prefix not postfix to increment in a loop

3. Use Solidity errors instead of require

Impact

Solidity errors introduced in version 0.8.4 can save gas on revert conditions https://blog.soliditylang.org/2021/04/21/custom-errors/ https://twitter.com/PatrickAlphaC/status/1505197417884528640

Proof of Concept

Some error messages are used, but many require blocks still exist in the code. Many zero address check instances are in ERC20.sol https://github.com/code-423n4/2022-04-axelar/blob/main/src/ERC20.sol#L164 https://github.com/code-423n4/2022-04-axelar/blob/main/src/ERC20.sol#L165 https://github.com/code-423n4/2022-04-axelar/blob/main/src/ERC20.sol#L184 https://github.com/code-423n4/2022-04-axelar/blob/main/src/ERC20.sol#L205 https://github.com/code-423n4/2022-04-axelar/blob/main/src/ERC20.sol#L232 https://github.com/code-423n4/2022-04-axelar/blob/main/src/ERC20.sol#L233

Tools Used

Manual analysis

Replace require blocks with new solidity errors described in https://blog.soliditylang.org/2021/04/21/custom-errors/

4. Add payable to functions that won't receive ETH

Impact

Identifying a function as payable saves gas. Functions that have the onlyOwner modifier cannot be called by normal users and will not mistakenly receive ETH. These functions can be payable to save gas.

Proof of Concept

There are many functions that have the onlyOwner modifier and can be payable https://github.com/code-423n4/2022-04-axelar/blob/main/src/Ownable.sol#L20 https://github.com/code-423n4/2022-04-axelar/blob/main/src/MintableCappedERC20.sol#L23 https://github.com/code-423n4/2022-04-axelar/blob/main/src/MintableCappedERC20.sol#L31 https://github.com/code-423n4/2022-04-axelar/blob/main/src/BurnableMintableCappedERC20.sol#L48

Tools Used

Manual analysis

Add payable to these functions for gas savings

5. Use simple comparison

Impact

The comparison operators >= and <= use more gas than >, <, or ==. Replacing the >= and ≤ operators with a comparison operator that has an opcode in the EVM saves gas

Proof of Concept

This code is in _isSortedAscAndContainsNoDuplicate from AxelarGatewayMultisig is the same as an if/else statement https://github.com/code-423n4/2022-04-axelar/blob/main/src/AxelarGatewayMultisig.sol#L41-L49

function _isSortedAscAndContainsNoDuplicate(address[] memory accounts) internal pure returns (bool) { for (uint256 i; i < accounts.length - 1; ++i) { if (accounts[i] >= accounts[i + 1]) { return false; } } return true; }

A simple comparison can be used for gas savings by reversing the logic. Because this happens in a for loop, the savings may be more noticeable

function _isSortedAscAndContainsNoDuplicate(address[] memory accounts) internal pure returns (bool) { for (uint256 i; i < accounts.length - 1; ++i) { if (accounts[i] < accounts[i + 1]) { return true; } } return false; }

The same gas efficiency can be used in two other places with the same pattern https://github.com/code-423n4/2022-04-axelar/blob/main/src/AxelarGatewayMultisig.sol#L114-L123 https://github.com/code-423n4/2022-04-axelar/blob/main/src/AxelarGatewayMultisig.sol#L267-L276

Tools Used

Manual analysis

Replace the comparison operator and reverse the logic to save gas using the suggestions above

#0 - deluca-mike

2022-04-20T08:16:59Z

Use != 0 instead of > 0

Confirmed.

Use prefix not postfix in loops

Confirmed.

Use Solidity errors instead of require

Confirmed.

Add payable to functions that won't receive ETH

Acknowledged, but will not do since it is gas savings at the expense of confusion, readability issues, and the possibilities for ETH to be received.

Use simple comparison

Disputed. While correct about the gas savings, the proposed changes to the functions would actually break their functionality entirely. Returning true after the first positive test would result ignoring the rest of the data. Specifically, we want to return false for any issue, and only return true if there were no issues.

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