|
| 1 | +// SPDX-License-Identifier: LGPL-3.0-or-later |
| 2 | + |
| 3 | +pragma solidity >=0.7.6 <0.9.0; |
| 4 | +pragma abicoder v2; |
| 5 | + |
| 6 | +import {Test, Vm} from "forge-std/Test.sol"; |
| 7 | +import {StorageAccessibleWrapper, ExternalStorageReader} from "src/contracts/test/vendor/StorageAccessibleWrapper.sol"; |
| 8 | +import {ViewStorageAccessible} from "src/contracts/mixins/StorageAccessible.sol"; |
| 9 | + |
| 10 | +contract StorageAccessibleTest is Test { |
| 11 | + StorageAccessibleWrapper instance; |
| 12 | + ExternalStorageReader reader; |
| 13 | + |
| 14 | + function setUp() public { |
| 15 | + instance = new StorageAccessibleWrapper(); |
| 16 | + reader = new ExternalStorageReader(); |
| 17 | + } |
| 18 | + |
| 19 | + function test_can_invoke_function_in_the_context_of_previously_deployed_contract() public { |
| 20 | + instance.setFoo(42); |
| 21 | + bytes memory data = instance.simulateDelegatecall(address(reader), abi.encodeWithSignature("getFoo()")); |
| 22 | + uint256 result = abi.decode(data, (uint256)); |
| 23 | + assertEq(result, 42); |
| 24 | + } |
| 25 | + |
| 26 | + function test_can_simulateDelegatecall_a_function_with_side_effects() public { |
| 27 | + instance.setFoo(42); |
| 28 | + vm.startStateDiffRecording(); |
| 29 | + |
| 30 | + bytes memory data = |
| 31 | + instance.simulateDelegatecall(address(reader), abi.encodeWithSignature("setAndGetFoo(uint256)", 69)); |
| 32 | + uint256 result = abi.decode(data, (uint256)); |
| 33 | + assertEq(result, 69); |
| 34 | + |
| 35 | + // Make sure foo is not actually changed |
| 36 | + uint256 foo = reader.invokeStaticDelegatecall( |
| 37 | + ViewStorageAccessible(address(instance)), abi.encodeWithSignature("getFoo()") |
| 38 | + ); |
| 39 | + assertEq(foo, 42); |
| 40 | + |
| 41 | + // Using state changes to make sure foo isn't changed |
| 42 | + Vm.AccountAccess[] memory records = vm.stopAndReturnStateDiff(); |
| 43 | + for (uint256 i; i < records.length; i++) { |
| 44 | + uint256 storageCalls = records[i].storageAccesses.length; |
| 45 | + for (uint256 j; j < storageCalls; j++) { |
| 46 | + if (records[i].storageAccesses[j].isWrite) { |
| 47 | + assertEq(records[i].storageAccesses[j].reverted, true); |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + function test_can_simulateDelegatecall_a_function_that_reverts() public { |
| 54 | + vm.expectRevert(); |
| 55 | + instance.simulateDelegatecall(address(reader), abi.encodeWithSignature("doRevert()")); |
| 56 | + } |
| 57 | + |
| 58 | + function test_allows_detection_of_reverts_when_invoked_from_other_smart_contract() public { |
| 59 | + vm.expectRevert(); |
| 60 | + reader.invokeDoRevertViaStorageAccessible(instance); |
| 61 | + } |
| 62 | +} |
0 commit comments