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);
}