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
Rank: 7/19
Findings: 2
Award: $720.25
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: CertoraInc, Dravee, Funen, cccz, delfin454000, dirk_y, ilan, rayn, rishabh
name
and symbol
should be immutableA mismatch between doc and code.
Proof of Concept:
in ERC20.sol constructor:
/** * @dev Sets the values for {name}, {symbol}, and {decimals}. All three of these values are immutable: they can only be set once during construction. */
however, in the code they are declared:
string public name;
string public symbol;
therefore they should be immutuable, and anyway there is a mismatch between the doc and the code.
Recommended Mitigation Steps: change variables to
string public imuutable name;
string public immutable symbol;
Most functions and logic are missing documentation and comments
AdminMultisigBase AxelarGateway AxelarGatewayMultisig AxelarGatewaySinglesig AxelarGatewayProxy BurnableMintableCappedERC20 ERC20Permit MintableCappedERC20 Ownable TokenDeployer
In DepositHandler.sol, use enum instead of 2 unit256 for LOCK variables. will make the code nicer and more structured.
#0 - deluca-mike
2022-04-20T08:19:44Z
Good catch that the comment is incorrect, but the solution is actually to remove the comment, since strings (non-value types) cannot be immutable in storage.
Acknowledged. They will be documented in a future release.
Acknowledged, but will not change in this release.
i++ is generally more expensive because it must increment a value and return the old value, so it may require holding two numbers in memory. ++i only uses one number in memory.
Example:
for (uint256 i; i < adminCount; i++) -> for (uint256 i; i < adminCount; ++i)
line 255 in AxelarGateway.sol.
Affected contracts: AdminMultisigBase.sol AxelarGateway.sol AxelarGatewayMultisig.sol AxelarGatewaySinglesig.sol AddressFormat.sol
using calldata for function parameters which do not change inside the function, instead of memory, has proven to save gas.
AxelarGatewayMultisig.sol, l41 AdminMultisigBase.sol, l144 AxelarGateway.sol AxelarGatewaySinglesig.sol
save array length locally instead of calling .length in the loop every iteration. Fewer memory calls result in less gas consumption.
POC:
for (uint256 i; i < accounts.length - 1; ++i)
every loop call accounts.length is called
change to length = accounts.length for (uint256 i; i < length - 1; ++i) every loop call accounts.length is called
Affected contracts: AxelarGatewayMultisig._isSortedAscAndContainsNoDuplicate AddressFormat.sol, l14 (library)
cap
variable immutableimmutable variables consume less gas
change
uint256 public cap;
to
uint256 public immutable cap;
in MintableCappedERC20.sol
In DepositHandler.sol. using 3 state variables for the lock when actually just 1 is needed. Wasting storage space results in wasting gas, and many storage calls consume a lot of gas.
can resolve by changing lock mechanism to receive unit values;
set _lockedStatus = unit256(0)
and
set _lockedStatus = unit256(1)
Uninitialized variables are automatically initialized to 0, doing it explicitly will cost more gas.
poc:
for (uint256 i = 0; i < length; i++)
change to
for (uint256 i; i < length; i++)
in AddressFormat.sol
#0 - deluca-mike
2022-04-20T08:05:20Z
Confirmed.
Confirmed.
With recent versions of solidity, the compiler now does this itself for arrays with fixed lengths. SO a good suggestion, but not needed anymore.
Confirmed.
Disputed. The variables being referred to are not state variables, but constants that end up being in-lined by the compiler.
While the compiler does not actually do any operation here, thus no extra gas is used, it is still a good suggestion in general, so we will do it.