diff --git a/foundry.toml b/foundry.toml index 43a43494..ca70eb72 100644 --- a/foundry.toml +++ b/foundry.toml @@ -4,6 +4,10 @@ libs = ['lib'] ffi = true fuzz_runs = 1000 fs_permissions = [ + { access = "read", path = "./test/auth/mocks/AuthWrappers.huff" }, + { access = "read", path = "./test/auth/mocks/OwnedWrappers.huff" }, + { access = "read", path = "./test/auth/mocks/RolesAuthorityWrappers.huff" }, + { access = "read", path = "./test/data-structures/mocks/ArrayWrappers.huff" }, { access = "read", path = "./test/data-structures/mocks/HashmapWrappers.huff" }, diff --git a/lib/forge-std b/lib/forge-std index d26946ae..cb69e9c0 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit d26946aeef956d9d11238ce02c94b7a22ac23ca8 +Subproject commit cb69e9c07fbd002819c8c6c8db3caeab76b90d6b diff --git a/src/auth/Auth.huff b/src/auth/Auth.huff index a603b89a..8d4fae49 100644 --- a/src/auth/Auth.huff +++ b/src/auth/Auth.huff @@ -24,42 +24,42 @@ #define constant AUTHORITY = FREE_STORAGE_POINTER() /// @notice Constructor -#define macro CONSTRUCTOR() = takes (0) returns (0) { +#define macro AUTH_CONSTRUCTOR() = takes (0) returns (0) { // Copy the owner into memory - 0x20 // [size] - byte size to copy - 0x40 codesize sub // [offset, size] - offset in the code to copy from - 0x00 // [mem, offset, size] - offset in memory to copy to - codecopy // [] + 0x20 // [size] - byte size to copy + 0x40 codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] // Copy the authority into memory - 0x20 // [size] - byte size to copy - 0x20 codesize sub // [offset, size] - offset in the code to copy from - 0x20 // [mem, offset, size] - offset in memory to copy to - codecopy // [] + 0x20 // [size] - byte size to copy + 0x20 codesize sub // [offset, size] - offset in the code to copy from + 0x20 // [mem, offset, size] - offset in memory to copy to + codecopy // [] // Set the new owner - 0x00 mload // [owner] - dup1 // [owner, owner] - [OWNER] // [OWNER, owner, owner] - sstore // [owner] + 0x00 mload // [owner] + dup1 // [owner, owner] + [OWNER] // [OWNER, owner, owner] + sstore // [owner] // Set the new Authority - 0x20 mload // [authority, owner] - dup1 // [authority, authority, owner] - [AUTHORITY] // [AUTHORITY, authority, authority, owner] - sstore // [authority, owner] + 0x20 mload // [authority, owner] + dup1 // [authority, authority, owner] + [AUTHORITY] // [AUTHORITY, authority, authority, owner] + sstore // [authority, owner] // Emit the authority updated event - caller // [from, authority, owner] - [AUTHORITY_UPDATED_SIG] // [sig, from, authority, owner] - 0x00 0x00 // [0, 0, sig, from, authority, owner] - log3 // [owner] + caller // [from, authority, owner] + __EVENT_HASH(AuthorityUpdated) // [sig, from, authority, owner] + 0x00 0x00 // [0, 0, sig, from, authority, owner] + log3 // [owner] // Emit the owner updated event - caller // [from, owner] - [OWNER_UPDATED_SIG] // [sig, from, owner] - 0x00 0x00 // [0, 0, sig, from, owner] - log3 // [] + caller // [from, owner] + [OWNER_UPDATED_SIG] // [sig, from, owner] + 0x00 0x00 // [0, 0, sig, from, owner] + log3 // [] } /// @notice Modifier that enforces caller authorization @@ -84,8 +84,8 @@ iszero post jumpi // [authority, user, sig] // WARN: If an account has no code, the call will unintendedly return successfully - dup1 extcodesize // [code, authority, user, sig] - iszero post jumpi // [authority, user, sig] + dup1 extcodesize // [code, authority, user, sig] + iszero post jumpi // [authority, user, sig] // Store the auth.canCall arguments in memory at offset 0 // function canCall(address user, address target, bytes4 functionSig) external view returns (bool) @@ -126,15 +126,15 @@ REQUIRES_AUTH() // Set the new authority - 0x04 calldataload // [newAuthority] - dup1 // [newAuthority, newAuthority] - [AUTHORITY] sstore // [newAuthority] + 0x04 calldataload // [newAuthority] + dup1 // [newAuthority, newAuthority] + [AUTHORITY] sstore // [newAuthority] // Emit the authority updated event - caller // [from, newAuthority] - [AUTHORITY_UPDATED_SIG] // [sig, from, newAuthority] - 0x00 0x00 // [0, 32, sig, from, newAuthority] - log3 // [] + caller // [from, newAuthority] + __EVENT_HASH(AuthorityUpdated) // [sig, from, newAuthority] + 0x00 0x00 // [0, 32, sig, from, newAuthority] + log3 // [] stop } @@ -176,17 +176,16 @@ } /// @notice Main Function Dispatcher -#define macro MAIN() = takes(0) returns (0) { - // Identify which function is being called using the 4 byte function signature - pc calldataload 0xE0 shr +#define macro AUTH_MAIN() = takes (1) returns (1) { + // Input Stack: [function_selector] dup1 __FUNC_SIG(setOwner) eq set_owner jumpi dup1 __FUNC_SIG(setAuthority) eq set_authority jumpi dup1 __FUNC_SIG(owner) eq owner jumpi dup1 __FUNC_SIG(authority) eq authority jumpi - // Revert if no signatures match - 0x00 0x00 revert + // Bubble up to parent if no function selector matches + no_match jump set_owner: SET_OWNER() @@ -196,4 +195,6 @@ OWNER() authority: AUTHORITY() + + no_match: } diff --git a/src/auth/Owned.huff b/src/auth/Owned.huff index 9bf1be42..f45b298b 100644 --- a/src/auth/Owned.huff +++ b/src/auth/Owned.huff @@ -11,14 +11,11 @@ // Events #define event OwnerUpdated(address indexed user, address indexed newOwner) -// Event Signatures -#define constant OWNER_UPDATED_SIG = 0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76 - // Storage Slots #define constant OWNER = FREE_STORAGE_POINTER() // CONSTRUCTOR -#define macro CONSTRUCTOR() = takes (0) returns (0) { +#define macro OWNED_CONSTRUCTOR() = takes (0) returns (0) { // Copy the owner into memory 0x20 // [size] - byte size to copy 0x20 codesize sub // [offset, size] - offset in the code to copy from @@ -33,13 +30,13 @@ // Emit the owner updated event caller // [from, owner] - [OWNER_UPDATED_SIG] // [sig, from, owner] + __EVENT_HASH(OwnerUpdated) // [sig, from, owner] 0x00 0x00 // [0, 0, sig, from, owner] log3 // [] } /// @notice Only Owner Modifier -#define macro IS_OWNER() = takes(0) returns(0) { +#define macro IS_OWNER() = takes (0) returns (0) { caller // [msg.sender] [OWNER] sload // [owner, msg.sender] eq authed jumpi // [authed] @@ -52,7 +49,7 @@ /// @notice Set the Owner /// @param {owner} [address] - The new owner -#define macro SET_OWNER() = takes(0) returns(0) { +#define macro SET_OWNER() = takes (0) returns (0) { // Check that the caller is authorized IS_OWNER() @@ -63,7 +60,7 @@ // Emit the owner updated event caller // [from, newOwner] - [OWNER_UPDATED_SIG] // [sig, from, newOwner] + __EVENT_HASH(OwnerUpdated) // [sig, from, newOwner] 0x00 0x00 // [0, 32, sig, from, newOwner] log3 // [] @@ -72,24 +69,26 @@ /// @notice Get the owner of the contract /// @return {owner} [address] - The owner of the contract -#define macro OWNER() = takes(0) returns (0) { +#define macro OWNER() = takes (0) returns (0) { [OWNER] sload // [owner] 0x00 mstore // [] 0x20 0x00 return } /// @notice Main Function Dispatcher -#define macro MAIN() = takes(0) returns(0) { - pc calldataload 0xE0 shr +#define macro OWNED_MAIN() = takes (1) returns (1) { + // Input Stack: [function_selector] dup1 __FUNC_SIG(setOwner) eq set_owner jumpi dup1 __FUNC_SIG(owner) eq owner jumpi - // Revert if no signatures match - 0x00 0x00 revert + // Bubble up to parent macro + no_match jump set_owner: SET_OWNER() owner: OWNER() + + no_match: } \ No newline at end of file diff --git a/src/auth/RolesAuthority.huff b/src/auth/RolesAuthority.huff index 9ff9fd2b..3974ae05 100644 --- a/src/auth/RolesAuthority.huff +++ b/src/auth/RolesAuthority.huff @@ -21,11 +21,6 @@ #define event PublicCapabilityUpdated(address indexed target, bytes4 indexed functionSig, bool enabled) #define event RoleCapabilityUpdated(uint8 indexed role, address indexed target, bytes4 indexed functionSig, bool enabled) -// Event Signatures -#define constant USER_ROLE_UPDATED_SIG = 0x4c9bdd0c8e073eb5eda2250b18d8e5121ff27b62064fbeeeed4869bb99bc5bf2 -#define constant PUBLIC_CAPABILITY_UPDATED_SIG = 0x950a343f5d10445e82a71036d3f4fb3016180a25805141932543b83e2078a93e -#define constant ROLE_CAPABILITY_UPDATED_SIG = 0xa52ea92e6e955aa8ac66420b86350f7139959adfcc7e6a14eee1bd116d09860e - // MAPPINGS #define constant USER_ROLES_LOCATION = FREE_STORAGE_POINTER() #define constant IS_CAPABILITY_PUBLIC_LOCATION = FREE_STORAGE_POINTER() @@ -117,18 +112,18 @@ REQUIRES_AUTH() // Set the capability to the passed in value - 0x44 calldataload // [value] - 0x24 calldataload // [sig, value] - 0x04 calldataload // [target, sig, value] - STORE_ELEMENT_FROM_KEYS(0x00) // [] + 0x44 calldataload // [value] + 0x24 calldataload // [sig, value] + 0x04 calldataload // [target, sig, value] + STORE_ELEMENT_FROM_KEYS(0x00) // [] // Emit the capability updated event - 0x44 calldataload // [value] - 0x24 calldataload // [func, value] - 0x04 calldataload // [target, func, value] - [PUBLIC_CAPABILITY_UPDATED_SIG] // [sig, target, func, value] - 0x00 0x00 // [0, 0, sig, target, func, value] - log3 // [] + 0x44 calldataload // [value] + 0x24 calldataload // [func, value] + 0x04 calldataload // [target, func, value] + __EVENT_HASH(PublicCapabilityUpdated) // [sig, target, func, value] + 0x00 0x00 // [0, 0, sig, target, func, value] + log3 // [] // End Execution stop @@ -145,25 +140,25 @@ REQUIRES_AUTH() // Check if enabled - 0x64 calldataload // [value] - enable jumpi // [] + 0x64 calldataload // [value] + enable jumpi // [] // Disable the capability disable: // Get the current roles with the capability - 0x44 calldataload // [sig] - 0x24 calldataload // [target, sig] - GET_ROLE_FOR_CAPABILITY() // [roles] + 0x44 calldataload // [sig] + 0x24 calldataload // [target, sig] + GET_ROLE_FOR_CAPABILITY() // [roles] // Shift 1 left the role - 0x01 0x04 calldataload shl // [role, roles] - not // [others, roles] - and // [updated] + 0x01 0x04 calldataload shl // [role, roles] + not // [others, roles] + and // [updated] // Store the new capability - 0x44 calldataload // [sig, updated] - 0x24 calldataload // [target, sig, updated] - STORE_ELEMENT_FROM_KEYS(0x00) // [] + 0x44 calldataload // [sig, updated] + 0x24 calldataload // [target, sig, updated] + STORE_ELEMENT_FROM_KEYS(0x00) // [] // Jump to the emit log label emit_log jump @@ -171,28 +166,28 @@ // Enable the capability enable: // Get the current roles with the capability - 0x44 calldataload // [sig] - 0x24 calldataload // [target, sig] - GET_ROLE_FOR_CAPABILITY() // [roles] + 0x44 calldataload // [sig] + 0x24 calldataload // [target, sig] + GET_ROLE_FOR_CAPABILITY() // [roles] // Shift 1 left the role - 0x01 0x04 calldataload shl // [role, roles] - or // [capabilies] + 0x01 0x04 calldataload shl // [role, roles] + or // [capabilies] // Store the new capability - 0x44 calldataload // [sig, capabilies] - 0x24 calldataload // [target, sig, capabilies] - STORE_ELEMENT_FROM_KEYS(0x00) // [] + 0x44 calldataload // [sig, capabilies] + 0x24 calldataload // [target, sig, capabilies] + STORE_ELEMENT_FROM_KEYS(0x00) // [] // Emit the capability updated event emit_log: - 0x64 calldataload // [enabled] - 0x44 calldataload // [func, enabled] - 0x24 calldataload // [target, func, enabled] - 0x04 calldataload // [role, target, func, enabled] - [ROLE_CAPABILITY_UPDATED_SIG] // [sig, role, target, func, enabled] - 0x00 0x00 // [0, 0, sig, role, target, func, enabled] - log4 // [] + 0x64 calldataload // [enabled] + 0x44 calldataload // [func, enabled] + 0x24 calldataload // [target, func, enabled] + 0x04 calldataload // [role, target, func, enabled] + __EVENT_HASH(RoleCapabilityUpdated) // [sig, role, target, func, enabled] + 0x00 0x00 // [0, 0, sig, role, target, func, enabled] + log4 // [] // End Execution stop @@ -251,7 +246,7 @@ 0x44 calldataload // [enabled] 0x24 calldataload // [role, enabled] 0x04 calldataload // [account, role, enabled] - [USER_ROLE_UPDATED_SIG] // [sig, account, role, enabled] + __EVENT_HASH(UserRoleUpdated) // [sig, account, role, enabled] 0x00 0x00 // [0, 0, sig, account, role, enabled] log3 // [] @@ -260,9 +255,8 @@ } /// @notice Main Function Dispatcher -#define macro MAIN() = takes(0) returns (0) { - // Identify which function is being called using the 4 byte function signature - pc calldataload 0xe0 shr +#define macro ROLES_AUTHORITY_MAIN() = takes (1) returns (1) { + // Input Stack: [function_selector] dup1 __FUNC_SIG(hasRole) eq has_role jumpi dup1 __FUNC_SIG(doesRoleHaveCapability) eq role_capability jumpi @@ -277,8 +271,8 @@ dup1 __FUNC_SIG(owner) eq owner jumpi dup1 __FUNC_SIG(authority) eq authority jumpi - // Revert if no signatures match - 0x00 0x00 revert + // Bubble up function selector to parent macro + no_match jump has_role: HAS_ROLE() @@ -301,6 +295,8 @@ OWNER() authority: AUTHORITY() + + no_match: } diff --git a/src/math/Trigonometry.huff b/src/math/Trigonometry.huff index df8484bf..3aecf40f 100644 --- a/src/math/Trigonometry.huff +++ b/src/math/Trigonometry.huff @@ -46,16 +46,14 @@ // BASIC TRIG // //////////////////////////////////////////////////////////////// -/** - * @notice Return the sine of a value, specified in radians scaled by 1e18 - * @dev This algorithm for converting sine only uses integer values, and it works by dividing the - * circle into 30 bit angles, i.e. there are 1,073,741,824 (2^30) angle units, instead of the - * standard 360 degrees (2pi radians). From there, we get an output in range -2,147,483,647 to - * 2,147,483,647, (which is the max value of an int32) which is then converted back to the standard - * range of -1 to 1, again scaled by 1e18 - * @param _angle Angle to convert - * @return Result scaled by 1e18 - */ +/// @notice Return the sine of a value, specified in radians scaled by 1e18 +/// @dev This algorithm for converting sine only uses integer values, and it works by dividing the +/// circle into 30 bit angles, i.e. there are 1,073,741,824 (2^30) angle units, instead of the +/// standard 360 degrees (2pi radians). From there, we get an output in range -2,147,483,647 to +/// 2,147,483,647, (which is the max value of an int32) which is then converted back to the standard +/// range of -1 to 1, again scaled by 1e18 +/// @param _angle Angle to convert +/// @return Result scaled by 1e18 #define macro SIN() = takes (1) returns (1) { // Input stack: [angle] @@ -174,14 +172,12 @@ // Return stack: [1e18 * sine / I32_MAX] } -/** - * @notice Return the cosine of a value, specified in radians scaled by 1e18 - * @dev This is identical to the sin() method, and just computes the value by delegating to the - * sin() method using the identity cos(x) = sin(x + pi/2) - * @dev Overflow when `angle + PI_OVER_TWO > type(uint256).max` is ok, results are still accurate - * @param _angle Angle to convert - * @return Result scaled by 1e18 - */ +/// @notice Return the cosine of a value, specified in radians scaled by 1e18 +/// @dev This is identical to the sin() method, and just computes the value by delegating to the +/// sin() method using the identity cos(x) = sin(x + pi/2) +/// @dev Overflow when `angle + PI_OVER_TWO > type(uint256).max` is ok, results are still accurate +/// @param _angle Angle to convert +/// @return Result scaled by 1e18 #define macro COS() = takes (1) returns (1) { // Input stack: [angle] diff --git a/src/proxies/ERC1967Upgrade.huff b/src/proxies/ERC1967Upgrade.huff index f59105f9..a4e21771 100644 --- a/src/proxies/ERC1967Upgrade.huff +++ b/src/proxies/ERC1967Upgrade.huff @@ -11,7 +11,7 @@ #define function implementation() view returns (address) -/// @notice Foreign implementation function +/// @notice Foreign implementation function #define function proxiableUUID() nonpayable returns (bytes32) // EIP 1967 Constants diff --git a/src/tokens/ERC20.huff b/src/tokens/ERC20.huff index c22d0a2e..827ef3f3 100644 --- a/src/tokens/ERC20.huff +++ b/src/tokens/ERC20.huff @@ -61,7 +61,7 @@ /// @notice Constructor /// @notice Sets the initial domain separator and chain ID -#define macro INNER_ERC20_CONSTRUCTOR() = takes (0) returns (0) { +#define macro ERC20_CONSTRUCTOR() = takes (0) returns (0) { // Copy the decimals into memory from the bytecode 0x20 // [size] - byte size to copy 0x20 codesize sub // [offset, size] - offset in the code to copy from @@ -549,7 +549,7 @@ // Function Dispatching -#define macro MAIN_ERC20() = takes (1) returns (1) { +#define macro ERC20_MAIN() = takes (1) returns (1) { // Identify which function is being called. // [func sig] @@ -569,7 +569,8 @@ dup1 __FUNC_SIG(transferFrom) eq transferFromJump jumpi dup1 __FUNC_SIG(approve) eq approveJump jumpi - cont jumpi + // Bubble up to the parent macro + no_match jumpi allowanceJump: ALLOWANCE() @@ -596,5 +597,5 @@ transferJump: TRANSFER() - cont: + no_match: } \ No newline at end of file diff --git a/src/tokens/ERC4626.huff b/src/tokens/ERC4626.huff index 618e57ae..4786d911 100644 --- a/src/tokens/ERC4626.huff +++ b/src/tokens/ERC4626.huff @@ -43,7 +43,7 @@ #define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff /// @notice Constructor -#define macro INNER_4626_CONSTRUCTOR() = takes (0) returns (0) { +#define macro ERC4626_CONSTRUCTOR() = takes (0) returns (0) { // Copy the asset address into memory and then the stack from the bytecode 0x20 // [size] - byte size to copy 0x20 codesize sub // [offset, size] - offset in the code to copy from @@ -686,7 +686,7 @@ // ------------------------------------------------------ /// @notice An internal function dispatcher -#define macro INNER_4626_MAIN() = takes (1) returns (1) { +#define macro ERC4626_MAIN() = takes (1) returns (1) { // Input stack: [func_selector] // Output stack: [func_selector] @@ -711,9 +711,10 @@ dup1 __FUNC_SIG(maxWithdraw) eq max_withdraw_jump jumpi // [func_selector] dup1 __FUNC_SIG(maxRedeem) eq max_redeem_jump jumpi // [func_selector] - MAIN_ERC20() // [func_selector] + ERC20_MAIN() // [func_selector] - cont jump + // Bubble up to the parent macro + no_match jump decimals_jump: ERC4626_DECIMALS() @@ -754,5 +755,5 @@ MAX_REDEEM() // Resume parent dispatching - cont: // [func_selector] + no_match: // [func_selector] } \ No newline at end of file diff --git a/src/utils/MerkleDistributor.huff b/src/utils/MerkleDistributor.huff index f6be9d52..dbb3abbe 100644 --- a/src/utils/MerkleDistributor.huff +++ b/src/utils/MerkleDistributor.huff @@ -184,7 +184,7 @@ /// @notice Constructor /// @param address The address of the token to distribute /// @param merkleRoot The merkle root of the merkle tree -#define macro INNER_MERKLE_CONSTRUCTOR() = takes (0) returns (0) { +#define macro MERKLE_DISTRIBUTOR_CONSTRUCTOR() = takes (0) returns (0) { // Copy the first argument into memory 0x20 // [size] - byte size to copy 0x40 codesize sub // [offset, size] - offset in the code to copy from @@ -211,14 +211,16 @@ /// @notice Function Dispatch /// @notice Takes the first 4 bytes of calldata (aka the function selector) and dispatches to the appropriate function /// @notice If non match, execution proceeds as the code is inlined -#define macro INNER_MERKLE_MAIN() = takes (1) returns (1) { +#define macro MERKLE_DISTRIBUTOR_MAIN() = takes (1) returns (1) { + // Input Stack: [function_selector] + dup1 __FUNC_SIG(getTokenAddress) eq getTokenAddress jumpi dup1 __FUNC_SIG(getMerkleRoot) eq getMerkleRoot jumpi dup1 __FUNC_SIG(isClaimed) eq isClaimed jumpi dup1 __FUNC_SIG(claim) eq claim jumpi // Jump to the end if non match - non_match jump + no_match jump getMerkleRoot: GET_MERKLE_ROOT() @@ -229,5 +231,5 @@ claim: CLAIM() - non_match: + no_match: } \ No newline at end of file diff --git a/src/utils/SafeTransferLib.huff b/src/utils/SafeTransferLib.huff index 043e68fe..98b876f5 100644 --- a/src/utils/SafeTransferLib.huff +++ b/src/utils/SafeTransferLib.huff @@ -60,14 +60,14 @@ __RIGHTPAD(0xa9059cbb) // [transfer_selector, to, amount, token] mstore // [to, amount, token] - + // TODO: If we designate a 96 byte scratch space for this macro, // no need to do these additions at runtime. 0x04 add // [mem_ptr + 0x04, to, amount, token] mstore // [amount, token] 0x24 add // [mem_ptr + 0x24, amount, token] - mstore - + mstore + // [mem_ptr, token] 0x44 dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] @@ -81,10 +81,10 @@ and // [success & (data == 0x01 | returndatasize == 0)] success jumpi // [] - + 0x90b8ec18 0x00 mstore 0x04 0x1c revert - + success: // Return stack: [] } @@ -94,14 +94,14 @@ __RIGHTPAD(0x095ea7b3) // [transfer_selector, to, amount, token] mstore // [to, amount, token] - + // TODO: If we designate a 96 byte scratch space for this macro, // no need to do these additions at runtime. 0x04 add // [mem_ptr + 0x04, to, amount, token] mstore // [amount, token] 0x24 add // [mem_ptr + 0x24, amount, token] - mstore - + mstore + // [mem_ptr, token] 0x44 dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] @@ -115,10 +115,10 @@ and // [success & (data == 0x01 | returndatasize == 0)] success jumpi // [] - + 0x3e3f8f73 0x00 mstore 0x04 0x1c revert - + success: // Return stack: [] } diff --git a/src/utils/TSOwnable.huff b/src/utils/TSOwnable.huff index ca67eb0b..893a266f 100644 --- a/src/utils/TSOwnable.huff +++ b/src/utils/TSOwnable.huff @@ -39,7 +39,7 @@ #define constant PENDING_OWNER_SLOT = FREE_STORAGE_POINTER() /// @notice Inner TSOwnable Constructor -#define macro CONSTRUCTOR_TSOWNABLE() = takes (0) returns (0) { +#define macro TSOWNABLE_CONSTRUCTOR() = takes (0) returns (0) { // Store msg.sender as owner caller [OWNER_SLOT] sstore // [] } @@ -135,7 +135,7 @@ } // Function Dispatching -#define macro MAIN_TSOWNABLE() = takes (1) returns (1) { +#define macro TSOWNABLE_MAIN() = takes (1) returns (1) { // Input stack: [sig] // Output stack: [sig] @@ -144,7 +144,8 @@ dup1 __FUNC_SIG(owner) eq get_owner jumpi dup1 __FUNC_SIG(pendingOwner) eq get_pending_owner jumpi - not_found jump + // Bubble up to the parent macro + no_match jump set_pending_owner: OWNABLE_SET_PENDING_OWNER() @@ -155,5 +156,5 @@ get_pending_owner: OWNABLE_GET_PENDING_OWNER() - not_found: + no_match: } diff --git a/test/auth/Auth.t.sol b/test/auth/Auth.t.sol index 4f6853a8..5db5567a 100644 --- a/test/auth/Auth.t.sol +++ b/test/auth/Auth.t.sol @@ -35,19 +35,21 @@ contract AuthTest is Test { bytes memory owner = abi.encode(OWNER); bytes memory authority = abi.encode(INIT_AUTHORITY); - // Deploy a roles authority for later use - HuffConfig roleConfig = HuffDeployer.config().with_args(bytes.concat(owner, authority)); - vm.expectEmit(true, true, true, true); - emit AuthorityUpdated(address(roleConfig), INIT_AUTHORITY); - emit OwnerUpdated(address(roleConfig), OWNER); - rolesAuth = RolesAuthority(roleConfig.deploy("auth/RolesAuthority")); - - // Create Auth - HuffConfig config = HuffDeployer.config().with_args(bytes.concat(owner, authority)); + // Deploy the roles authority + string memory wrapper_code = vm.readFile("test/auth/mocks/RolesAuthorityWrappers.huff"); + HuffConfig config = HuffDeployer.config().with_code(wrapper_code).with_args(bytes.concat(owner, authority)); vm.expectEmit(true, true, true, true); emit AuthorityUpdated(address(config), INIT_AUTHORITY); emit OwnerUpdated(address(config), OWNER); - auth = Auth(config.deploy("auth/Auth")); + rolesAuth = RolesAuthority(config.deploy("auth/RolesAuthority")); + + // Deploy the authority + string memory auth_wrapper_code = vm.readFile("test/auth/mocks/AuthWrappers.huff"); + HuffConfig auth_config = HuffDeployer.config().with_code(auth_wrapper_code).with_args(bytes.concat(owner, authority)); + vm.expectEmit(true, true, true, true); + emit AuthorityUpdated(address(auth_config), INIT_AUTHORITY); + emit OwnerUpdated(address(auth_config), OWNER); + auth = Auth(auth_config.deploy("auth/Auth")); } /// @notice Test that a non-matching signature reverts @@ -140,11 +142,9 @@ contract AuthTest is Test { function testAuthoritiesCanSetAuthority() public { // Create Roles Auth for authority - rolesAuth = RolesAuthority( - HuffDeployer.deploy_with_args( - "auth/RolesAuthority", - bytes.concat(abi.encode(OWNER), abi.encode(OWNER)) - )); + string memory wrapper_code = vm.readFile("test/auth/mocks/RolesAuthorityWrappers.huff"); + HuffConfig config = HuffDeployer.config().with_code(wrapper_code).with_args(bytes.concat(abi.encode(OWNER), abi.encode(OWNER))); + rolesAuth = RolesAuthority(config.deploy("auth/RolesAuthority")); // Set roles auth as the authority vm.prank(OWNER); diff --git a/test/auth/Owned.t.sol b/test/auth/Owned.t.sol index 722c3352..7cdfb402 100644 --- a/test/auth/Owned.t.sol +++ b/test/auth/Owned.t.sol @@ -18,7 +18,8 @@ contract OwnedTest is Test { function setUp() public { // Create Owner - HuffConfig config = HuffDeployer.config().with_args(abi.encode(OWNER)); + string memory wrapper_code = vm.readFile("test/auth/mocks/OwnedWrappers.huff"); + HuffConfig config = HuffDeployer.config().with_code(wrapper_code).with_args(abi.encode(OWNER)); vm.expectEmit(true, true, true, true); emit OwnerUpdated(address(config), OWNER); owner = Owned(config.deploy("auth/Owned")); diff --git a/test/auth/RolesAuthority.t.sol b/test/auth/RolesAuthority.t.sol index ba773585..8a2933de 100644 --- a/test/auth/RolesAuthority.t.sol +++ b/test/auth/RolesAuthority.t.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.15; import "forge-std/Test.sol"; -import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; -import {HuffConfig} from "foundry-huff/HuffConfig.sol"; +import { HuffDeployer } from "foundry-huff/HuffDeployer.sol"; +import { HuffConfig } from "foundry-huff/HuffConfig.sol"; interface RolesAuthority { function hasRole(address user, uint8 role) external returns (bool); @@ -28,8 +28,13 @@ contract RolesAuthorityTest is Test { bytes memory owner = abi.encode(OWNER); bytes memory authority = abi.encode(INIT_AUTHORITY); - // Deploy RolesAuthority - HuffConfig config = HuffDeployer.config().with_args(bytes.concat(owner, authority)); + // Grab wrapper code + string memory wrapper_code = vm.readFile("test/auth/mocks/RolesAuthorityWrappers.huff"); + + // Create the config deployer + HuffConfig config = HuffDeployer.config().with_code(wrapper_code).with_args(bytes.concat(owner, authority)); + + // Deploy and expect events vm.expectEmit(true, true, true, true); emit AuthorityUpdated(address(config), INIT_AUTHORITY); emit OwnerUpdated(address(config), OWNER); diff --git a/test/auth/mocks/AuthWrappers.huff b/test/auth/mocks/AuthWrappers.huff new file mode 100644 index 00000000..16dc708a --- /dev/null +++ b/test/auth/mocks/AuthWrappers.huff @@ -0,0 +1,10 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + AUTH_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + AUTH_MAIN() + 0x00 dup1 revert +} diff --git a/test/auth/mocks/OwnedWrappers.huff b/test/auth/mocks/OwnedWrappers.huff new file mode 100644 index 00000000..4d22b3a0 --- /dev/null +++ b/test/auth/mocks/OwnedWrappers.huff @@ -0,0 +1,10 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + OWNED_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + OWNED_MAIN() + 0x00 dup1 revert +} diff --git a/test/auth/mocks/RolesAuthorityWrappers.huff b/test/auth/mocks/RolesAuthorityWrappers.huff new file mode 100644 index 00000000..3656f26a --- /dev/null +++ b/test/auth/mocks/RolesAuthorityWrappers.huff @@ -0,0 +1,10 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + AUTH_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + ROLES_AUTHORITY_MAIN() + 0x00 dup1 revert +} diff --git a/test/data-structures/mocks/HashmapWrappers.huff b/test/data-structures/mocks/HashmapWrappers.huff index b1b40f15..448f3c04 100644 --- a/test/data-structures/mocks/HashmapWrappers.huff +++ b/test/data-structures/mocks/HashmapWrappers.huff @@ -50,17 +50,18 @@ stop } -/* Main Macro - The contract entrypoint */ +// Main Macro - The contract entrypoint #define macro MAIN() = takes(0) returns (0) { // Identify which function is being called using the 4 byte function signature - 0x00 calldataload 0xE0 shr - dup1 0x437b8ad6 eq load_element jumpi - dup1 0xf268de10 eq load_element_from_keys jumpi - dup1 0x376caf9f eq store_element jumpi - dup1 0x2fdb44d8 eq store_element_from_keys jumpi + pc calldataload 0xE0 shr + + dup1 __FUNC_SIG(loadElement) eq load_element jumpi + dup1 __FUNC_SIG(loadElementFromKeys) eq load_element_from_keys jumpi + dup1 __FUNC_SIG(storeElement) eq store_element jumpi + dup1 __FUNC_SIG(storeElementFromKeys) eq store_element_from_keys jumpi // Revert if otherwise - 0x00 0x00 revert + 0x00 dup1 revert load_element: GET() diff --git a/test/proxies/mocks/ClonesWrappers.huff b/test/proxies/mocks/ClonesWrappers.huff index 207961c7..92178cb0 100644 --- a/test/proxies/mocks/ClonesWrappers.huff +++ b/test/proxies/mocks/ClonesWrappers.huff @@ -39,10 +39,10 @@ #define macro MAIN() = { pc calldataload 0xe0 shr - dup1 __FUNC_SIG(clone) eq clone_jump jumpi - dup1 __FUNC_SIG(cloneDeterministic) eq clone_deterministic_jump jumpi - dup1 __FUNC_SIG(predictDeterministicAddress) eq predict_deterministic_address_jump jumpi - dup1 0x93a7e711 eq predict_deterministic_address_deployer_jump jumpi + dup1 __FUNC_SIG(clone) eq clone_jump jumpi + dup1 __FUNC_SIG(cloneDeterministic) eq clone_deterministic_jump jumpi + dup1 __FUNC_SIG(predictDeterministicAddress) eq predict_deterministic_address_jump jumpi + dup1 __FUNC_SIG("predictDeterministicAddress(address,bytes32,address)") eq predict_deterministic_address_deployer_jump jumpi // Exit is selector does not match 0x00 dup1 revert diff --git a/test/proxies/mocks/ProxyWrappers.huff b/test/proxies/mocks/ProxyWrappers.huff index 9d0070dc..6f1d675d 100644 --- a/test/proxies/mocks/ProxyWrappers.huff +++ b/test/proxies/mocks/ProxyWrappers.huff @@ -84,9 +84,9 @@ #define macro CONSTRUCTOR() = { // ERC1967_PROXY_CONSTRUCTOR() - 0x20 + 0x20 0x20 codesize sub - 0x00 + 0x00 codecopy 0x00 mload @@ -96,21 +96,20 @@ #define macro MAIN() = { pc calldataload 0xe0 shr - dup1 __FUNC_SIG(implementation) eq implementation jumpi dup1 __FUNC_SIG(upgradeTo) eq upgradeTo jumpi dup1 __FUNC_SIG(upgradeToAndCall) eq upgradeToAndCall jumpi dup1 __FUNC_SIG(upgradeToAndCallUUPS) eq upgradeToAndCallUUPS jumpi - + dup1 __FUNC_SIG(admin) eq getAdmin jumpi dup1 __FUNC_SIG(changeAdmin) eq changeAdmin jumpi - + dup1 __FUNC_SIG(beacon) eq getBeacon jumpi dup1 __FUNC_SIG(setBeacon) eq setBeacon jumpi dup1 __FUNC_SIG(upgradeBeaconAndCall) eq upgradeBeaconAndCall jumpi GET_IMPLEMENTATION() // [implementation] - DELEGATE() + DELEGATE() implementation: IMPLEMENTATION_WRAPPER() diff --git a/test/tokens/mocks/ERC20MintableWrappers.huff b/test/tokens/mocks/ERC20MintableWrappers.huff index 08a61c57..b20668a6 100644 --- a/test/tokens/mocks/ERC20MintableWrappers.huff +++ b/test/tokens/mocks/ERC20MintableWrappers.huff @@ -30,7 +30,7 @@ } #define macro CONSTRUCTOR() = takes (0) returns (0) { - INNER_ERC20_CONSTRUCTOR() + ERC20_CONSTRUCTOR() } #define macro MAIN() = takes (0) returns (0) { diff --git a/test/tokens/mocks/ERC20Wrappers.huff b/test/tokens/mocks/ERC20Wrappers.huff index 5475046a..085a5c4f 100644 --- a/test/tokens/mocks/ERC20Wrappers.huff +++ b/test/tokens/mocks/ERC20Wrappers.huff @@ -1,10 +1,10 @@ #define macro CONSTRUCTOR() = takes (0) returns (0) { - INNER_ERC20_CONSTRUCTOR() + ERC20_CONSTRUCTOR() } #define macro MAIN() = { 0x00 calldataload 0xE0 shr // [func sig] - MAIN_ERC20() + ERC20_MAIN() 0x00 dup1 revert } diff --git a/test/tokens/mocks/ERC4626Wrappers.huff b/test/tokens/mocks/ERC4626Wrappers.huff index 1e2c6c6b..c36fd0c2 100644 --- a/test/tokens/mocks/ERC4626Wrappers.huff +++ b/test/tokens/mocks/ERC4626Wrappers.huff @@ -6,7 +6,7 @@ #define constant AFTER_HOOK_COUNTER = FREE_STORAGE_POINTER() #define macro CONSTRUCTOR() = takes (0) returns (0) { - INNER_4626_CONSTRUCTOR() // [] + ERC4626_CONSTRUCTOR() // [] } #define macro BEFORE_WITHDRAW() = takes (2) returns (0) { @@ -78,7 +78,7 @@ dup1 __FUNC_SIG(beforeWithdrawHookCalledCounter) eq before_jump jumpi // [sig] dup1 __FUNC_SIG(afterDepositHookCalledCounter) eq after_jump jumpi // [sig] - INNER_4626_MAIN() // [sig] + ERC4626_MAIN() // [sig] 0x00 dup1 revert diff --git a/test/tokens/mocks/ERC721Wrappers.huff b/test/tokens/mocks/ERC721Wrappers.huff index 3f55fb8f..1cd122fd 100644 --- a/test/tokens/mocks/ERC721Wrappers.huff +++ b/test/tokens/mocks/ERC721Wrappers.huff @@ -158,8 +158,8 @@ dup1 __FUNC_SIG(mint) eq mint_jump jumpi dup1 __FUNC_SIG(burn) eq burn_jump jumpi - dup1 0xa1448194 eq safe_mint jumpi - dup1 0x8832e6e3 eq safe_mint_with_data jumpi + dup1 __FUNC_SIG("safeMint(address,uint256)") eq safe_mint jumpi + dup1 __FUNC_SIG("safeMint(address,uint256,bytes)") eq safe_mint_with_data jumpi dup1 __FUNC_SIG(approve) eq approve jumpi dup1 __FUNC_SIG(setApprovalForAll) eq setApprovalForAll jumpi diff --git a/test/utils/mocks/BitPackLibWrappers.huff b/test/utils/mocks/BitPackLibWrappers.huff index 1b88ff6e..9176492f 100644 --- a/test/utils/mocks/BitPackLibWrappers.huff +++ b/test/utils/mocks/BitPackLibWrappers.huff @@ -41,10 +41,11 @@ #define macro MAIN() = takes (0) returns (0) { // Identify which function is being called using the 4 byte function signature pc calldataload 0xE0 shr - dup1 0x20cf269e eq packValue jumpi - dup1 0x0ec88d16 eq unpackValueFromRight jumpi - dup1 0xf59c8b86 eq unpackValueFromLeft jumpi - dup1 0xe6022afd eq unpackValueFromCenter jumpi + + dup1 __FUNC_SIG(packValue) eq packValue jumpi + dup1 __FUNC_SIG(unpackValueFromRight) eq unpackValueFromRight jumpi + dup1 __FUNC_SIG(unpackValueFromLeft) eq unpackValueFromLeft jumpi + dup1 __FUNC_SIG(unpackValueFromCenter) eq unpackValueFromCenter jumpi 0x00 0x00 revert diff --git a/test/utils/mocks/MerkleDistributorWrappers.huff b/test/utils/mocks/MerkleDistributorWrappers.huff index 0a769c8c..4c38455a 100644 --- a/test/utils/mocks/MerkleDistributorWrappers.huff +++ b/test/utils/mocks/MerkleDistributorWrappers.huff @@ -1,10 +1,10 @@ #define macro CONSTRUCTOR() = takes (0) returns (0) { - INNER_MERKLE_CONSTRUCTOR() + MERKLE_DISTRIBUTOR_CONSTRUCTOR() } #define macro MAIN() = takes (0) returns (0) { pc calldataload 0xE0 shr - INNER_MERKLE_MAIN() + MERKLE_DISTRIBUTOR_MAIN() 0x00 dup1 revert } diff --git a/test/utils/mocks/SSTORE2Wrappers.huff b/test/utils/mocks/SSTORE2Wrappers.huff index 74a34d06..c5084ba5 100644 --- a/test/utils/mocks/SSTORE2Wrappers.huff +++ b/test/utils/mocks/SSTORE2Wrappers.huff @@ -36,8 +36,8 @@ dup1 __FUNC_SIG(write) eq write_jump jumpi dup1 __FUNC_SIG(read) eq read_jump jumpi - dup1 0x014c2add eq read_at_jump jumpi - dup1 0x8937dad8 eq read_between_jump jumpi + dup1 __FUNC_SIG("read(address,uint256)") eq read_at_jump jumpi + dup1 __FUNC_SIG("read(address,uint256,uint256)") eq read_between_jump jumpi 0x00 dup1 revert diff --git a/test/utils/mocks/TSOwnableWrappers.huff b/test/utils/mocks/TSOwnableWrappers.huff index 2613b4cf..179ef269 100644 --- a/test/utils/mocks/TSOwnableWrappers.huff +++ b/test/utils/mocks/TSOwnableWrappers.huff @@ -1,10 +1,10 @@ #define macro CONSTRUCTOR() = takes (0) returns (0) { - CONSTRUCTOR_TSOWNABLE() + TSOWNABLE_CONSTRUCTOR() } #define macro MAIN() = takes (0) returns (0) { pc calldataload 0xe0 shr // [sig] - MAIN_TSOWNABLE() // [sig] + TSOWNABLE_MAIN() // [sig] 0x00 dup1 revert // [] } \ No newline at end of file