3

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?

Shane Fontaine
  • 18,036
  • 20
  • 54
  • 82
CodeSandwich
  • 183
  • 1
  • 4

1 Answers1

6

EIP-1884 (included in the Istanbul hard fork) changed the cost of an SLOAD from 200 to 800, which explains why you are seeing exactly 600 more than expected.

It looks like the yellow paper has not been updated to reflect this change.

Edit: I have opened a PR on the yellow paper repository to resolve this issue.

Shane Fontaine
  • 18,036
  • 20
  • 54
  • 82