Open code423n4 opened 2 years ago
I think there's merits to the optimization
That said:
STATICCALL
is 100 gas
As for the difference in gas cost I believe it's mostly due to how many cold SLOAD the current version would do vs the one you propose. The issue with the proposed solution is that we're doing a division early, meaning we're loosing a lot of precision, this can be fixed by adding a constant multiplier.
I think the finding is valid
Avoid calling staticcall instruction and power calculation every time someone buys tokens (save 5000 gas)
Every time a users calls the function buy() it will execute a
The function is:
function getAmountOut(uint256 _tokenInAmount) public view returns (uint256 tokenOutAmount_) { tokenOutAmount_ = (_tokenInAmount * 10**tokenOut.decimals()) / tokenOutPrice; }
The
tokenOut.decimals()
is a contract call, more specifically a staticcall OPCODE that will cost you 700 gas according to https://eips.ethereum.org/EIPS/eip-1380. Apart from that power calculation is also expensive. I have code a PoC contract and mi results is that you would be saving 5000 gas if you use a precomputed variableThe Poc
I have coded these two simple contracts in a single file that you can test easily in remix
Simulation in remix shows that expensivePower is 5000 gas more expensive that cheapPower
Proposed solution
I would suggest you to use a precomputed variable stored at the time you create your constract because buy() is a function that is highly used and you would be saving a few dollars per transaction
exchangeRate = 10**tokenOut.decimals() / tokenOutPrice
or at least
otherConstant = 10**tokenOut.decimals()
Just to mention that if you use the first option you need to set again exchangeRate when you setTokenOutPrice al L303.