40,000 USDC
View results
Submission Details
Severity: gas

[G‑05] Input validation should be done in the beginning

All optimizations were benchmarked using the protocol's tests using the following config: solc version 0.8.18, optimizer on, 200 runs, viaIR = true. In most cases forge test --gas-report was used

Each optimization was submitted individually.

Gas Optimizations

Issue Instances Total Gas Saved
[G‑01] Consider using clones * -70% cheaper deployment gas
[G‑02] ReentrancyGuard can be safely removed 1 42725
[G‑03] computeEscrowAddress() can be internal instead of public 1 55863 + 193
[G‑04] Redundant zero address checks 2 237
[G‑05] Input validation should be done in the beginning 2 110649(in the revert case)
[G‑06] Emit after the transfer has been made in case it fails 2 1381(in the revert case)
[G‑07] The bytecode can be removed from the function params 1 27
[G‑08] Nested ifs are cheaper than && 1 19

[G‑05] Input validation should be done in the beginning

Input validations should be always done in the beginning because we want out tx to revert as early as possible so no operations were made before the REVERT opcode was hit and no gas was wasted on them.

When deploying a new escrow we are first computing an address, transferring tokens and only then during deployment we have input validations like zero address seller or arbiterFee < price check. These validations should be done in the beginning before any other operations are done so no gas is wasted in the revert case.

Gas Savings for testSellerZeroReverts() obtained via forge snapshot(the gas costs here are for the entire test but only the difference is important to us): 55330 gas in the revert case

Before 140272
After 84942

Gas Savings for testRevertIfFeeGreaterThanPrice() obtained via forge snapshot(the gas costs here are for the entire test but only the difference is important to us): 55319 gas in the revert case

MED
Before 141012
After 85693

There are 2 instances of this issue:

https://github.com/Cyfrin/2023-07-escrow/blob/65a60eb0773803fa0be4ba72defaec7d8567bccc/src/Escrow.sol#L42-L43

File: Escrow.sol
42: if (seller == address(0)) revert Escrow__SellerZeroAddress();
43: if (arbiterFee >= price) revert Escrow__FeeExceedsPrice(price, arbiterFee);

These checks can be done in newEscrow() before any other operations are done. In case that the seller is a zero address or arbiterFee >= price then placing this in the beginning would save a lot of gas.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.