Skip to content

setArbitraryStorage

function setArbitraryStorage(address target) external;
function setArbitraryStorage(address target, bool overwrite) external;

Utility cheatcode to make the storage of the given address fully symbolic. If overwrite is specified, any storage slots that have been previously set are overwritten. Any subsequent SLOAD to target storage reads an arbitrary value which is memorized and returned if the same slot is loaded again. If the storage slot is explicitly written (before or after first load), then the written value is returned.

For a contract with following storage layout:

contract Counter {
address[] public owners;
function getOwner(uint256 pos) public view returns (address) {
return owners[pos];
}
function setOwner(uint256 pos, address owner) public {
owners[pos] = owner;
}
}

using setArbitraryStorage cheatcode ensures that arbitrary values are returned:

contract ArbitraryStorageTest is Test {
function testArbitraryStorage() public {
Counter counter = new Counter();
vm.setArbitraryStorage(address(counter));
// Next call would fail with array out of bounds without arbitrary storage
address owner = counter.getOwner(55);
// Subsequent calls to same slot returns same value
assertEq(counter.getOwner(55), owner);
// The new value is returned if explicitly written
counter.setOwner(55, address(111));
assertEq(counter.getOwner(55), address(111));
}
}