code-423n4 / 2022-07-axelar-findings

0 stars 0 forks source link

Gas Optimizations #234

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

AXELAR

Gas Optimizations Report

You can use ++i instead of i++ to save a gas (same for --i/i--)

This will save you 6 gas per instance/loop

There are 5 instances of this issue:

File: contracts/deposit-service/AxelarDepositService.sol

114:    for (uint256 i; i < refundTokens.length; i++) {

168:    for (uint256 i; i < refundTokens.length; i++) {

204:    for (uint256 i; i < refundTokens.length; i++) {

https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/deposit-service/AxelarDepositService.sol#L114

File: contracts/gas-service/AxelarGasService.sol

123:    for (uint256 i; i < tokens.length; i++) {

https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/gas-service/AxelarGasService.sol#L123

File: contracts/AxelarGateway.sol

207:    for (uint256 i = 0; i < symbols.length; i++) {

https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/AxelarGateway.sol#L207

Intializing the variables to zero that aren't constant or immutable will cost more gas rather than use default value of zero.

If you not overwritte the default value you will save 8 gas for stack variables and more for storage and memory variables.

There are 6 instances of this issue:

File: contracts/auth/AxelarAuthWeighted.sol

68:     uint256 totalWeight = 0;

69:     for (uint256 i = 0; i < weightsLength; ++i) {

94:     uint256 operatorIndex = 0;

95:     uint256 weight = 0;

98:     for (uint256 i = 0; i < signatures.length; ++i) {

https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/auth/AxelarAuthWeighted.sol#L68

File: contracts/AxelarGateway.sol

207:    for (uint256 i = 0; i < symbols.length; i++) {

https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/AxelarGateway.sol#L207

Empty blocks should be removed or emit something

The code that don't exist anymore should be removed or refactored to use to do something useful.

There are 1 instances of this issue:

File: xc20/contracts/ERC20.sol

255:    function _beforeTokenTransfer(

https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/ERC20.sol#L255

Using of custom errors is recommended instead of using the revert()/require() functions.

Custom errors are available from solidity version 0.8.4. This instaces below is 0.8.9

There are 1 instances of this issue:

File: contracts/AxelarGatewayProxy.sol

48:     receive() external payable {

https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/AxelarGatewayProxy.sol#L48

If you use uint/int than are smaller than 256 bits outside of structure will cost you more gas

Using a smaller uints and ints that are smaller than 256 bits or 32 bytes will cost more gas this is because the EVM how operates.

There are 1 instances of this issue:

File: contracts/auth/AxelarAuthWeighted.sol

14:     uint8 internal constant OLD_KEY_RETENTION = 16;

If you use ++i should be unchecked{++i} in for-loops

Using a `unchecked{++i} will cost more gas because the default compiler overflow and underflow safety checks. This is true from version 0.8.0, code below match that requirments.

There are 1 instances of this issue:

File: contracts/auth/AxelarAuthWeighted.sol

17:     for (uint256 i; i < recentOperators.length; ++i) {

69:     for (uint256 i = 0; i < weightsLength; ++i) {

98:     for (uint256 i = 0; i < signatures.length; ++i) { 

116:    for (uint256 i; i < accounts.length - 1; ++i) {    
File: contracts/deposit-service/AxelarDepositService.sol

114:    for (uint256 i; i < refundTokens.length; i++) {

168:    for (uint256 i; i < refundTokens.length; i++) {

204:    for (uint256 i; i < refundTokens.length; i++) {   
File: contracts/gas-service/AxelarGasService.sol

123:    for (uint256 i; i < tokens.length; i++) {
File: contracts/AxelarGateway.sol

207:    for (uint256 i = 0; i < symbols.length; i++) {

USING FUNCTION MODIFIER INSTEAD REPEATING if STATEMENT

Function modifier with require that checks address isn't a zero address cost less than if statement with revert.If statement are removed and replaced with functional modifier.

There are 1 instances of this issue:

File: contracts/ERC20.sol 
168:   if (sender == address(0) || recipient == address(0)) revert InvalidAccount();
187:    if (account == address(0)) revert InvalidAccount();
208:   if (account == address(0)) revert InvalidAccount();
235:   if (owner == address(0) || spender == address(0)) revert InvalidAccount();

https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/ERC20.sol#L168

This can be done with function modifier like this:

modifier notZeroAddress(address value){
require(value != address(0));      
 _;    
}
GalloDaSballo commented 2 years ago

Less than 300 gas saved