Summary
Currently, some of the functions in ScrvusdVerifierV2.sol
and ScrvusdVerifierV1.sol
use require
statements for validation checks. Each require
statement consumes additional gas due to the storage of revert reasons in memory. Replacing require
statements with if
conditions followed by revert
with custom errors reduces gas usage by minimizing string memory allocation.
Vulnerability Details
For example:
function verifyPeriodByBlockHash(
bytes memory _block_header_rlp,
bytes memory _proof_rlp
) external returns (bool) {
Verifier.BlockHeader memory block_header = Verifier.parseBlockHeader(_block_header_rlp);
require(block_header.hash != bytes32(0), "Invalid blockhash");
require(
block_header.hash == IBlockHashOracle(ScrvusdVerifierV1.BLOCK_HASH_ORACLE).get_block_hash(block_header.number),
"Blockhash mismatch"
);
uint256 period = _extractPeriodFromProof(block_header.stateRootHash, _proof_rlp);
return IScrvusdOracleV2(SCRVUSD_ORACLE).update_profit_max_unlock_time(period, block_header.number);
}
Impact
Using custom errors than require
statement is more gas efficient and without requiring additional memory allocation.
Tools Used
Recommendations
Use of custom errors:
error InvalidBlockHash();
error BlockhashMismatch();
function verifyPeriodByBlockHash(
bytes memory _block_header_rlp,
bytes memory _proof_rlp
) external returns (bool) {
Verifier.BlockHeader memory block_header = Verifier.parseBlockHeader(_block_header_rlp);
if (block_header.hash == bytes32(0)) {
revert InvalidBlockHash();
}
if (block_header.hash != IBlockHashOracle(ScrvusdVerifierV1.BLOCK_HASH_ORACLE).get_block_hash(block_header.number)) {
revert BlockhashMismatch();
}
uint256 period = _extractPeriodFromProof(block_header.stateRootHash, _proof_rlp);
return IScrvusdOracleV2(SCRVUSD_ORACLE).update_profit_max_unlock_time(period, block_header.number);
}