Open code423n4 opened 2 years ago
L06: If SKALE chain owner adds custom ERC20 it must allow TokenManager to minting it. Custom token can have custom logic of minting
N02: In our code style we always put public
functions after external
G01: They are called inside smart contract in child contracts
Would like to see explanation of vulns like other wardens, downgrading to non-critical
Also non-critical as it's just explicit inheritance
Non-critical as if all messages are unique you don't need the contract, also the revert trace will show you the contract as well
I think this is an interesting and valid finding
Agree but Non-critical
Disagree with finding per-sponsor reply
Will leave as valid although the warden has missed some bugs from 0.8.6
Agree, but non-critical as it's just a refactoring
Agree
Per the sponsor's styleguide, consistency > dogma
I believe this is a test function but finding is valid nonetheless
I really like this report as it's short and sweet and has some interesting finds, good job!
Low Severity
[L01] Outdated version of inherited contracts and upgrade library
[L02] Not calling inherited function directly
For instance https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/SkaleManagerClient.sol#L62
is not necessary. Just use
__AccessControlEnumerable_init();
. It compiles and all tests passed.[L03] Require messages not indicative of the contracts
Almost all
require
message has no indication of which contract it is coming from. It is a good practice for debugging and monitoring purposes to mark the contract that reverted.For example, https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/MessageProxy.sol#L188 the revert message could be
"MessageProxy: Extra contract is not registered"
. Many other instances are also present in almost all contracts by globally searchrequire
.[L04] Use initializer instead of onlyInitializing
In
OpenZeppline-contracts-upgradeable
v4.5initializer
has a new modifier https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/20380ee699406211ae88c4edd11b0af87c8abdd6/contracts/proxy/utils/Initializable.sol#L72to mark and protect the initializing functions that should not be called directly called.
Instances such as
https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/SkaleManagerClient.sol#L54-L60 , which is inherited by
Twin.sol
https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/Twin.sol#L95-L101
https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/DepositBox.sol#L99-L107
[L05] Inconsistent use of schainHash or schainName when referencing a schain
There is inconsistency in referring to a schain, sometimes by bytes32 hash, sometimes by string name in a single contract.
For example, in
SkaleManagerClient
,https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/SkaleManagerClient.sol#L70-L73 uses schainNash and https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/SkaleManagerClient.sol#L42-L48 uses schainName.
Bytes32 should be preferred over string for gas-saving reasons.
[L06] Schain owner cannot add ERC20 token manually as specified in the doc
The specification in the doc is inconsistent with the code. For example in https://docs.skale.network/ima/1.2.x/managing-erc20 and the diagram https://docs.skale.network/ima/1.2.x/flows#_manual_setup_steps is not consistent with the code.
Minter role in ERC20 is granted automatically either to
TokenManagerERC20
or to the deployer in the constructor.[L07] Outdated Solidity Version
Solidity version
0.8.6
is used throughout. Many updates have been applied to the compiler. A more recent version such as0.8.10
would work better. The latest version is0.8.11
.[L08] Use OnlyRole() modifier from inherited contract AccessControlUpgradeable
Many instances can be simplified using the
OnlyRole
modifier.https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/20380ee699406211ae88c4edd11b0af87c8abdd6/contracts/access/AccessControlUpgradeable.sol#L75-L78
For instance, https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/schain/MessageProxyForSchain.sol#L237 and https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/schain/tokens/ERC20OnChain.sol#L60-L61 and many other role-based
require
statements.Informational
[N01] NatSpec on Events and Functions
Many functions and events do not have
@param
and@return
labelled in Natspec, for instancehttps://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/schain/MessageProxyForSchain.sol#L261-L265
and many others.
[N02]
initialize
functions positioned too much down the contractinitialize
function is a special feature in upgradeability patterns and often important and prone to grave consequences too. It is a good practice to put them at the beginning of the contract, like those in the OpenZeppelin-contracts-upgradeable library.[N03] Repeated code
Repeated unimplemented function
postIncomingMessages()
in bothand "@skalenetwork/ima-interfaces/IMessageProxy.sol" .
One can remove the one in
MessageProxy.sol
without affecting any test results.Gas Saving
[G01] public functions can be external
Here are two example instances
https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/MessageProxy.sol#L262
https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/MessageProxy.sol#L313