-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathFraxTest.sol
More file actions
130 lines (114 loc) · 5.66 KB
/
FraxTest.sol
File metadata and controls
130 lines (114 loc) · 5.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-License-Identifier: ISC
pragma solidity >=0.8.0;
import { console2 as console, StdAssertions, StdChains, StdCheats, stdError, StdInvariant, stdJson, stdMath, StdStorage, stdStorage, StdUtils, Vm, StdStyle, TestBase, DSTest, Test } from "forge-std/Test.sol";
import { VmHelper } from "./VmHelper.sol";
import { Strings } from "./StringsHelper.sol";
abstract contract FraxTest is VmHelper, Test {
/// @notice Differential State Storage
uint256[] internal snapShotIds;
function()[] internal setupFunctions;
/// @notice EIP-1967 Slots
bytes32 internal IMPLEMENTATION_SLOT = bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1);
bytes32 internal ADMIN_SLOT = bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1);
// ========================================================================
// ~~~~~~~~~~~~~~~~~~ Different State Testing Helpers ~~~~~~~~~~~~~~~~~~~~~
// ========================================================================
modifier useMultipleSetupFunctions() {
if (snapShotIds.length == 0) _;
for (uint256 i = 0; i < snapShotIds.length; i++) {
uint256 _originalSnapshotId = vm.snapshot();
if (!vm.revertTo(snapShotIds[i])) {
revert VmDidNotRevert(snapShotIds[i]);
}
_;
vm.clearMockedCalls();
vm.revertTo(_originalSnapshotId);
}
}
function addSetupFunctions(function()[] memory _setupFunctions) internal {
for (uint256 i = 0; i < _setupFunctions.length; i++) {
_setupFunctions[i]();
snapShotIds.push(vm.snapshot());
vm.clearMockedCalls();
}
}
// ========================================================================
// ~~~~~~~~~~~~~~~~~~~~~~~ EIP-1967 Proxy Helpers ~~~~~~~~~~~~~~~~~~~~~~~~~
// ========================================================================
/// @notice Helper function to efficiently return the address type located at the implementation
/// and admin slot on an EIP-1967 Proxy
/// @param _proxyToCheck The proxy to fetch the implementation and admin of
/// @return implementation The Implmentation of the `_proxyToCheck`
/// @return admin The Admin of the `_proxyToCheck`
function get1967ProxyImplAndAdmin(
address _proxyToCheck
) internal view returns (address implementation, address admin) {
implementation = address(uint160(uint(vm.load(_proxyToCheck, IMPLEMENTATION_SLOT))));
admin = address(uint160(uint(vm.load(_proxyToCheck, ADMIN_SLOT))));
}
/// @notice Variant of the above function but the returns will be logged to the console
/// @param _proxyToCheck The proxy to fetch the implementation and admin of
/// @return implementation The Implmentation of the `_proxyToCheck`
/// @return admin The Admin of the `_proxyToCheck`
function get1967ProxyImplAndAdminWithLog(
address _proxyToCheck
) internal view returns (address implementation, address admin) {
(implementation, admin) = get1967ProxyImplAndAdmin(_proxyToCheck);
console.log(" get1967ProxyImplAndAdminWithLog: Implementation - ", implementation);
console.log(" get1967ProxyImplAndAdminWithLog: ProxyAdmin - ", admin);
}
// ========================================================================
// ~~~~~~~~~~~~~~~~~~~~~~~ Storage Slot Helpers ~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ========================================================================
/// @notice Helper function to dump the storage slots of a contract to the console
/// @param target The target contract whose state we wish to view
/// @param slotsToDump The # of lower storage slots we want to log
function dumpStorageLayout(address target, uint256 slotsToDump) internal view {
console.log("===================================");
console.log("Storage dump for: ", target);
console.log("===================================");
for (uint i; i <= slotsToDump; i++) {
bytes32 slot = vm.load(target, bytes32(uint256(i)));
string memory exp = Strings.toHexString(uint256(slot), 32);
console.log("slot", i, ":", exp);
}
}
/// @notice Helper function for unpacking low level storage slots
/// @param dataToUnpack The bytes32|uint256 of the slot to unpack
/// @param offset The bits to remove st. the target bits are LSB
/// @param lenOfTarget The length target result in bits
/// @return result The target bits expressed as a uint256
function unpackBits(
uint256 dataToUnpack,
uint256 offset,
uint256 lenOfTarget
) internal pure returns (uint256 result) {
uint256 mask = (1 << lenOfTarget) - 1;
result = (dataToUnpack >> offset) & mask;
}
function unpackBits(
bytes32 dataToUnpack,
uint256 offset,
uint256 lenOfTarget
) internal pure returns (uint256 result) {
uint256 mask = (1 << lenOfTarget) - 1;
result = (uint256(dataToUnpack) >> offset) & mask;
}
function unpackBitsAndLogUint(
uint256 dataToUnpack,
uint256 offset,
uint256 lenOfTarget
) internal pure returns (uint256 result) {
result = unpackBits(dataToUnpack, offset, lenOfTarget);
console.log(result);
}
function unpackBitsAndLogUint(
bytes32 dataToUnpack,
uint256 offset,
uint256 lenOfTarget
) internal pure returns (uint256 result) {
result = unpackBits(dataToUnpack, offset, lenOfTarget);
console.log(result);
}
error VmDidNotRevert(uint256 _snapshotId);
}