40,000 USDC
View results
Submission Details
Severity: gas

Gas Optimizations finding

[G-01] State variables only set in the constructor should be declared immutable

Impact

Avoids a Gusset (20000 gas)

Findings:

2023-07-escrow-main/src/Escrow.sol::26 => State private s_state;

[G-02] Amounts should be checked for 0 before calling a transfer

Impact

Checking non-zero transfer values can avoid an expensive external call and save gas.

While this is done in some places, it’s not consistently done in the solution.

Findings:

2023-07-escrow-main/src/Escrow.sol::98 => i_tokenContract.safeTransfer(i_seller, i_tokenContract.balanceOf(address(this)));
2023-07-escrow-main/src/Escrow.sol::120 => i_tokenContract.safeTransfer(i_buyer, buyerAward);
2023-07-escrow-main/src/Escrow.sol::123 => i_tokenContract.safeTransfer(i_arbiter, i_arbiterFee);
2023-07-escrow-main/src/Escrow.sol::127 => i_tokenContract.safeTransfer(i_seller, tokenBalance);

[G-03] abi.encode() is less efficient than abi.encodePacked()

Findings:

2023-07-escrow-main/src/EscrowFactory.sol::77 => byteCode, abi.encode(price, tokenContract, buyer, seller, arbiter, arbiterFee)

[G-04] Setting the constructor to payable

Impact

You can cut out 10 opcodes in the creation-time EVM bytecode if you declare a constructor payable. Making the constructor payable eliminates the need for an initial check of msg.value == 0 and saves 13 gas on deployment with no security risks.

Findings:

2023-07-escrow-main\src\Escrow.sol#L32-L39:
constructor(
uint256 price,
IERC20 tokenContract,
address buyer,
address seller,
address arbiter,
uint256 arbiterFee
) {

Support

FAQs

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