Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gas optimization, Flexible code #427

Open
abhi3700 opened this issue Nov 5, 2024 · 0 comments
Open

Gas optimization, Flexible code #427

abhi3700 opened this issue Nov 5, 2024 · 0 comments

Comments

@abhi3700
Copy link

abhi3700 commented Nov 5, 2024

Background

In this line:

require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");

require(owner != address(0), "ZERO_ADDRESS");

although they are view functions, it's cheaper to simply return _ownerOf[id] & _balanceOf[owner]. Also, it's more developer-friendly or flexible I think.
Like in this test code:

/// address who owns the nft token id, can only burn
function testBurnWorks() public {
    vm.expectEmit(true, true, true, true);
    emit Burned(ALICE, 1);
    vm.prank(ALICE);
    myNFT.burn(1);
    // assertEq(myNFT.ownerOf(1), address(0));
}

I could call simply ownerOf function after burning NFT to verify. Otherwise, i have to use new_balance - old_balance.

Analysis

ownerOf

The current code costs 622 gas:

 ├─ [622] MyNFT::ownerOf(2) [staticcall]
    │   └─ ← [Return] ECRecover: [0x0000000000000000000000000000000000000001]

Modifying the code with:

- require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
+ return _ownerOf[id];

Function code (NEW):

function ownerOf(uint256 id) public view virtual returns (address) {
    return _ownerOf[id];
}

The new code would cost 588 gas:

├─ [588] MyNFT::ownerOf(2) [staticcall]
    │   └─ ← [Return] ECRecover: [0x0000000000000000000000000000000000000001]

balanceOf

Same reasoning in balanceOf function with new function code:

function balanceOf(address owner) public view virtual returns (uint256) {
    return _balanceOf[owner];
}
├─ [634] MyNFT::balanceOf(ECRecover: [0x0000000000000000000000000000000000000001]) [staticcall]
    │   └─ ← [Return] 4
├─ [582] MyNFT::balanceOf(ECRecover: [0x0000000000000000000000000000000000000001]) [staticcall]
    │   └─ ← [Return] 4
    └─ ← [Stop]

Summary

  • In ownerOf function, we can save by 52 gas per call.
  • In balanceOf function, we can save by 34 gas per call.
  • Also, the code becomes more developer friendly or flexible.
@abhi3700 abhi3700 closed this as completed Nov 5, 2024
@abhi3700 abhi3700 reopened this Nov 5, 2024
@abhi3700 abhi3700 changed the title Gas optimization Gas optimization, Flexible code Nov 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant