🎓 A1Learner
🔍
0 of 48 lessons completed

Solidity Caching Storage Reads

Caching a storage read is copying a state value into a local variable once and working with the copy. The copy is cheap to reuse while the stored value costs more on every read.

A cached value doubles the same as a direct read

Doubling the cached copy gives the same answer as doubling the stored value. The two functions must agree.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract CacheValue {
    uint256 public total;

    function setTotal(uint256 t) public {
        total = t;
    }

    function doubleDirect() public view returns (uint256) {
        return total * 2;
    }

    function doubleCached() public view returns (uint256) {
        uint256 cached = total;
        return cached * 2;
    }
}

One cached price serves a whole calculation

The function copies the price once and uses the copy for both results. No second storage read is needed.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract CachedPrice {
    uint256 public price;

    function setPrice(uint256 p) public {
        price = p;
    }

    function priceAndDouble() public view returns (uint256 p, uint256 doubled) {
        uint256 cached = price;
        p = cached;
        doubled = cached * 2;
    }
}

A cached mapping value can be reused

A balance read from a mapping can be cached like any other value. The cached copy is then reused for the doubling.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract CachedBalance {
    mapping(address => uint256) public balances;

    function setBalance(uint256 v) public {
        balances[msg.sender] = v;
    }

    function doubled() public view returns (uint256) {
        uint256 cached = balances[msg.sender];
        return cached * 2;
    }
}

Example

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract RewardPayout {
    uint256 public balance;
    uint256 public rate;

    function set(uint256 b, uint256 r) public {
        balance = b;
        rate = r;
    }

    function payout() public view returns (uint256 fee, uint256 net) {
        uint256 cachedBalance = balance;
        uint256 cachedRate = rate;
        fee = cachedBalance * cachedRate / 100;
        net = cachedBalance - fee;
    }
}

Key points

  • Cache: a local copy of a state value made once.
  • Storage read: each read of state costs more than reading a local variable.
  • Reuse: work with the cached copy instead of reading state again.
  • Freshness: a cache holds the value from the moment it was copied.
  • Use caching to read a value once when a function needs it several times.

In this example, a payout function copies the balance and the rate into local variables once. The fee and the net payout are both worked out from those copies.

Note

a function that changes a cached value must write the result back to storage.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Remix IDE

Exercise

What does caching a storage read mean?