40,000 USDC
View results
Submission Details
Severity: gas

Functions that require access control are cheaper when using payable

Summary

When adding 'payable' to a function that has access control, you will save approximately 20 gas per function call.

Vulnerability Details

A function with access control that is marked as payable will be more cost-effective for legitimate callers, as the compiler removes checks for msg.value, resulting in a savings of approximately 17 gas per function call.

The following three functions can be marked as 'payable' as well as the same functions in IEscrow.sol:

File: 2023-07-escrow/src/Escrow.sol
094: function confirmReceipt() external onlyBuyer inState(State.Created) {
102: function initiateDispute() external onlyBuyerOrSeller inState(State.Created) {
109: function resolveDispute(uint256 buyerAward) external onlyArbiter nonReentrant inState(State.Disputed) {

Function gas savings:

Function Name min avg median max # calls
confirmReceipt 316 24518 40322 40322 11
confirmReceiptOptimized 301 24505 40310 40310 11
initiateDispute 316 16855 23603 23603 10
initiateDisputeOptimized 301 16840 23588 23588 10
resolveDispute 383 27017 22342 62460 8
resolveDisputeOptimized 365 27001 22326 62446 8

Deployment gas savings:

Contract Name Deployment Cost Deployment Size
Escrow 591900 3666
EscrowOptimized 588700 3650
Contract Name Deployment Cost Deployment Size
EscrowFactory 1720616 8622
EscrowFactoryOptimized 1714209 8590

Impact

Gas Optimization.

Tools Used

Manual review.

Recommendations

File: 2023-07-escrow/src/Escrow.sol
- function confirmReceipt() external onlyBuyer inState(State.Created) {
+ function confirmReceipt() external payable onlyBuyer inState(State.Created) {
- function initiateDispute() external onlyBuyerOrSeller inState(State.Created) {
+ function initiateDispute() external payable onlyBuyerOrSeller inState(State.Created) {
- function resolveDispute(uint256 buyerAward) external onlyArbiter nonReentrant inState(State.Disputed) {
+ function resolveDispute(uint256 buyerAward) external payable onlyArbiter nonReentrant inState(State.Disputed) {

Support

FAQs

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