0

I want to execute a function like the following:

 function calculateUserVotingPower(address _user) public view returns (uint256 userVotingPower) { IVoteEscrow.NFTInfo[] memory nfts = voteEscrow.getUserAllNFTs(_user); uint256 length = nfts.length; if (length > MAX_NFTS_CONSIDERED) revert TooManyNFTs(); for (uint256 i = 0; i < length; ) { if (nfts[i].locked_end > block.timestamp) { userVotingPower += nfts[i].balanceOf; } unchecked { ++i; } } } 

So, in such functions, does it save gas to cache block.timestamp variable and use it for comparisons? for eg.

 function calculateUserVotingPower(address _user) public view returns (uint256 userVotingPower) { IVoteEscrow.NFTInfo[] memory nfts = voteEscrow.getUserAllNFTs(_user); uint256 length = nfts.length; if (length > MAX_NFTS_CONSIDERED) revert TooManyNFTs(); uint256 timestamp = block.timestamp; for (uint256 i = 0; i < length; ) { if (nfts[i].locked_end > timestamp) { userVotingPower += nfts[i].balanceOf; } unchecked { ++i; } } 

}

Other than loops, if block.timestamp, msg.sender or address(this) if used multiple times, should they be cached in memory and then used to save gas?

1 Answer 1

0

I ran some tests, and the difference is around 1 gas each loop. So just pick what looks best for you.

2
  • 1
    In case of msg.sender, reading from memory consumes 3 gas (mload opcode) and getting the address of the sender consumes 2 gas (caller opcode). Essentially, saving the variable in memory and reading it afterwards is more expensive than using msg.sender every time. Commented Dec 19, 2024 at 11:35
  • In his case he's not using mload but reading from the stack. So it's all about stack manipulation (DUP, POP, etc..) Commented Dec 19, 2024 at 13:58

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.