arnaucube
arnaucube/poseidon-solidity-examplePublic Self-hosted repository
poseidon-solidity-example/lib/forge-std/test/StdStorage.t.sol
lib/forge-std/test/StdStorage.t.solRaw
  1// SPDX-License-Identifier: MIT
  2pragma solidity >=0.7.0 <0.9.0;
  3
  4import "../src/StdStorage.sol";
  5import "../src/Test.sol";
  6
  7contract StdStorageTest is Test {
  8    using stdStorage for StdStorage;
  9
 10    StorageTest internal test;
 11
 12    function setUp() public {
 13        test = new StorageTest();
 14    }
 15
 16    function testStorageHidden() public {
 17        assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find());
 18    }
 19
 20    function testStorageObvious() public {
 21        assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find());
 22    }
 23
 24    function testStorageCheckedWriteHidden() public {
 25        stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100);
 26        assertEq(uint256(test.hidden()), 100);
 27    }
 28
 29    function testStorageCheckedWriteObvious() public {
 30        stdstore.target(address(test)).sig(test.exists.selector).checked_write(100);
 31        assertEq(test.exists(), 100);
 32    }
 33
 34    function testStorageMapStructA() public {
 35        uint256 slot =
 36            stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find();
 37        assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot);
 38    }
 39
 40    function testStorageMapStructB() public {
 41        uint256 slot =
 42            stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find();
 43        assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot);
 44    }
 45
 46    function testStorageDeepMap() public {
 47        uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(
 48            address(this)
 49        ).find();
 50        assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot);
 51    }
 52
 53    function testStorageCheckedWriteDeepMap() public {
 54        stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this))
 55            .checked_write(100);
 56        assertEq(100, test.deep_map(address(this), address(this)));
 57    }
 58
 59    function testStorageDeepMapStructA() public {
 60        uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this))
 61            .with_key(address(this)).depth(0).find();
 62        assertEq(
 63            bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0),
 64            bytes32(slot)
 65        );
 66    }
 67
 68    function testStorageDeepMapStructB() public {
 69        uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this))
 70            .with_key(address(this)).depth(1).find();
 71        assertEq(
 72            bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1),
 73            bytes32(slot)
 74        );
 75    }
 76
 77    function testStorageCheckedWriteDeepMapStructA() public {
 78        stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key(
 79            address(this)
 80        ).depth(0).checked_write(100);
 81        (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this));
 82        assertEq(100, a);
 83        assertEq(0, b);
 84    }
 85
 86    function testStorageCheckedWriteDeepMapStructB() public {
 87        stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key(
 88            address(this)
 89        ).depth(1).checked_write(100);
 90        (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this));
 91        assertEq(0, a);
 92        assertEq(100, b);
 93    }
 94
 95    function testStorageCheckedWriteMapStructA() public {
 96        stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100);
 97        (uint256 a, uint256 b) = test.map_struct(address(this));
 98        assertEq(a, 100);
 99        assertEq(b, 0);
