I've got a very simple contract. It narrows down and measures cost of loading a storage variable:
pragma solidity ^0.7.6;
contract Bench {
uint256 public data;
function increment() public {
uint256 gasUsed = gasleft();
uint256 dataLocal = data;
gasUsed -= gasleft();
dataLocal += gasUsed;
data = dataLocal;
}
}
It generates an unsurprising assembly:
(...)
GAS gasleft()
PUSH 0 uint256 dataLocal
SLOAD data
SWAP1 uint256 gasUsed = gasleft()
SWAP2 uint256 gasUsed = gasleft()
POP
GAS gasleft()
(...)
The measured gas usage according to the yellow paper should be 213:
PUSH - 3
SLOAD - 200
SWAP1 - 3
SWAP2 - 3
POP - 2
GAS - 2
A simple Remix test shows the measured gas:
function checkFailure() public {
Bench bench = new Bench();
bench.increment();
Assert.equal(bench.data(), 0, "GAS USED");
}
The printed result is 813, exactly 600 more than expected. Why? How to reduce that?