Omniscia Nexera Audit

ChainidTools Manual Review Findings

ChainidTools Manual Review Findings

CTS-01M: Inconsistent Restriction of Self-Chain

Description:

The ChainidTools::requireCurrentChain function differs from the ChainidTools::chainid implementation in the sense that it does not necessarily ensure that the local block.chainid can fit in the uint32 data type.

In turn, this permits a one-to-many payload to be processed as the block.chainid value has its upper bits stripped causing multiple block.chainid values to equal the "current chain" of a single payload.

Impact:

A single payload may be decoded by multiple chains due to an insecure down-casting operation of the block.chainid when the ChainidTools::requireCurrentChain function is invoked.

Example:

contracts/utils/ChainidTools.sol
16/**
17 * @dev Converts block.chainid to uint32 chainid
18 * @return uint32 chainid
19 */
20function chainid() internal view returns (uint32) {
21 if (block.chainid < type(uint32).max) {
22 return uint32(block.chainid);
23 }
24 revert UnsupportedChain(block.chainid);
25}
26
27/**
28 * @dev Requires current chain to be the same as requested
29 * @param chainId Requested chain ID
30 */
31function requireCurrentChain(uint32 chainId) internal view {
32 uint32 currentChain = uint32(block.chainid);
33 if (currentChain != chainId) revert UnexpectedChain(currentChain, chainId);
34}

Recommendation:

We advise the code to assign currentChain to the result of the ChainidTools::chainid function, ensuring that the system utilizes the "canonical" chain ID per the EIP-7208 reference implementation.

Alleviation:

The local ChainidTools::chainid function is now utilized as advised, ensuring that the value limitation on the native block.chainid value is properly enforced within the ChainidTools::requireCurrentChain function.

CTS-02M: Incorrect Restriction of Chain ID

Description:

The ChainidTools::chainid function will incorrectly prevent a value of type(uint32).max from being considered valid even though it fits within the uint32 data type, preventing blockchains from using this chain ID value incorrectly.

Impact:

The ChainidTools::chainid function disallows a value of 0xFF..FF to be configured for the chain ID incorrectly, going against the reference implementation indicated in EIP-7208.

Example:

contracts/utils/ChainidTools.sol
20function chainid() internal view returns (uint32) {
21 if (block.chainid < type(uint32).max) {
22 return uint32(block.chainid);
23 }
24 revert UnsupportedChain(block.chainid);
25}

Recommendation:

We advise the comparator to be made inclusive, ensuring that a chain ID of type(uint32).max is properly supported.

Alleviation:

The restriction has been updated to be inclusive, addressing this exhibit in full.