100    }
101
102    function testStorageCheckedWriteMapStructB() public {
103        stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100);
104        (uint256 a, uint256 b) = test.map_struct(address(this));
105        assertEq(a, 0);
106        assertEq(b, 100);
107    }
108
109    function testStorageStructA() public {
110        uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find();
111        assertEq(uint256(7), slot);
112    }
113
114    function testStorageStructB() public {
115        uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find();
116        assertEq(uint256(7) + 1, slot);
117    }
118
119    function testStorageCheckedWriteStructA() public {
120        stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100);
121        (uint256 a, uint256 b) = test.basic();
122        assertEq(a, 100);
123        assertEq(b, 1337);
124    }
125
126    function testStorageCheckedWriteStructB() public {
127        stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100);
128        (uint256 a, uint256 b) = test.basic();
129        assertEq(a, 1337);
130        assertEq(b, 100);
131    }
132
133    function testStorageMapAddrFound() public {
134        uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find();
135        assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot);
136    }
137
138    function testStorageMapUintFound() public {
139        uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find();
140        assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot);
141    }
142
143    function testStorageCheckedWriteMapUint() public {
144        stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100);
145        assertEq(100, test.map_uint(100));
146    }
147
148    function testStorageCheckedWriteMapAddr() public {
149        stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100);
150        assertEq(100, test.map_addr(address(this)));
151    }
152
153    function testStorageCheckedWriteMapBool() public {
154        stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true);
155        assertTrue(test.map_bool(address(this)));
156    }
157
158    function testFailStorageCheckedWriteMapPacked() public {
159        // expect PackedSlot error but not external call so cant expectRevert
160        stdstore.target(address(test)).sig(test.read_struct_lower.selector).with_key(address(uint160(1337)))
161            .checked_write(100);
162    }
163
164    function testStorageCheckedWriteMapPackedSuccess() public {
165        uint256 full = test.map_packed(address(1337));
166        // keep upper 128, set lower 128 to 1337
167        full = (full & (uint256((1 << 128) - 1) << 128)) | 1337;
168        stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write(
169            full
170        );
171        assertEq(1337, test.read_struct_lower(address(1337)));
172    }
173
174    function testFailStorageConst() public {
175        // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()"))));
176        stdstore.target(address(test)).sig("const()").find();
177    }
178
179    function testFailStorageNativePack() public {
180        stdstore.target(address(test)).sig(test.tA.selector).find();
181        stdstore.target(address(test)).sig(test.tB.selector).find();
182
183        // these both would fail
184        stdstore.target(address(test)).sig(test.tC.selector).find();
185        stdstore.target(address(test)).sig(test.tD.selector).find();
186    }
187
188    function testStorageReadBytes32() public {
189        bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32();
190        assertEq(val, hex"1337");
191    }
192
193    function testStorageReadBool_False() public {
194        bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool();
195        assertEq(val, false);
196    }
197
198    function testStorageReadBool_True() public {
199        bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool();
200        assertEq(val, true);
201    }
202
203    function testStorageReadBool_Revert() public {
204        vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.");
205        this.readNonBoolValue();
206    }
207
208    function readNonBoolValue() public {
209        stdstore.target(address(test)).sig(test.tE.selector).read_bool();
210    }
211
212    function testStorageReadAddress() public {
213        address val = stdstore.target(address(test)).sig(test.tF.selector).read_address();
214        assertEq(val, address(1337));
215    }
216
217    function testStorageReadUint() public {
218        uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint();
219        assertEq(val, 1);
220    }
221
222    function testStorageReadInt() public {
223        int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int();
224        assertEq(val, type(int256).min);
225    }
226}
227
228contract StorageTest {
229    uint256 public exists = 1;
230    mapping(address => uint256) public map_addr;
231    mapping(uint256 => uint256) public map_uint;
232    mapping(address => uint256) public map_packed;
233    mapping(address => UnpackedStruct) public map_struct;
234    mapping(address => mapping(address => uint256)) public deep_map;
235    mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct;
236    UnpackedStruct public basic;
237
238    uint248 public tA;
239    bool public tB;
240
241    bool public tC = false;
242    uint248 public tD = 1;
243
244    struct UnpackedStruct {
245        uint256 a;
246        uint256 b;
247    }
248
249    mapping(address => bool) public map_bool;
250
251    bytes32 public tE = hex"1337";
252    address public tF = address(1337);
253    int256 public tG = type(int256).min;
254    bool public tH = true;
255
256    constructor() {
257        basic = UnpackedStruct({a: 1337, b: 1337});
258
259        uint256 two = (1 << 128) | 1;
260        map_packed[msg.sender] = two;
261        map_packed[address(uint160(1337))] = 1 << 128;
262    }
263
264    function read_struct_upper(address who) public view returns (uint256) {
265        return map_packed[who] >> 128;
266    }
267
268    function read_struct_lower(address who) public view returns (uint256) {
269        return map_packed[who] & ((1 << 128) - 1);
270    }
271
272    function hidden() public view returns (bytes32 t) {
273        bytes32 slot = keccak256("my.random.var");
274        /// @solidity memory-safe-assembly
275        assembly {
276            t := sload(slot)
277        }
278    }
279
280    function const() public pure returns (bytes32 t) {
281        t = bytes32(hex"1337");
282    }
283}