-
Notifications
You must be signed in to change notification settings - Fork 697
Open
Description
Background
In this line:
Line 36 in c93f771
| require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); |
Line 40 in c93f771
| 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
ownerOffunction, we can save by52 gasper call. - In
balanceOffunction, we can save by34 gasper call. - Also, the code becomes more developer friendly or flexible.
Metadata
Metadata
Assignees
Labels
No labels