diff --git a/README.md b/README.md index 97e1b27..1d0e629 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,8 @@ $ forge test ``` ## Usage +Version 0 of The Compact is currently deployed on mainnet, Sepolia, Unichain testnet, Base, and Base Sepolia at `0x00000000000018DF021Ff2467dF97ff846E09f48`. As long as the prerequisite deployer contract and Permit2 are deployed to a given chain, The Compact can be deployed to any new chain by running `forge script script/TheCompact.s.sol`. + ### 1) Register an Allocator To begin using The Compact, an allocator must first be registered on the contract. Anyone can register any account as an allocator by calling the `__register` function as long as one of the following requirements are met: - the allocator being registered is the caller diff --git a/script/TheCompact.s.sol b/script/TheCompact.s.sol index 3a8e7c2..cac5735 100644 --- a/script/TheCompact.s.sol +++ b/script/TheCompact.s.sol @@ -4,6 +4,10 @@ pragma solidity ^0.8.13; import { Script, console } from "forge-std/Script.sol"; import { TheCompact } from "../src/TheCompact.sol"; +interface ImmutableCreate2Factory { + function safeCreate2(bytes32 salt, bytes calldata initializationCode) external payable returns (address deploymentAddress); +} + contract TheCompactScript is Script { TheCompact public theCompact; @@ -12,7 +16,23 @@ contract TheCompactScript is Script { function run() public { vm.startBroadcast(); - theCompact = new TheCompact(); + // ensure permit2 is deployed + assert(address(0x000000000022D473030F116dDEE9F6B43aC78BA3).code.length > 0); + + // to deploy using create2 (need to rederive salt and target address when changing code): + bytes32 salt = bytes32(0x00000000000000000000000000000000000000008a0f466a78cd1102ce3d82f7); + address targetAddress = address(0x00000000000018DF021Ff2467dF97ff846E09f48); + // ensure create2 deployer is deployed + address immutableCreate2Factory = address(0x0000000000FFe8B47B3e2130213B802212439497); + assert(immutableCreate2Factory.code.length > 0); + // deploy it and check the target address + theCompact = TheCompact(ImmutableCreate2Factory(immutableCreate2Factory).safeCreate2(salt, type(TheCompact).creationCode)); + assert(address(theCompact) == targetAddress); + + // // to just deploy it directly: + // theCompact = new TheCompact(); + + assert(keccak256(bytes(theCompact.name())) == keccak256(bytes("The Compact"))); vm.stopBroadcast(); } diff --git a/src/lib/ClaimHashFunctionCastLib.sol b/src/lib/ClaimHashFunctionCastLib.sol index e318de9..6ee3577 100644 --- a/src/lib/ClaimHashFunctionCastLib.sol +++ b/src/lib/ClaimHashFunctionCastLib.sol @@ -54,7 +54,7 @@ import { /** * @title ClaimHashFunctionCastLib - * @notice Libray contract implementing function casts used throughout the codebase, + * @notice Library contract implementing function casts used throughout the codebase, * particularly as part of processing claims. The input function operates on a * function that takes some argument that differs from what is currently available. * The output function modifies one or more argument types so that they match the diff --git a/src/lib/ClaimHashLib.sol b/src/lib/ClaimHashLib.sol index e5a36ab..2d08076 100644 --- a/src/lib/ClaimHashLib.sol +++ b/src/lib/ClaimHashLib.sol @@ -76,7 +76,7 @@ import { HashLib } from "./HashLib.sol"; /** * @title ClaimHashLib - * @notice Libray contract implementing logic for deriving hashes as part of processing + * @notice Library contract implementing logic for deriving hashes as part of processing * claims, allocated transfers, and withdrawals. */ library ClaimHashLib { diff --git a/src/lib/ClaimProcessorFunctionCastLib.sol b/src/lib/ClaimProcessorFunctionCastLib.sol index 55d5b4d..859da17 100644 --- a/src/lib/ClaimProcessorFunctionCastLib.sol +++ b/src/lib/ClaimProcessorFunctionCastLib.sol @@ -54,7 +54,7 @@ import { /** * @title ClaimProcessorFunctionCastLib - * @notice Libray contract implementing function casts used in ClaimProcessorLogic. + * @notice Library contract implementing function casts used in ClaimProcessorLogic. * The input function operates on a function that takes some argument that differs * from what is currently available. The output function modifies one or more * argument types so that they match the arguments that are being used to call the diff --git a/src/lib/ConsumerLib.sol b/src/lib/ConsumerLib.sol index 6d18526..ab0ad6c 100644 --- a/src/lib/ConsumerLib.sol +++ b/src/lib/ConsumerLib.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.27; /** * @title ConsumerLib - * @notice Libray contract implementing logic for consuming bitpacked nonces scoped to + * @notice Library contract implementing logic for consuming bitpacked nonces scoped to * specific accounts and for querying for the state of those nonces. Note that only the * allocator nonce scope is currently in use in The Compact. */ diff --git a/src/lib/DomainLib.sol b/src/lib/DomainLib.sol index 509f0ab..32d6626 100644 --- a/src/lib/DomainLib.sol +++ b/src/lib/DomainLib.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.27; /** * @title DomainLib - * @notice Libray contract implementing logic for deriving domain hashes. + * @notice Library contract implementing logic for deriving domain hashes. */ library DomainLib { /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`. diff --git a/src/lib/HashLib.sol b/src/lib/HashLib.sol index fde0eb3..7313fae 100644 --- a/src/lib/HashLib.sol +++ b/src/lib/HashLib.sol @@ -31,7 +31,7 @@ import { TransferFunctionCastLib } from "./TransferFunctionCastLib.sol"; /** * @title HashLib - * @notice Libray contract implementing logic for deriving hashes as part of processing + * @notice Library contract implementing logic for deriving hashes as part of processing * claims, allocated transfers, and withdrawals, including deriving typehashes when * witness data is utilized and qualification hashes when claims have been qualified by * the allocator. diff --git a/src/lib/IdLib.sol b/src/lib/IdLib.sol index 57905c1..83d2db8 100644 --- a/src/lib/IdLib.sol +++ b/src/lib/IdLib.sol @@ -13,7 +13,7 @@ import { EfficientHashLib } from "solady/utils/EfficientHashLib.sol"; /** * @title IdLib - * @notice Libray contract implementing logic for deriving IDs for allocators and + * @notice Library contract implementing logic for deriving IDs for allocators and * for resource locks, converting between various IDs, and for extracting details * related to those IDs. This includes logic for registering allocators and for * assigning them an allocator ID. diff --git a/src/lib/MetadataLib.sol b/src/lib/MetadataLib.sol index 074e937..f6baadd 100644 --- a/src/lib/MetadataLib.sol +++ b/src/lib/MetadataLib.sol @@ -11,7 +11,7 @@ import { MetadataReaderLib } from "solady/utils/MetadataReaderLib.sol"; /** * @title MetadataLib - * @notice Libray contract implementing logic for deriving and displaying + * @notice Library contract implementing logic for deriving and displaying * ERC6909 metadata as well as metadata specific to various underlying tokens. */ library MetadataLib { diff --git a/src/lib/RegistrationLib.sol b/src/lib/RegistrationLib.sol index 9b397f2..20f37fb 100644 --- a/src/lib/RegistrationLib.sol +++ b/src/lib/RegistrationLib.sol @@ -8,7 +8,7 @@ import { IdLib } from "./IdLib.sol"; /** * @title RegistrationLib - * @notice Libray contract implementing logic for registering compact claim hashes + * @notice Library contract implementing logic for registering compact claim hashes * and typehashes and querying for whether given claim hashes and typehashes have * been registered. */ diff --git a/src/lib/TransferFunctionCastLib.sol b/src/lib/TransferFunctionCastLib.sol index 4db7b1f..38e4277 100644 --- a/src/lib/TransferFunctionCastLib.sol +++ b/src/lib/TransferFunctionCastLib.sol @@ -7,7 +7,7 @@ import { TransferComponent, SplitByIdComponent } from "../types/Components.sol"; /** * @title TransferFunctionCastLib - * @notice Libray contract implementing function casts used in TransferLogic as well as + * @notice Library contract implementing function casts used in TransferLogic as well as * in HashLib. The input function operates on a function that takes some argument that * differs from what is currently available. The output function modifies one or more * argument types so that they match the arguments that are being used to call the diff --git a/src/lib/ValidityLib.sol b/src/lib/ValidityLib.sol index d88ec1e..6a765e5 100644 --- a/src/lib/ValidityLib.sol +++ b/src/lib/ValidityLib.sol @@ -11,7 +11,7 @@ import { SignatureCheckerLib } from "solady/utils/SignatureCheckerLib.sol"; /** * @title ValidityLib - * @notice Libray contract implementing logic for validating expirations, + * @notice Library contract implementing logic for validating expirations, * signatures, nonces (including consuming unused nonces), and token addresses. */ library ValidityLib { diff --git a/test/TheCompact.t.sol b/test/TheCompact.t.sol index 0d539d3..a6e4d08 100644 --- a/test/TheCompact.t.sol +++ b/test/TheCompact.t.sol @@ -84,6 +84,10 @@ interface EIP712 { function DOMAIN_SEPARATOR() external view returns (bytes32); } +interface ImmutableCreate2Factory { + function safeCreate2(bytes32 salt, bytes calldata initializationCode) external payable returns (address deploymentAddress); +} + contract TheCompactTest is Test { TheCompact public theCompact; MockERC20 public token; @@ -117,9 +121,22 @@ contract TheCompactTest is Test { (bool ok,) = permit2Deployer.call(permit2CreationCalldata); require(ok && permit2.code.length != 0, "permit2 deployment failed"); - theCompact = new TheCompact(); - token = new MockERC20("Mock ERC20", "MOCK", 18); anotherToken = new MockERC20("Another Mock ERC20", "MOCK2", 18); + token = new MockERC20("Mock ERC20", "MOCK", 18); + + address immutableCreate2Factory = address(0x0000000000FFe8B47B3e2130213B802212439497); + bytes memory immutableCreate2FactoryRuntimeCode = + hex"60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009857806385cf97ab14610138578063a49a7c90146101bc575b600080fd5b34801561005057600080fd5b506100846004803603602081101561006757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101ec565b604080519115158252519081900360200190f35b61010f600480360360408110156100ae57600080fd5b813591908101906040810160208201356401000000008111156100d057600080fd5b8201836020820111156100e257600080fd5b8035906020019184600183028401116401000000008311171561010457600080fd5b509092509050610217565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561014457600080fd5b5061010f6004803603604081101561015b57600080fd5b8135919081019060408101602082013564010000000081111561017d57600080fd5b82018360208201111561018f57600080fd5b803590602001918460018302840111640100000000831117156101b157600080fd5b509092509050610592565b3480156101c857600080fd5b5061010f600480360360408110156101df57600080fd5b508035906020013561069e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205460ff1690565b600083606081901c33148061024c57507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116155b6102a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260458152602001806107746045913960600191505060405180910390fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051855195965090943094508b93508692506020918201918291908401908083835b6020831061033557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016102f8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018281037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183528085528251928201929092207fff000000000000000000000000000000000000000000000000000000000000008383015260609890981b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602183015260358201969096526055808201979097528251808203909701875260750182525084519484019490942073ffffffffffffffffffffffffffffffffffffffff81166000908152938490529390922054929350505060ff16156104a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180610735603f913960400191505060405180910390fd5b81602001825188818334f5955050508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461053a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260468152602001806107b96046913960600191505060405180910390fd5b50505073ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790559392505050565b6000308484846040516020018083838082843760408051919093018181037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001825280845281516020928301207fff000000000000000000000000000000000000000000000000000000000000008383015260609990991b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166021820152603581019790975260558088019890985282518088039098018852607590960182525085519585019590952073ffffffffffffffffffffffffffffffffffffffff81166000908152948590529490932054939450505060ff909116159050610697575060005b9392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091523060601b6021830152603582018590526055808301859052835180840390910181526075909201835281519181019190912073ffffffffffffffffffffffffffffffffffffffff81166000908152918290529190205460ff161561072e575060005b9291505056fe496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c7265616479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374207573696e672070726f76696465642073616c7420616e6420696e697469616c697a6174696f6e20636f64652ea265627a7a723058202bdc55310d97c4088f18acf04253db593f0914059f0c781a9df3624dcef0d1cf64736f6c634300050a0032"; + vm.etch(immutableCreate2Factory, immutableCreate2FactoryRuntimeCode); + bytes32 salt = bytes32(0x00000000000000000000000000000000000000008a0f466a78cd1102ce3d82f7); + address targetAddress = address(0x00000000000018DF021Ff2467dF97ff846E09f48); + + // to deploy using create2 (need to rederive salt and target address when changing code): + theCompact = TheCompact(ImmutableCreate2Factory(immutableCreate2Factory).safeCreate2(salt, type(TheCompact).creationCode)); + assertEq(address(theCompact), targetAddress); + + // // to deploy using standard create: + // theCompact = new TheCompact(); (swapper, swapperPrivateKey) = makeAddrAndKey("swapper"); (allocator, allocatorPrivateKey) = makeAddrAndKey("allocator");