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: 9/19
Findings: 2
Award: $390.20
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: CertoraInc, Dravee, Funen, cccz, delfin454000, dirk_y, ilan, rayn, rishabh
233.261 USDC - $233.26
https://github.com/code-423n4/2022-04-axelar/blob/main/src/ERC20.sol#L48
its said that : ``` * All three of these values are immutable``
but in actual codename
and symbol
arent immutable value. so it would be missleading information on comment sectioin.
##Tool Used Manual Review, Remix
##Recommended Mitigation Change it or remove it
#0 - deluca-mike
2022-04-20T08:01:43Z
Good catch. Confirmed, will remove this comment. Strings (non-value types) cannot be immutable.
https://github.com/code-423n4/2022-04-axelar/blob/main/src/DepositHandler.sol#L6-L7
This implementation for nonReenter, can be used 1 and 2, instead of 0 and 1 for saving more gas.
##Tool Used Manual Review
##POC
// Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect.
https://github.com/code-423n4/2022-04-axelar/blob/main/src/MintableCappedERC20.sol
set cap
as immutable for saving more gas.
Manual Review
https://github.com/code-423n4/2022-04-axelar/blob/main/src/ERC20.sol
Using msg.sender was less cost gas than _msg.Sender(). This _msg.Sender() was a replacement for msg.sender.For regular transactions it returns msg.sender and for meta transactions it can be used to return the end user (rather than the relayer). but the implementation for msg.sender can saving more gas more.
##Tool Used Manual Review
This implementation below can be saving more gas, has the same output either.
##Tool Used Remix & test
##Recommended Mitigation
if (_isOwner(epoch, accounts[i]) && ++validSignerCount >= threshold) return true; // 6960521 before
change to :
if (_isOwner(epoch, accounts[i]) || ++validSignerCount >= threshold) return true; // 6960341 after
Using i++ instead ++i for all the loops, the variable i is incremented using i++. It is known that implementation by using ++i costs less gas per iteration than i++.
Remix
main/src/AxelarGatewayMultisig.sol#L118 main/src/AxelarGatewayMultisig.sol#L140 main/src/AxelarGatewayMultisig.sol#L182 main/src/AxelarGatewayMultisig.sol#L271 main/src/AxelarGatewayMultisig.sol#L293 main/src/AxelarGatewayMultisig.sol#L332 main/src/AxelarGatewayMultisig.sol#L495 main/src/AxelarGatewayMultisig.sol#L526
this can be shorten by not checking if (success)
just passing into emit and can be saving more gas instead.
##Tool Used Test, Remix
##Recommended Mitigation Remove if (success) and pass into emit.
since if was ignore duplicate commandId received, no function inside contract was called so it would be effective that remove it and saving more gas.
##Tool Used Manual Review, test
#0 - deluca-mike
2022-04-20T08:00:14Z
"Better way to use nonReenter for saving more gas" Confirmed.
"Variable can be set as immutable for saving gas" Confirmed.
"Used msg.sender than _msg.sender() for saving more gas" Confirmed. We will remove Context.
"Used || operator for saving more gas" Disputed. The outputs are very much not going to be the same. We are checking that the account is an owner AND that the count so far of owners is greater than the threshold, not OR.
"using ++i than i++ for saving more gas" Confirmed.
"Unnecessary check" Disputed. The check is very necessary as it prevent event missions when the command execution did not succeed, which can happen.
"Unnecessary Duplicate Check" Disputed. I don't understand the issue, and despite that, the check is very necessary as it prevents executing a command more than once.