From 369c51501ecf731cea7ecff2352a0ffb70f0108c Mon Sep 17 00:00:00 2001 From: Filipp Makarov Date: Thu, 12 Dec 2024 14:59:31 +0300 Subject: [PATCH] sign over chain id and salt --- contracts/utils/Deployer.sol | 2 +- .../artifacts/Deployer/Deployer.json | 2 +- .../artifacts/Deployer/verify.json | 1 + scripts/bash-deploy/deploy-gasdaddy.sh | 1 + scripts/bash-deploy/deploy-prerequisites.sh | 3 +- scripts/foundry/DeployDeployer.s.sol | 6 +- scripts/foundry/DeployGasdaddy.s.sol | 76 ++++++++----------- 7 files changed, 38 insertions(+), 53 deletions(-) create mode 100644 scripts/bash-deploy/artifacts/Deployer/verify.json diff --git a/contracts/utils/Deployer.sol b/contracts/utils/Deployer.sol index 9460075..f6d07ff 100644 --- a/contracts/utils/Deployer.sol +++ b/contracts/utils/Deployer.sol @@ -14,7 +14,7 @@ contract Deployer is SoladyOwnable { constructor(address _owner) SoladyOwnable(_owner) {} function deploy(bytes32 _salt, bytes calldata _creationCode, bytes calldata signature) external returns (address deployedContract) { - bytes32 hash = keccak256(_creationCode); + bytes32 hash = keccak256(abi.encode(_creationCode, _salt, block.chainid)); if (!_verifySignature(hash, signature)) revert InvalidBytecodeSignature(); deployedContract = Create3.create3(_salt, _creationCode); emit ContractDeployed(deployedContract); diff --git a/scripts/bash-deploy/artifacts/Deployer/Deployer.json b/scripts/bash-deploy/artifacts/Deployer/Deployer.json index eab7c99..2c3f223 100644 --- a/scripts/bash-deploy/artifacts/Deployer/Deployer.json +++ b/scripts/bash-deploy/artifacts/Deployer/Deployer.json @@ -1 +1 @@ -{"abi":[{"type":"constructor","inputs":[{"name":"_owner","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"addressOf","inputs":[{"name":"_salt","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"cancelOwnershipHandover","inputs":[],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"completeOwnershipHandover","inputs":[{"name":"pendingOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"deploy","inputs":[{"name":"_salt","type":"bytes32","internalType":"bytes32"},{"name":"_creationCode","type":"bytes","internalType":"bytes"},{"name":"signature","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"deployedContract","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"deploy","inputs":[{"name":"_salt","type":"bytes32","internalType":"bytes32"},{"name":"_creationCode","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"deployedContract","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"result","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"ownershipHandoverExpiresAt","inputs":[{"name":"pendingOwner","type":"address","internalType":"address"}],"outputs":[{"name":"result","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"requestOwnershipHandover","inputs":[],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"type":"event","name":"ContractDeployed","inputs":[{"name":"contractAddress","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipHandoverCanceled","inputs":[{"name":"pendingOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipHandoverRequested","inputs":[{"name":"pendingOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"oldOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"error","name":"AlreadyInitialized","inputs":[]},{"type":"error","name":"ErrorCreatingContract","inputs":[]},{"type":"error","name":"ErrorCreatingProxy","inputs":[]},{"type":"error","name":"InvalidBytecodeSignature","inputs":[]},{"type":"error","name":"NewOwnerIsZeroAddress","inputs":[]},{"type":"error","name":"NoHandoverRequest","inputs":[]},{"type":"error","name":"TargetAlreadyExists","inputs":[]},{"type":"error","name":"Unauthorized","inputs":[]}],"bytecode":{"object":"0x34605f5761087a388190036080601f8201601f19168101906001600160401b03821190821017606357602092829160405260803912605f576080516001600160a01b0381168103605f576050906077565b6040516107b490816100c68239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b8060601b1560b8576001600160a01b0316638b78c6d8198190555f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a3565b637448fbae5f526004601cfdfe60806040526004361015610011575f80fd5b5f3560e01c806319cdeff1146100b457806325692962146100af57806354d1f13d146100aa578063715018a6146100a55780638da5cb5b146100a0578063bb34534c1461009b578063cdcb760a14610096578063f04e283e14610091578063f2fde38b1461008c5763fee81cf414610087575f80fd5b610458565b610428565b6103e4565b61037c565b61034d565b610323565b6102da565b610296565b61024d565b3461021b57606036600319011261021b5760043560243567ffffffffffffffff811161021b576100e890369060040161021f565b9060443567ffffffffffffffff811161021b5761010c61012491369060040161021f565b906101183686866104d6565b6020815191012061050c565b1561020c576101349136916104d6565b61013c61073d565b91610146816105dc565b92833b6101fd576020815191015ff56001600160a01b038116156101ee57815f92918360208194519301915af161017b610778565b501580156101e5575b6101d6576101d29060405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b0390f35b6353de54b960e01b5f5260045ffd5b50803b15610184565b63bbd2fe8760e01b5f5260045ffd5b63cd43efa160e01b5f5260045ffd5b6306f691ef60e51b5f5260045ffd5b5f80fd5b9181601f8401121561021b5782359167ffffffffffffffff831161021b576020838186019501011161021b57565b5f36600319011261021b5763389a75e1600c52335f526202a30042016020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a2005b5f36600319011261021b5763389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2005b5f36600319011261021b576102ed610582565b5f638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a35f638b78c6d81955005b3461021b575f36600319011261021b576020638b78c6d819546001600160a01b0360405191168152f35b3461021b57602036600319011261021b57602061036b6004356105dc565b6001600160a01b0360405191168152f35b3461021b57604036600319011261021b5760043560243567ffffffffffffffff811161021b576103b361013491369060040161021f565b6103bb610582565b36916104d6565b602090600319011261021b576004356001600160a01b038116810361021b5790565b6103ed366103c2565b6103f5610582565b63389a75e1600c52805f526020600c20908154421161041b575f610419925561059e565b005b636f5e88185f526004601cfd5b610431366103c2565b610439610582565b8060601b1561044b576104199061059e565b637448fbae5f526004601cfd5b3461021b57610466366103c2565b63389a75e1600c525f52602080600c2054604051908152f35b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176104b557604052565b61047f565b67ffffffffffffffff81116104b557601f01601f191660200190565b9291926104e2826104ba565b916104f06040519384610493565b82948184528183011161021b578281602093845f960137010152565b6001600160a01b03926105208184846106a2565b638b78c6d81954851694168414610579576001600160a01b039261056a926020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c6004206106a2565b1614610574575f90565b600190565b50505050600190565b638b78c6d81954330361059157565b6382b429005f526004601cfd5b6001600160a01b031680638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3638b78c6d81955565b6106936001600160a01b0361069f92604051602081019160ff60f81b83523060601b602183015260358201527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f60558201526055815261063d607582610493565b5190206040516135a560f21b602082019081529290911660601b6bffffffffffffffffffffffff19166022820152600160f81b603682015260178152610684603782610493565b5190206001600160a01b031690565b6001600160a01b031690565b90565b9092919260405193806040146106fd576041146106cb57505050505b638baa579f5f526004601cfd5b806040809201355f1a60205281375b5f526020600160805f825afa51915f6060526040523d6106fb5750506106be565b565b508060207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92013590601b8260ff1c0160205235604052166060526106da565b6040519061074c604083610493565b601082527f67363d3d37363d34f03d5260086018f3000000000000000000000000000000006020830152565b3d156107a2573d90610789826104ba565b916107976040519384610493565b82523d5f602084013e565b60609056fea164736f6c634300081b000a","sourceMap":"163:1299:5:-:0;;;;;;;;;;;;-1:-1:-1;;163:1299:5;;;;-1:-1:-1;;;;;163:1299:5;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;163:1299:5;;;;;;334:52;;;:::i;:::-;163:1299;;;;;;;;;;-1:-1:-1;163:1299:5;;;;;;-1:-1:-1;163:1299:5;;;;;-1:-1:-1;163:1299:5;150:269:6;198:181;;;;;;-1:-1:-1;;;;;5710:347:20;-1:-1:-1;;5710:347:20;;;-1:-1:-1;5710:347:20;-1:-1:-1;;5710:347:20;150:269:6:o;198:181::-;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x60806040526004361015610011575f80fd5b5f3560e01c806319cdeff1146100b457806325692962146100af57806354d1f13d146100aa578063715018a6146100a55780638da5cb5b146100a0578063bb34534c1461009b578063cdcb760a14610096578063f04e283e14610091578063f2fde38b1461008c5763fee81cf414610087575f80fd5b610458565b610428565b6103e4565b61037c565b61034d565b610323565b6102da565b610296565b61024d565b3461021b57606036600319011261021b5760043560243567ffffffffffffffff811161021b576100e890369060040161021f565b9060443567ffffffffffffffff811161021b5761010c61012491369060040161021f565b906101183686866104d6565b6020815191012061050c565b1561020c576101349136916104d6565b61013c61073d565b91610146816105dc565b92833b6101fd576020815191015ff56001600160a01b038116156101ee57815f92918360208194519301915af161017b610778565b501580156101e5575b6101d6576101d29060405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b0390f35b6353de54b960e01b5f5260045ffd5b50803b15610184565b63bbd2fe8760e01b5f5260045ffd5b63cd43efa160e01b5f5260045ffd5b6306f691ef60e51b5f5260045ffd5b5f80fd5b9181601f8401121561021b5782359167ffffffffffffffff831161021b576020838186019501011161021b57565b5f36600319011261021b5763389a75e1600c52335f526202a30042016020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a2005b5f36600319011261021b5763389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2005b5f36600319011261021b576102ed610582565b5f638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a35f638b78c6d81955005b3461021b575f36600319011261021b576020638b78c6d819546001600160a01b0360405191168152f35b3461021b57602036600319011261021b57602061036b6004356105dc565b6001600160a01b0360405191168152f35b3461021b57604036600319011261021b5760043560243567ffffffffffffffff811161021b576103b361013491369060040161021f565b6103bb610582565b36916104d6565b602090600319011261021b576004356001600160a01b038116810361021b5790565b6103ed366103c2565b6103f5610582565b63389a75e1600c52805f526020600c20908154421161041b575f610419925561059e565b005b636f5e88185f526004601cfd5b610431366103c2565b610439610582565b8060601b1561044b576104199061059e565b637448fbae5f526004601cfd5b3461021b57610466366103c2565b63389a75e1600c525f52602080600c2054604051908152f35b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176104b557604052565b61047f565b67ffffffffffffffff81116104b557601f01601f191660200190565b9291926104e2826104ba565b916104f06040519384610493565b82948184528183011161021b578281602093845f960137010152565b6001600160a01b03926105208184846106a2565b638b78c6d81954851694168414610579576001600160a01b039261056a926020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c6004206106a2565b1614610574575f90565b600190565b50505050600190565b638b78c6d81954330361059157565b6382b429005f526004601cfd5b6001600160a01b031680638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3638b78c6d81955565b6106936001600160a01b0361069f92604051602081019160ff60f81b83523060601b602183015260358201527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f60558201526055815261063d607582610493565b5190206040516135a560f21b602082019081529290911660601b6bffffffffffffffffffffffff19166022820152600160f81b603682015260178152610684603782610493565b5190206001600160a01b031690565b6001600160a01b031690565b90565b9092919260405193806040146106fd576041146106cb57505050505b638baa579f5f526004601cfd5b806040809201355f1a60205281375b5f526020600160805f825afa51915f6060526040523d6106fb5750506106be565b565b508060207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92013590601b8260ff1c0160205235604052166060526106da565b6040519061074c604083610493565b601082527f67363d3d37363d34f03d5260086018f3000000000000000000000000000000006020830152565b3d156107a2573d90610789826104ba565b916107976040519384610493565b82523d5f602084013e565b60609056fea164736f6c634300081b000a","sourceMap":"163:1299:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;;;;;-1:-1:-1;;163:1299:5;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;587:33;163:1299;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;548:24;587:33;:::i;:::-;586:34;582:73;;163:1299;;;;;:::i;:::-;;;:::i;:::-;3399:16:4;;;;:::i;:::-;2041:59;;;3425:53;;163:1299:5;3544:181:4;;;;163:1299:5;3544:181:4;-1:-1:-1;;;;;163:1299:5;;3738:19:4;3734:52;;3859:40;163:1299:5;3859:40:4;;;163:1299:5;3859:40:4;;;;;;;;;;:::i;:::-;;3913:8;163:1299:5;;3913:31:4;;163:1299:5;3909:67:4;;163:1299:5;;;;;;-1:-1:-1;;;;;163:1299:5;;;736:34;163:1299;736:34;;-1:-1:-1;;;;;163:1299:5;;;;;;;;;;;;3909:67:4;3953:23;;;163:1299:5;3953:23:4;163:1299:5;;3953:23:4;3913:31;2041:59;;;3925:19;3913:31;;3734:52;3766:20;;;163:1299:5;3766:20:4;163:1299:5;;3766:20:4;3425:53;3457:21;;;163:1299:5;3457:21:4;163:1299:5;;3457:21:4;582:73:5;629:26;;;163:1299;629:26;163:1299;;629:26;163:1299;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;163:1299:5;;;;9239:383:20;;;;163:1299:5;9239:383:20;7972:9;9132:15;163:1299:5;9239:383:20;;;;;;163:1299:5;9239:383:20;;163:1299:5;;;;-1:-1:-1;;163:1299:5;;;;9831:339:20;;;;163:1299:5;9831:339:20;163:1299:5;9831:339:20;;;;;;163:1299:5;9831:339:20;;163:1299:5;;;;-1:-1:-1;;163:1299:5;;;;12478:70:20;;:::i;:::-;163:1299:5;6813:405:20;;;;;;;163:1299:5;-1:-1:-1;;6813:405:20;163:1299:5;;;;;;;-1:-1:-1;;163:1299:5;;;;;6813:405:20;;11523:61;-1:-1:-1;;;;;163:1299:5;;;;;;;;;;;;;-1:-1:-1;;163:1299:5;;;;;1112:24;163:1299;;1112:24;:::i;:::-;-1:-1:-1;;;;;163:1299:5;;;;;;;;;;;;;-1:-1:-1;;163:1299:5;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12478:70:20;;:::i;:::-;163:1299:5;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;163:1299:5;;;;;;;:::o;:::-;;;;:::i;:::-;12478:70:20;;:::i;:::-;10506:526;;;;;;;;;;;;;;;;;11051:12;10506:526;;11051:12;:::i;:::-;163:1299:5;10506:526:20;;;;163:1299:5;10506:526:20;;163:1299:5;;;;:::i;:::-;12478:70:20;;:::i;:::-;8479:183;;;;;;8681:8;;;:::i;8479:183::-;;;;163:1299:5;8479:183:20;;163:1299:5;;;;;;;:::i;:::-;11885:237:20;;;-1:-1:-1;11885:237:20;;;;;;163:1299:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;:::i;:::-;;;;;;;;-1:-1:-1;;163:1299:5;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;163:1299:5;;;;;;:::o;1149:311::-;-1:-1:-1;;;;;1149:311:5;1258:31;;;;;:::i;:::-;-1:-1:-1;;11523:61:20;163:1299:5;;;;1258:42;;1254:71;;-1:-1:-1;;;;;13414:265:21;1339:56:5;13414:265:21;;;;163:1299:5;13414:265:21;;;;1339:56:5;:::i;:::-;163:1299;1339:67;1335:96;;163:1299;1149:311;:::o;1335:96::-;1427:4;1420:11;:::o;1254:71::-;1314:11;;;;1321:4;1314:11;:::o;7292:355:20:-;-1:-1:-1;;7390:251:20;;;;;7292:355::o;7390:251::-;;;;;;;6145:1089;-1:-1:-1;;;;;6813:405:20;;;;;;-1:-1:-1;6813:405:20;;-1:-1:-1;;6813:405:20;6145:1089::o;4973:345:4:-;5140:157;-1:-1:-1;;;;;5115:196:4;4973:345;163:1299:5;;4215:237:4;;;1707:66;;;;;;4314:4;163:1299:5;;1707:66:4;;;163:1299:5;1707:66:4;;;163:1299:5;1707:66:4;;;;163:1299:5;1707:66:4;4215:237;;;;;;:::i;:::-;163:1299:5;4176:302:4;;163:1299:5;;-1:-1:-1;;;4215:237:4;5212:44;;163:1299:5;;;;;;;;;-1:-1:-1;;163:1299:5;;;;;-1:-1:-1;;;163:1299:5;;;;;5212:44:4;;;163:1299:5;;5212:44:4;:::i;:::-;163:1299:5;5202:55:4;;-1:-1:-1;;;;;163:1299:5;;;5140:157:4;-1:-1:-1;;;;;163:1299:5;;;5115:196:4;4973:345;:::o;4336:1373:21:-;;;;;4521:1182;;;;;;;;;;;;;;;;;;163:1299:5;4521:1182:21;;;;;;;;;;;163:1299:5;4521:1182:21;;;;;;163:1299:5;4521:1182:21;;;;163:1299:5;4521:1182:21;;;;;163:1299:5;4521:1182:21;;;;;;;;;;;;4336:1373::o;4521:1182::-;;;;;;;;;;;;;;;;;;;;;;;;163:1299:5;;;;;;;;:::i;:::-;;;;;;;;;:::o;1485:52:4:-;;;;;;163:1299:5;;;;:::i;:::-;;;;;;;;:::i;:::-;;;1485:52:4;-1:-1:-1;1485:52:4;;;;:::o;:::-;;;:::o","linkReferences":{}},"methodIdentifiers":{"addressOf(bytes32)":"bb34534c","cancelOwnershipHandover()":"54d1f13d","completeOwnershipHandover(address)":"f04e283e","deploy(bytes32,bytes)":"cdcb760a","deploy(bytes32,bytes,bytes)":"19cdeff1","owner()":"8da5cb5b","ownershipHandoverExpiresAt(address)":"fee81cf4","renounceOwnership()":"715018a6","requestOwnershipHandover()":"25692962","transferOwnership(address)":"f2fde38b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.27+commit.40a35a09\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ErrorCreatingContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ErrorCreatingProxy\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBytecodeSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewOwnerIsZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoHandoverRequest\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TargetAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"}],\"name\":\"ContractDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pendingOwner\",\"type\":\"address\"}],\"name\":\"OwnershipHandoverCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pendingOwner\",\"type\":\"address\"}],\"name\":\"OwnershipHandoverRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_salt\",\"type\":\"bytes32\"}],\"name\":\"addressOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"cancelOwnershipHandover\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pendingOwner\",\"type\":\"address\"}],\"name\":\"completeOwnershipHandover\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_creationCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"deploy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"deployedContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_creationCode\",\"type\":\"bytes\"}],\"name\":\"deploy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"deployedContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"result\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pendingOwner\",\"type\":\"address\"}],\"name\":\"ownershipHandoverExpiresAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"requestOwnershipHandover\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"Cannot double-initialize.\"}],\"NewOwnerIsZeroAddress()\":[{\"details\":\"The `newOwner` cannot be the zero address.\"}],\"NoHandoverRequest()\":[{\"details\":\"The `pendingOwner` does not have a valid handover request.\"}],\"Unauthorized()\":[{\"details\":\"The caller is not authorized to call the function.\"}]},\"events\":{\"OwnershipHandoverCanceled(address)\":{\"details\":\"The ownership handover to `pendingOwner` has been canceled.\"},\"OwnershipHandoverRequested(address)\":{\"details\":\"An ownership handover to `pendingOwner` has been requested.\"},\"OwnershipTransferred(address,address)\":{\"details\":\"The ownership is transferred from `oldOwner` to `newOwner`. This event is intentionally kept the same as OpenZeppelin's Ownable to be compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173), despite it not being as lightweight as a single argument event.\"}},\"kind\":\"dev\",\"methods\":{\"cancelOwnershipHandover()\":{\"details\":\"Cancels the two-step ownership handover to the caller, if any.\"},\"completeOwnershipHandover(address)\":{\"details\":\"Allows the owner to complete the two-step ownership handover to `pendingOwner`. Reverts if there is no existing ownership handover requested by `pendingOwner`.\"},\"owner()\":{\"details\":\"Returns the owner of the contract.\"},\"ownershipHandoverExpiresAt(address)\":{\"details\":\"Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.\"},\"renounceOwnership()\":{\"details\":\"Allows the owner to renounce their ownership.\"},\"requestOwnershipHandover()\":{\"details\":\"Request a two-step ownership handover to the caller. The request will automatically expire in 48 hours (172800 seconds) by default.\"},\"transferOwnership(address)\":{\"details\":\"Allows the owner to transfer the ownership to `newOwner`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/Deployer.sol\":\"Deployer\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[\":@ERC4337/account-abstraction/=node_modules/account-abstraction/\",\":@biconomy-devx/=node_modules/@biconomy-devx/\",\":@erc7579/=node_modules/@erc7579/\",\":@gnosis.pm/=node_modules/@gnosis.pm/\",\":@modulekit/=node_modules/modulekit/src/\",\":@nexus/=node_modules/nexus/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@prb/math/=node_modules/erc7739-validator-base/node_modules/@prb/math/src/\",\":@prb/test/=node_modules/@prb/test/\",\":@rhinestone/=node_modules/@rhinestone/\",\":@safe-global/=node_modules/@safe-global/\",\":@uniswap/swap-router-contracts/contracts/=node_modules/@uniswap/swap-router-contracts/contracts/\",\":@uniswap/v3-core/contracts/=node_modules/@uniswap/v3-core/contracts/\",\":@uniswap/v3-periphery/contracts/=node_modules/@uniswap/v3-periphery/contracts/\",\":@zerodev/=node_modules/@zerodev/\",\":ExcessivelySafeCall/=node_modules/erc7739-validator-base/node_modules/excessively-safe-call/src/\",\":account-abstraction-v0.6/=node_modules/account-abstraction-v0.6/\",\":account-abstraction/=node_modules/account-abstraction/contracts/\",\":accountabstraction/=node_modules/accountabstraction/\",\":base64-sol/=node_modules/base64-sol/\",\":ds-test/=node_modules/ds-test/\",\":enumerableset4337/=node_modules/erc7739-validator-base/node_modules/@erc7579/enumerablemap4337/src/\",\":erc4337-validation/=node_modules/erc7739-validator-base/node_modules/@rhinestone/erc4337-validation/src/\",\":erc7579/=node_modules/erc7579/src/\",\":erc7739-validator-base/=node_modules/erc7739-validator-base/\",\":erc7739Validator/=node_modules/erc7739-validator-base/src/\",\":excessively-safe-call/=node_modules/excessively-safe-call/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=node_modules/hardhat-deploy/\",\":hardhat/=node_modules/hardhat/\",\":kernel/=node_modules/@zerodev/kernel/src/\",\":module-bases/=node_modules/module-bases/src/\",\":modulekit/=node_modules/@rhinestone/modulekit/src/\",\":nexus/=node_modules/nexus/\",\":registry/=node_modules/modulekit/node_modules/@rhinestone/registry/src/\",\":safe7579/=node_modules/erc7739-validator-base/node_modules/@rhinestone/safe7579/src/\",\":sentinellist/=node_modules/sentinellist/src/\",\":solady/=node_modules/solady/src/\",\":solady/src/=node_modules/solady/src/\",\":solarray/=node_modules/solarray/src/\"],\"viaIR\":true},\"sources\":{\"contracts/utils/Create3.sol\":{\"keccak256\":\"0xc878c1ed02e55355fa7e68e015944e9e2b8097ac6d28a1996e489504b6295c41\",\"license\":\"Unlicense\",\"urls\":[\"bzz-raw://7757231804e65ed9488dce0d4398cea9ea6ac986c908d3af030ca48e81772181\",\"dweb:/ipfs/QmSa2oj33ssAoG59gYkYHLwFFF3fij2M1H8bVbvFCunVvr\"]},\"contracts/utils/Deployer.sol\":{\"keccak256\":\"0xea1685a3cfa53acaa1bb943cd618a9b1fdb5f1cdf65363751b2d6fbdf4564875\",\"license\":\"Unlicense\",\"urls\":[\"bzz-raw://30ae88c7855e31815c1e77a9ba9ba12f4aee2426517ad02d5e07d5414a158ae4\",\"dweb:/ipfs/QmRZ1hDZL1eDA8srKfRamCtaDgZcPXeRRfsb1wy9HTXUDU\"]},\"contracts/utils/SoladyOwnable.sol\":{\"keccak256\":\"0xa8d7b45c34f96e24ae669cdc5add90088b8236a101cb36a7148b05c678d2f8ce\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://05d1686b40ce43c7ebb674c64ec6695c7822f3380954028c218bf59b64f8165d\",\"dweb:/ipfs/Qmc6Vr8Ru1EpupJ7gp6kmdPA5BqcoPY5GqF8ZLvMPzvBaX\"]},\"node_modules/solady/src/auth/Ownable.sol\":{\"keccak256\":\"0xc208cdd9de02bbf4b5edad18b88e23a2be7ff56d2287d5649329dc7cda64b9a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e8fba079cc7230c617f7493a2e97873f88e59a53a5018fcb2e2b6ac42d8aa5a3\",\"dweb:/ipfs/QmTXg8GSt8hsK2cZhbPFrund1mrwVdkLQmEPoQaFy4fhjs\"]},\"node_modules/solady/src/utils/ECDSA.sol\":{\"keccak256\":\"0x5a37fbc86ff99139e1cffad4ec05ffeeef17c1d1401113f107665d08a6abe7df\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4253a9d0cf4eab99f858fe798904f02ddaabfca3133c07a6314dc479ddd2e217\",\"dweb:/ipfs/QmXeK8yCQ8G4KsqkiP2Yewi2kPV9vdpUU9Qi1xcdX92p8v\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.27+commit.40a35a09"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"type":"error","name":"AlreadyInitialized"},{"inputs":[],"type":"error","name":"ErrorCreatingContract"},{"inputs":[],"type":"error","name":"ErrorCreatingProxy"},{"inputs":[],"type":"error","name":"InvalidBytecodeSignature"},{"inputs":[],"type":"error","name":"NewOwnerIsZeroAddress"},{"inputs":[],"type":"error","name":"NoHandoverRequest"},{"inputs":[],"type":"error","name":"TargetAlreadyExists"},{"inputs":[],"type":"error","name":"Unauthorized"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address","indexed":true}],"type":"event","name":"ContractDeployed","anonymous":false},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipHandoverCanceled","anonymous":false},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipHandoverRequested","anonymous":false},{"inputs":[{"internalType":"address","name":"oldOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferred","anonymous":false},{"inputs":[{"internalType":"bytes32","name":"_salt","type":"bytes32"}],"stateMutability":"view","type":"function","name":"addressOf","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"payable","type":"function","name":"cancelOwnershipHandover"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"stateMutability":"payable","type":"function","name":"completeOwnershipHandover"},{"inputs":[{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_creationCode","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"deploy","outputs":[{"internalType":"address","name":"deployedContract","type":"address"}]},{"inputs":[{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_creationCode","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"deploy","outputs":[{"internalType":"address","name":"deployedContract","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}]},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"stateMutability":"view","type":"function","name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}]},{"inputs":[],"stateMutability":"payable","type":"function","name":"renounceOwnership"},{"inputs":[],"stateMutability":"payable","type":"function","name":"requestOwnershipHandover"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"stateMutability":"payable","type":"function","name":"transferOwnership"}],"devdoc":{"kind":"dev","methods":{"cancelOwnershipHandover()":{"details":"Cancels the two-step ownership handover to the caller, if any."},"completeOwnershipHandover(address)":{"details":"Allows the owner to complete the two-step ownership handover to `pendingOwner`. Reverts if there is no existing ownership handover requested by `pendingOwner`."},"owner()":{"details":"Returns the owner of the contract."},"ownershipHandoverExpiresAt(address)":{"details":"Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`."},"renounceOwnership()":{"details":"Allows the owner to renounce their ownership."},"requestOwnershipHandover()":{"details":"Request a two-step ownership handover to the caller. The request will automatically expire in 48 hours (172800 seconds) by default."},"transferOwnership(address)":{"details":"Allows the owner to transfer the ownership to `newOwner`."}},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ERC4337/account-abstraction/=node_modules/account-abstraction/","@biconomy-devx/=node_modules/@biconomy-devx/","@erc7579/=node_modules/@erc7579/","@gnosis.pm/=node_modules/@gnosis.pm/","@modulekit/=node_modules/modulekit/src/","@nexus/=node_modules/nexus/","@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/","@prb/math/=node_modules/erc7739-validator-base/node_modules/@prb/math/src/","@prb/test/=node_modules/@prb/test/","@rhinestone/=node_modules/@rhinestone/","@safe-global/=node_modules/@safe-global/","@uniswap/swap-router-contracts/contracts/=node_modules/@uniswap/swap-router-contracts/contracts/","@uniswap/v3-core/contracts/=node_modules/@uniswap/v3-core/contracts/","@uniswap/v3-periphery/contracts/=node_modules/@uniswap/v3-periphery/contracts/","@zerodev/=node_modules/@zerodev/","ExcessivelySafeCall/=node_modules/erc7739-validator-base/node_modules/excessively-safe-call/src/","account-abstraction-v0.6/=node_modules/account-abstraction-v0.6/","account-abstraction/=node_modules/account-abstraction/contracts/","accountabstraction/=node_modules/accountabstraction/","base64-sol/=node_modules/base64-sol/","ds-test/=node_modules/ds-test/","enumerableset4337/=node_modules/erc7739-validator-base/node_modules/@erc7579/enumerablemap4337/src/","erc4337-validation/=node_modules/erc7739-validator-base/node_modules/@rhinestone/erc4337-validation/src/","erc7579/=node_modules/erc7579/src/","erc7739-validator-base/=node_modules/erc7739-validator-base/","erc7739Validator/=node_modules/erc7739-validator-base/src/","excessively-safe-call/=node_modules/excessively-safe-call/src/","forge-std/=lib/forge-std/src/","hardhat-deploy/=node_modules/hardhat-deploy/","hardhat/=node_modules/hardhat/","kernel/=node_modules/@zerodev/kernel/src/","module-bases/=node_modules/module-bases/src/","modulekit/=node_modules/@rhinestone/modulekit/src/","nexus/=node_modules/nexus/","registry/=node_modules/modulekit/node_modules/@rhinestone/registry/src/","safe7579/=node_modules/erc7739-validator-base/node_modules/@rhinestone/safe7579/src/","sentinellist/=node_modules/sentinellist/src/","solady/=node_modules/solady/src/","solady/src/=node_modules/solady/src/","solarray/=node_modules/solarray/src/"],"optimizer":{"enabled":true,"runs":800},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"contracts/utils/Deployer.sol":"Deployer"},"evmVersion":"cancun","libraries":{},"viaIR":true},"sources":{"contracts/utils/Create3.sol":{"keccak256":"0xc878c1ed02e55355fa7e68e015944e9e2b8097ac6d28a1996e489504b6295c41","urls":["bzz-raw://7757231804e65ed9488dce0d4398cea9ea6ac986c908d3af030ca48e81772181","dweb:/ipfs/QmSa2oj33ssAoG59gYkYHLwFFF3fij2M1H8bVbvFCunVvr"],"license":"Unlicense"},"contracts/utils/Deployer.sol":{"keccak256":"0xea1685a3cfa53acaa1bb943cd618a9b1fdb5f1cdf65363751b2d6fbdf4564875","urls":["bzz-raw://30ae88c7855e31815c1e77a9ba9ba12f4aee2426517ad02d5e07d5414a158ae4","dweb:/ipfs/QmRZ1hDZL1eDA8srKfRamCtaDgZcPXeRRfsb1wy9HTXUDU"],"license":"Unlicense"},"contracts/utils/SoladyOwnable.sol":{"keccak256":"0xa8d7b45c34f96e24ae669cdc5add90088b8236a101cb36a7148b05c678d2f8ce","urls":["bzz-raw://05d1686b40ce43c7ebb674c64ec6695c7822f3380954028c218bf59b64f8165d","dweb:/ipfs/Qmc6Vr8Ru1EpupJ7gp6kmdPA5BqcoPY5GqF8ZLvMPzvBaX"],"license":"MIT"},"node_modules/solady/src/auth/Ownable.sol":{"keccak256":"0xc208cdd9de02bbf4b5edad18b88e23a2be7ff56d2287d5649329dc7cda64b9a3","urls":["bzz-raw://e8fba079cc7230c617f7493a2e97873f88e59a53a5018fcb2e2b6ac42d8aa5a3","dweb:/ipfs/QmTXg8GSt8hsK2cZhbPFrund1mrwVdkLQmEPoQaFy4fhjs"],"license":"MIT"},"node_modules/solady/src/utils/ECDSA.sol":{"keccak256":"0x5a37fbc86ff99139e1cffad4ec05ffeeef17c1d1401113f107665d08a6abe7df","urls":["bzz-raw://4253a9d0cf4eab99f858fe798904f02ddaabfca3133c07a6314dc479ddd2e217","dweb:/ipfs/QmXeK8yCQ8G4KsqkiP2Yewi2kPV9vdpUU9Qi1xcdX92p8v"],"license":"MIT"}},"version":1},"id":5} \ No newline at end of file +{"abi":[{"type":"constructor","inputs":[{"name":"_owner","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"addressOf","inputs":[{"name":"_salt","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"cancelOwnershipHandover","inputs":[],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"completeOwnershipHandover","inputs":[{"name":"pendingOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"deploy","inputs":[{"name":"_salt","type":"bytes32","internalType":"bytes32"},{"name":"_creationCode","type":"bytes","internalType":"bytes"},{"name":"signature","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"deployedContract","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"deploy","inputs":[{"name":"_salt","type":"bytes32","internalType":"bytes32"},{"name":"_creationCode","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"deployedContract","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"result","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"ownershipHandoverExpiresAt","inputs":[{"name":"pendingOwner","type":"address","internalType":"address"}],"outputs":[{"name":"result","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"requestOwnershipHandover","inputs":[],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"type":"event","name":"ContractDeployed","inputs":[{"name":"contractAddress","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipHandoverCanceled","inputs":[{"name":"pendingOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipHandoverRequested","inputs":[{"name":"pendingOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"oldOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"error","name":"AlreadyInitialized","inputs":[]},{"type":"error","name":"ErrorCreatingContract","inputs":[]},{"type":"error","name":"ErrorCreatingProxy","inputs":[]},{"type":"error","name":"InvalidBytecodeSignature","inputs":[]},{"type":"error","name":"NewOwnerIsZeroAddress","inputs":[]},{"type":"error","name":"NoHandoverRequest","inputs":[]},{"type":"error","name":"TargetAlreadyExists","inputs":[]},{"type":"error","name":"Unauthorized","inputs":[]}],"bytecode":{"object":"0x34605f57610984388190036080601f8201601f19168101906001600160401b03821190821017606357602092829160405260803912605f576080516001600160a01b0381168103605f576050906077565b6040516108be90816100c68239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b8060601b1560b8576001600160a01b0316638b78c6d8198190555f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a3565b637448fbae5f526004601cfdfe60806040526004361015610011575f80fd5b5f3560e01c806319cdeff1146100b457806325692962146100af57806354d1f13d146100aa578063715018a6146100a55780638da5cb5b146100a0578063bb34534c1461009b578063cdcb760a14610096578063f04e283e14610091578063f2fde38b1461008c5763fee81cf414610087575f80fd5b6104de565b6104ae565b61046a565b61032e565b6102ff565b6102d5565b61028c565b610248565b6101ff565b346101cd5760603660031901126101cd5760043560243567ffffffffffffffff81116101cd576100e89036906004016101d1565b9160443567ffffffffffffffff81116101cd5761015461010f6101589236906004016101d1565b90606060a05286610100528686610120375f61012088015261014960a0601f19601f8a01168760c0524660e0526080810160805201610519565b60805160a0206105b5565b1590565b6101be5761016e610174926101ba94369161057f565b90610850565b60405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b0390f35b6306f691ef60e51b5f5260045ffd5b5f80fd5b9181601f840112156101cd5782359167ffffffffffffffff83116101cd57602083818601950101116101cd57565b5f3660031901126101cd5763389a75e1600c52335f526202a30042016020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a2005b5f3660031901126101cd5763389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2005b5f3660031901126101cd5761029f61062b565b5f638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a35f638b78c6d81955005b346101cd575f3660031901126101cd576020638b78c6d819546001600160a01b0360405191168152f35b346101cd5760203660031901126101cd57602061031d600435610685565b6001600160a01b0360405191168152f35b346101cd5760403660031901126101cd5760043560243567ffffffffffffffff81116101cd576103656103749136906004016101d1565b61036d61062b565b369161057f565b61037c6107e6565b9161038681610685565b92833b610439576020815191015ff56001600160a01b0381161561042a57815f92918360208194519301915af16103bb610821565b50158015610421575b610412576101ba9060405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b6353de54b960e01b5f5260045ffd5b50803b156103c4565b63bbd2fe8760e01b5f5260045ffd5b63cd43efa160e01b5f5260045ffd5b60209060031901126101cd576004356001600160a01b03811681036101cd5790565b61047336610448565b61047b61062b565b63389a75e1600c52805f526020600c2090815442116104a1575f61049f9255610647565b005b636f5e88185f526004601cfd5b6104b736610448565b6104bf61062b565b8060601b156104d15761049f90610647565b637448fbae5f526004601cfd5b346101cd576104ec36610448565b63389a75e1600c525f52602080600c2054604051908152f35b634e487b7160e01b5f52604160045260245ffd5b601f80199101166080016080811067ffffffffffffffff82111761053c57604052565b610505565b90601f8019910116810190811067ffffffffffffffff82111761053c57604052565b67ffffffffffffffff811161053c57601f01601f191660200190565b92919261058b82610563565b916105996040519384610541565b8294818452818301116101cd578281602093845f960137010152565b6001600160a01b03926105c981848461074b565b638b78c6d81954851694168414610622576001600160a01b0392610613926020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c60042061074b565b161461061d575f90565b600190565b50505050600190565b638b78c6d81954330361063a57565b6382b429005f526004601cfd5b6001600160a01b031680638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3638b78c6d81955565b61073c6001600160a01b0361074892604051602081019160ff60f81b83523060601b602183015260358201527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6055820152605581526106e6607582610541565b5190206040516135a560f21b602082019081529290911660601b6bffffffffffffffffffffffff19166022820152600160f81b60368201526017815261072d603782610541565b5190206001600160a01b031690565b6001600160a01b031690565b90565b9092919260405193806040146107a65760411461077457505050505b638baa579f5f526004601cfd5b806040809201355f1a60205281375b5f526020600160805f825afa51915f6060526040523d6107a4575050610767565b565b508060207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92013590601b8260ff1c016020523560405216606052610783565b604051906107f5604083610541565b601082527f67363d3d37363d34f03d5260086018f3000000000000000000000000000000006020830152565b3d1561084b573d9061083282610563565b916108406040519384610541565b82523d5f602084013e565b606090565b919061085a6107e6565b9261086481610685565b93843b610439576020815191015ff56001600160a01b0381161561042a57815f92918360208194519301915af1610899610821565b501580156108a8575b61041257565b50813b156108a256fea164736f6c634300081b000a","sourceMap":"163:1333:1:-:0;;;;;;;;;;;;-1:-1:-1;;163:1333:1;;;;-1:-1:-1;;;;;163:1333:1;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;163:1333:1;;;;;;334:52;;;:::i;:::-;163:1333;;;;;;;;;;-1:-1:-1;163:1333:1;;;;;;-1:-1:-1;163:1333:1;;;;;-1:-1:-1;163:1333:1;150:269:2;198:181;;;;;;-1:-1:-1;;;;;5710:347:22;-1:-1:-1;;5710:347:22;;;-1:-1:-1;5710:347:22;-1:-1:-1;;5710:347:22;150:269:2:o;198:181::-;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x60806040526004361015610011575f80fd5b5f3560e01c806319cdeff1146100b457806325692962146100af57806354d1f13d146100aa578063715018a6146100a55780638da5cb5b146100a0578063bb34534c1461009b578063cdcb760a14610096578063f04e283e14610091578063f2fde38b1461008c5763fee81cf414610087575f80fd5b6104de565b6104ae565b61046a565b61032e565b6102ff565b6102d5565b61028c565b610248565b6101ff565b346101cd5760603660031901126101cd5760043560243567ffffffffffffffff81116101cd576100e89036906004016101d1565b9160443567ffffffffffffffff81116101cd5761015461010f6101589236906004016101d1565b90606060a05286610100528686610120375f61012088015261014960a0601f19601f8a01168760c0524660e0526080810160805201610519565b60805160a0206105b5565b1590565b6101be5761016e610174926101ba94369161057f565b90610850565b60405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b0390f35b6306f691ef60e51b5f5260045ffd5b5f80fd5b9181601f840112156101cd5782359167ffffffffffffffff83116101cd57602083818601950101116101cd57565b5f3660031901126101cd5763389a75e1600c52335f526202a30042016020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a2005b5f3660031901126101cd5763389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2005b5f3660031901126101cd5761029f61062b565b5f638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a35f638b78c6d81955005b346101cd575f3660031901126101cd576020638b78c6d819546001600160a01b0360405191168152f35b346101cd5760203660031901126101cd57602061031d600435610685565b6001600160a01b0360405191168152f35b346101cd5760403660031901126101cd5760043560243567ffffffffffffffff81116101cd576103656103749136906004016101d1565b61036d61062b565b369161057f565b61037c6107e6565b9161038681610685565b92833b610439576020815191015ff56001600160a01b0381161561042a57815f92918360208194519301915af16103bb610821565b50158015610421575b610412576101ba9060405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b6353de54b960e01b5f5260045ffd5b50803b156103c4565b63bbd2fe8760e01b5f5260045ffd5b63cd43efa160e01b5f5260045ffd5b60209060031901126101cd576004356001600160a01b03811681036101cd5790565b61047336610448565b61047b61062b565b63389a75e1600c52805f526020600c2090815442116104a1575f61049f9255610647565b005b636f5e88185f526004601cfd5b6104b736610448565b6104bf61062b565b8060601b156104d15761049f90610647565b637448fbae5f526004601cfd5b346101cd576104ec36610448565b63389a75e1600c525f52602080600c2054604051908152f35b634e487b7160e01b5f52604160045260245ffd5b601f80199101166080016080811067ffffffffffffffff82111761053c57604052565b610505565b90601f8019910116810190811067ffffffffffffffff82111761053c57604052565b67ffffffffffffffff811161053c57601f01601f191660200190565b92919261058b82610563565b916105996040519384610541565b8294818452818301116101cd578281602093845f960137010152565b6001600160a01b03926105c981848461074b565b638b78c6d81954851694168414610622576001600160a01b0392610613926020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c60042061074b565b161461061d575f90565b600190565b50505050600190565b638b78c6d81954330361063a57565b6382b429005f526004601cfd5b6001600160a01b031680638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3638b78c6d81955565b61073c6001600160a01b0361074892604051602081019160ff60f81b83523060601b602183015260358201527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6055820152605581526106e6607582610541565b5190206040516135a560f21b602082019081529290911660601b6bffffffffffffffffffffffff19166022820152600160f81b60368201526017815261072d603782610541565b5190206001600160a01b031690565b6001600160a01b031690565b90565b9092919260405193806040146107a65760411461077457505050505b638baa579f5f526004601cfd5b806040809201355f1a60205281375b5f526020600160805f825afa51915f6060526040523d6107a4575050610767565b565b508060207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92013590601b8260ff1c016020523560405216606052610783565b604051906107f5604083610541565b601082527f67363d3d37363d34f03d5260086018f3000000000000000000000000000000006020830152565b3d1561084b573d9061083282610563565b916108406040519384610541565b82523d5f602084013e565b606090565b919061085a6107e6565b9261086481610685565b93843b610439576020815191015ff56001600160a01b0381161561042a57815f92918360208194519301915af1610899610821565b501580156108a8575b61041257565b50813b156108a256fea164736f6c634300081b000a","sourceMap":"163:1333:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;;;;;-1:-1:-1;;163:1333:1;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;621:33;163:1333;620:34;163:1333;;;;;;:::i;:::-;;;558:47;163:1333;;;;;;;;;;;;;558:47;;163:1333;;;;;;;;;591:13;163:1333;;;558:47;;163:1333;558:47;;;:::i;:::-;163:1333;;558:47;548:58;621:33;:::i;:::-;620:34;;163:1333;620:34;616:73;;163:1333;2628:32:0;163:1333:1;;;;;;:::i;:::-;2628:32:0;;:::i;:::-;163:1333:1;;;;-1:-1:-1;;;;;163:1333:1;;;770:34;163:1333;770:34;;-1:-1:-1;;;;;163:1333:1;;;;;;;;;;;;616:73;663:26;;;163:1333;663:26;163:1333;;663:26;163:1333;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;163:1333:1;;;;9239:383:22;;;;163:1333:1;9239:383:22;7972:9;9132:15;163:1333:1;9239:383:22;;;;;;163:1333:1;9239:383:22;;163:1333:1;;;;-1:-1:-1;;163:1333:1;;;;9831:339:22;;;;163:1333:1;9831:339:22;163:1333:1;9831:339:22;;;;;;163:1333:1;9831:339:22;;163:1333:1;;;;-1:-1:-1;;163:1333:1;;;;12478:70:22;;:::i;:::-;163:1333:1;6813:405:22;;;;;;;163:1333:1;-1:-1:-1;;6813:405:22;163:1333:1;;;;;;;-1:-1:-1;;163:1333:1;;;;;6813:405:22;;11523:61;-1:-1:-1;;;;;163:1333:1;;;;;;;;;;;;;-1:-1:-1;;163:1333:1;;;;;1146:24;163:1333;;1146:24;:::i;:::-;-1:-1:-1;;;;;163:1333:1;;;;;;;;;;;;;-1:-1:-1;;163:1333:1;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12478:70:22;;:::i;:::-;163:1333:1;;;:::i;:::-;;;:::i;:::-;3399:16:0;;;;:::i;:::-;2041:59;;;3425:53;;163:1333:1;3544:181:0;;;;-1:-1:-1;3544:181:0;-1:-1:-1;;;;;163:1333:1;;3738:19:0;3734:52;;3859:40;-1:-1:-1;3859:40:0;;;163:1333:1;3859:40:0;;;;;;;;;;:::i;:::-;;3913:8;163:1333:1;;3913:31:0;;163:1333:1;3909:67:0;;163:1333:1;;;;;;-1:-1:-1;;;;;163:1333:1;;;1016:34;-1:-1:-1;1016:34:1;;-1:-1:-1;;;;;163:1333:1;;;;;;;;3909:67:0;3953:23;;;-1:-1:-1;3953:23:0;163:1333:1;-1:-1:-1;3953:23:0;3913:31;2041:59;;;3925:19;3913:31;;3734:52;3766:20;;;-1:-1:-1;3766:20:0;163:1333:1;-1:-1:-1;3766:20:0;3425:53;3457:21;;;-1:-1:-1;3457:21:0;163:1333:1;-1:-1:-1;3457:21:0;163:1333:1;;;;;;;;;;;-1:-1:-1;;;;;163:1333:1;;;;;;;:::o;:::-;;;;:::i;:::-;12478:70:22;;:::i;:::-;10506:526;;;;;;;;;;;;;;;;;11051:12;10506:526;;11051:12;:::i;:::-;163:1333:1;10506:526:22;;;;163:1333:1;10506:526:22;;163:1333:1;;;;:::i;:::-;12478:70:22;;:::i;:::-;8479:183;;;;;;8681:8;;;:::i;8479:183::-;;;;163:1333:1;8479:183:22;;163:1333:1;;;;;;;:::i;:::-;11885:237:22;;;-1:-1:-1;11885:237:22;;;;;;163:1333:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;-1:-1:-1;;163:1333:1;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;163:1333:1;;;;;;:::o;1183:311::-;-1:-1:-1;;;;;1183:311:1;1292:31;;;;;:::i;:::-;-1:-1:-1;;11523:61:22;163:1333:1;;;;1292:42;;1288:71;;-1:-1:-1;;;;;13414:265:23;1373:56:1;13414:265:23;;;;163:1333:1;13414:265:23;;;;1373:56:1;:::i;:::-;163:1333;1373:67;1369:96;;163:1333;1183:311;:::o;1369:96::-;1461:4;1454:11;:::o;1288:71::-;1348:11;;;;1355:4;1348:11;:::o;7292:355:22:-;-1:-1:-1;;7390:251:22;;;;;7292:355::o;7390:251::-;;;;;;;6145:1089;-1:-1:-1;;;;;6813:405:22;;;;;;-1:-1:-1;6813:405:22;;-1:-1:-1;;6813:405:22;6145:1089::o;4973:345:0:-;5140:157;-1:-1:-1;;;;;5115:196:0;4973:345;163:1333:1;;4215:237:0;;;1707:66;;;;;;4314:4;163:1333:1;;1707:66:0;;;163:1333:1;1707:66:0;;;163:1333:1;1707:66:0;;;;163:1333:1;1707:66:0;4215:237;;;;;;:::i;:::-;163:1333:1;4176:302:0;;163:1333:1;;-1:-1:-1;;;4215:237:0;5212:44;;163:1333:1;;;;;;;;;-1:-1:-1;;163:1333:1;;;;;-1:-1:-1;;;163:1333:1;;;;;5212:44:0;;;163:1333:1;;5212:44:0;:::i;:::-;163:1333:1;5202:55:0;;-1:-1:-1;;;;;163:1333:1;;;5140:157:0;-1:-1:-1;;;;;163:1333:1;;;5115:196:0;4973:345;:::o;4336:1373:23:-;;;;;4521:1182;;;;;;;;;;;;;;;;;;163:1333:1;4521:1182:23;;;;;;;;;;;163:1333:1;4521:1182:23;;;;;;163:1333:1;4521:1182:23;;;;163:1333:1;4521:1182:23;;;;;163:1333:1;4521:1182:23;;;;;;;;;;;;4336:1373::o;4521:1182::-;;;;;;;;;;;;;;;;;;;;;;;;163:1333:1;;;;;;;;:::i;:::-;;;;;;;;;:::o;1485:52:0:-;;;;;;163:1333:1;;;;:::i;:::-;;;;;;;;:::i;:::-;;;1485:52:0;-1:-1:-1;1485:52:0;;;;:::o;:::-;;;:::o;3124:859::-;;;163:1333:1;;:::i;:::-;3399:16:0;;;;:::i;:::-;2041:59;;;3425:53;;3544:181;;;;;163:1333:1;3544:181:0;-1:-1:-1;;;;;163:1333:1;;3738:19:0;3734:52;;3859:40;163:1333:1;3859:40:0;;;3544:181;3859:40;;;;;;;;;;:::i;:::-;;3913:8;163:1333:1;;3913:31:0;;3124:859;3909:67;;3124:859::o;3913:31::-;2041:59;;;3925:19;3913:31;","linkReferences":{}},"methodIdentifiers":{"addressOf(bytes32)":"bb34534c","cancelOwnershipHandover()":"54d1f13d","completeOwnershipHandover(address)":"f04e283e","deploy(bytes32,bytes)":"cdcb760a","deploy(bytes32,bytes,bytes)":"19cdeff1","owner()":"8da5cb5b","ownershipHandoverExpiresAt(address)":"fee81cf4","renounceOwnership()":"715018a6","requestOwnershipHandover()":"25692962","transferOwnership(address)":"f2fde38b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.27+commit.40a35a09\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ErrorCreatingContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ErrorCreatingProxy\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBytecodeSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewOwnerIsZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoHandoverRequest\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TargetAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"}],\"name\":\"ContractDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pendingOwner\",\"type\":\"address\"}],\"name\":\"OwnershipHandoverCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pendingOwner\",\"type\":\"address\"}],\"name\":\"OwnershipHandoverRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_salt\",\"type\":\"bytes32\"}],\"name\":\"addressOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"cancelOwnershipHandover\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pendingOwner\",\"type\":\"address\"}],\"name\":\"completeOwnershipHandover\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_creationCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"deploy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"deployedContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_creationCode\",\"type\":\"bytes\"}],\"name\":\"deploy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"deployedContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"result\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pendingOwner\",\"type\":\"address\"}],\"name\":\"ownershipHandoverExpiresAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"requestOwnershipHandover\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"Cannot double-initialize.\"}],\"NewOwnerIsZeroAddress()\":[{\"details\":\"The `newOwner` cannot be the zero address.\"}],\"NoHandoverRequest()\":[{\"details\":\"The `pendingOwner` does not have a valid handover request.\"}],\"Unauthorized()\":[{\"details\":\"The caller is not authorized to call the function.\"}]},\"events\":{\"OwnershipHandoverCanceled(address)\":{\"details\":\"The ownership handover to `pendingOwner` has been canceled.\"},\"OwnershipHandoverRequested(address)\":{\"details\":\"An ownership handover to `pendingOwner` has been requested.\"},\"OwnershipTransferred(address,address)\":{\"details\":\"The ownership is transferred from `oldOwner` to `newOwner`. This event is intentionally kept the same as OpenZeppelin's Ownable to be compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173), despite it not being as lightweight as a single argument event.\"}},\"kind\":\"dev\",\"methods\":{\"cancelOwnershipHandover()\":{\"details\":\"Cancels the two-step ownership handover to the caller, if any.\"},\"completeOwnershipHandover(address)\":{\"details\":\"Allows the owner to complete the two-step ownership handover to `pendingOwner`. Reverts if there is no existing ownership handover requested by `pendingOwner`.\"},\"owner()\":{\"details\":\"Returns the owner of the contract.\"},\"ownershipHandoverExpiresAt(address)\":{\"details\":\"Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.\"},\"renounceOwnership()\":{\"details\":\"Allows the owner to renounce their ownership.\"},\"requestOwnershipHandover()\":{\"details\":\"Request a two-step ownership handover to the caller. The request will automatically expire in 48 hours (172800 seconds) by default.\"},\"transferOwnership(address)\":{\"details\":\"Allows the owner to transfer the ownership to `newOwner`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/Deployer.sol\":\"Deployer\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[\":@ERC4337/account-abstraction/=node_modules/account-abstraction/\",\":@biconomy-devx/=node_modules/@biconomy-devx/\",\":@erc7579/=node_modules/@erc7579/\",\":@gnosis.pm/=node_modules/@gnosis.pm/\",\":@modulekit/=node_modules/modulekit/src/\",\":@nexus/=node_modules/nexus/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@prb/math/=node_modules/erc7739-validator-base/node_modules/@prb/math/src/\",\":@prb/test/=node_modules/@prb/test/\",\":@rhinestone/=node_modules/@rhinestone/\",\":@safe-global/=node_modules/@safe-global/\",\":@uniswap/swap-router-contracts/contracts/=node_modules/@uniswap/swap-router-contracts/contracts/\",\":@uniswap/v3-core/contracts/=node_modules/@uniswap/v3-core/contracts/\",\":@uniswap/v3-periphery/contracts/=node_modules/@uniswap/v3-periphery/contracts/\",\":@zerodev/=node_modules/@zerodev/\",\":ExcessivelySafeCall/=node_modules/erc7739-validator-base/node_modules/excessively-safe-call/src/\",\":account-abstraction-v0.6/=node_modules/account-abstraction-v0.6/\",\":account-abstraction/=node_modules/account-abstraction/contracts/\",\":accountabstraction/=node_modules/accountabstraction/\",\":base64-sol/=node_modules/base64-sol/\",\":ds-test/=node_modules/ds-test/\",\":enumerableset4337/=node_modules/erc7739-validator-base/node_modules/@erc7579/enumerablemap4337/src/\",\":erc4337-validation/=node_modules/erc7739-validator-base/node_modules/@rhinestone/erc4337-validation/src/\",\":erc7579/=node_modules/erc7579/src/\",\":erc7739-validator-base/=node_modules/erc7739-validator-base/\",\":erc7739Validator/=node_modules/erc7739-validator-base/src/\",\":excessively-safe-call/=node_modules/excessively-safe-call/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=node_modules/hardhat-deploy/\",\":hardhat/=node_modules/hardhat/\",\":kernel/=node_modules/@zerodev/kernel/src/\",\":module-bases/=node_modules/module-bases/src/\",\":modulekit/=node_modules/@rhinestone/modulekit/src/\",\":nexus/=node_modules/nexus/\",\":registry/=node_modules/modulekit/node_modules/@rhinestone/registry/src/\",\":safe7579/=node_modules/erc7739-validator-base/node_modules/@rhinestone/safe7579/src/\",\":sentinellist/=node_modules/sentinellist/src/\",\":solady/=node_modules/solady/src/\",\":solady/src/=node_modules/solady/src/\",\":solarray/=node_modules/solarray/src/\"],\"viaIR\":true},\"sources\":{\"contracts/utils/Create3.sol\":{\"keccak256\":\"0xc878c1ed02e55355fa7e68e015944e9e2b8097ac6d28a1996e489504b6295c41\",\"license\":\"Unlicense\",\"urls\":[\"bzz-raw://7757231804e65ed9488dce0d4398cea9ea6ac986c908d3af030ca48e81772181\",\"dweb:/ipfs/QmSa2oj33ssAoG59gYkYHLwFFF3fij2M1H8bVbvFCunVvr\"]},\"contracts/utils/Deployer.sol\":{\"keccak256\":\"0xd09834408486dc70eaef5b0a12abc37d44ca6f300a061bece1e66758021a6d95\",\"license\":\"Unlicense\",\"urls\":[\"bzz-raw://4867cb95d29fa3a8ef99c63667f050c3fc2e83d76a5e158cb2c911b1f39fb3a1\",\"dweb:/ipfs/QmXYc3HkwgUy52tqkWpGJT5YvRj4Sogx2FWE8UHgHjYmKk\"]},\"contracts/utils/SoladyOwnable.sol\":{\"keccak256\":\"0xa8d7b45c34f96e24ae669cdc5add90088b8236a101cb36a7148b05c678d2f8ce\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://05d1686b40ce43c7ebb674c64ec6695c7822f3380954028c218bf59b64f8165d\",\"dweb:/ipfs/Qmc6Vr8Ru1EpupJ7gp6kmdPA5BqcoPY5GqF8ZLvMPzvBaX\"]},\"node_modules/solady/src/auth/Ownable.sol\":{\"keccak256\":\"0xc208cdd9de02bbf4b5edad18b88e23a2be7ff56d2287d5649329dc7cda64b9a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e8fba079cc7230c617f7493a2e97873f88e59a53a5018fcb2e2b6ac42d8aa5a3\",\"dweb:/ipfs/QmTXg8GSt8hsK2cZhbPFrund1mrwVdkLQmEPoQaFy4fhjs\"]},\"node_modules/solady/src/utils/ECDSA.sol\":{\"keccak256\":\"0x5a37fbc86ff99139e1cffad4ec05ffeeef17c1d1401113f107665d08a6abe7df\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4253a9d0cf4eab99f858fe798904f02ddaabfca3133c07a6314dc479ddd2e217\",\"dweb:/ipfs/QmXeK8yCQ8G4KsqkiP2Yewi2kPV9vdpUU9Qi1xcdX92p8v\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.27+commit.40a35a09"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"type":"error","name":"AlreadyInitialized"},{"inputs":[],"type":"error","name":"ErrorCreatingContract"},{"inputs":[],"type":"error","name":"ErrorCreatingProxy"},{"inputs":[],"type":"error","name":"InvalidBytecodeSignature"},{"inputs":[],"type":"error","name":"NewOwnerIsZeroAddress"},{"inputs":[],"type":"error","name":"NoHandoverRequest"},{"inputs":[],"type":"error","name":"TargetAlreadyExists"},{"inputs":[],"type":"error","name":"Unauthorized"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address","indexed":true}],"type":"event","name":"ContractDeployed","anonymous":false},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipHandoverCanceled","anonymous":false},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipHandoverRequested","anonymous":false},{"inputs":[{"internalType":"address","name":"oldOwner","type":"address","indexed":true},{"internalType":"address","name":"newOwner","type":"address","indexed":true}],"type":"event","name":"OwnershipTransferred","anonymous":false},{"inputs":[{"internalType":"bytes32","name":"_salt","type":"bytes32"}],"stateMutability":"view","type":"function","name":"addressOf","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"payable","type":"function","name":"cancelOwnershipHandover"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"stateMutability":"payable","type":"function","name":"completeOwnershipHandover"},{"inputs":[{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_creationCode","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"deploy","outputs":[{"internalType":"address","name":"deployedContract","type":"address"}]},{"inputs":[{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_creationCode","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"deploy","outputs":[{"internalType":"address","name":"deployedContract","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}]},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"stateMutability":"view","type":"function","name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}]},{"inputs":[],"stateMutability":"payable","type":"function","name":"renounceOwnership"},{"inputs":[],"stateMutability":"payable","type":"function","name":"requestOwnershipHandover"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"stateMutability":"payable","type":"function","name":"transferOwnership"}],"devdoc":{"kind":"dev","methods":{"cancelOwnershipHandover()":{"details":"Cancels the two-step ownership handover to the caller, if any."},"completeOwnershipHandover(address)":{"details":"Allows the owner to complete the two-step ownership handover to `pendingOwner`. Reverts if there is no existing ownership handover requested by `pendingOwner`."},"owner()":{"details":"Returns the owner of the contract."},"ownershipHandoverExpiresAt(address)":{"details":"Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`."},"renounceOwnership()":{"details":"Allows the owner to renounce their ownership."},"requestOwnershipHandover()":{"details":"Request a two-step ownership handover to the caller. The request will automatically expire in 48 hours (172800 seconds) by default."},"transferOwnership(address)":{"details":"Allows the owner to transfer the ownership to `newOwner`."}},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ERC4337/account-abstraction/=node_modules/account-abstraction/","@biconomy-devx/=node_modules/@biconomy-devx/","@erc7579/=node_modules/@erc7579/","@gnosis.pm/=node_modules/@gnosis.pm/","@modulekit/=node_modules/modulekit/src/","@nexus/=node_modules/nexus/","@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/","@prb/math/=node_modules/erc7739-validator-base/node_modules/@prb/math/src/","@prb/test/=node_modules/@prb/test/","@rhinestone/=node_modules/@rhinestone/","@safe-global/=node_modules/@safe-global/","@uniswap/swap-router-contracts/contracts/=node_modules/@uniswap/swap-router-contracts/contracts/","@uniswap/v3-core/contracts/=node_modules/@uniswap/v3-core/contracts/","@uniswap/v3-periphery/contracts/=node_modules/@uniswap/v3-periphery/contracts/","@zerodev/=node_modules/@zerodev/","ExcessivelySafeCall/=node_modules/erc7739-validator-base/node_modules/excessively-safe-call/src/","account-abstraction-v0.6/=node_modules/account-abstraction-v0.6/","account-abstraction/=node_modules/account-abstraction/contracts/","accountabstraction/=node_modules/accountabstraction/","base64-sol/=node_modules/base64-sol/","ds-test/=node_modules/ds-test/","enumerableset4337/=node_modules/erc7739-validator-base/node_modules/@erc7579/enumerablemap4337/src/","erc4337-validation/=node_modules/erc7739-validator-base/node_modules/@rhinestone/erc4337-validation/src/","erc7579/=node_modules/erc7579/src/","erc7739-validator-base/=node_modules/erc7739-validator-base/","erc7739Validator/=node_modules/erc7739-validator-base/src/","excessively-safe-call/=node_modules/excessively-safe-call/src/","forge-std/=lib/forge-std/src/","hardhat-deploy/=node_modules/hardhat-deploy/","hardhat/=node_modules/hardhat/","kernel/=node_modules/@zerodev/kernel/src/","module-bases/=node_modules/module-bases/src/","modulekit/=node_modules/@rhinestone/modulekit/src/","nexus/=node_modules/nexus/","registry/=node_modules/modulekit/node_modules/@rhinestone/registry/src/","safe7579/=node_modules/erc7739-validator-base/node_modules/@rhinestone/safe7579/src/","sentinellist/=node_modules/sentinellist/src/","solady/=node_modules/solady/src/","solady/src/=node_modules/solady/src/","solarray/=node_modules/solarray/src/"],"optimizer":{"enabled":true,"runs":800},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"contracts/utils/Deployer.sol":"Deployer"},"evmVersion":"cancun","libraries":{},"viaIR":true},"sources":{"contracts/utils/Create3.sol":{"keccak256":"0xc878c1ed02e55355fa7e68e015944e9e2b8097ac6d28a1996e489504b6295c41","urls":["bzz-raw://7757231804e65ed9488dce0d4398cea9ea6ac986c908d3af030ca48e81772181","dweb:/ipfs/QmSa2oj33ssAoG59gYkYHLwFFF3fij2M1H8bVbvFCunVvr"],"license":"Unlicense"},"contracts/utils/Deployer.sol":{"keccak256":"0xd09834408486dc70eaef5b0a12abc37d44ca6f300a061bece1e66758021a6d95","urls":["bzz-raw://4867cb95d29fa3a8ef99c63667f050c3fc2e83d76a5e158cb2c911b1f39fb3a1","dweb:/ipfs/QmXYc3HkwgUy52tqkWpGJT5YvRj4Sogx2FWE8UHgHjYmKk"],"license":"Unlicense"},"contracts/utils/SoladyOwnable.sol":{"keccak256":"0xa8d7b45c34f96e24ae669cdc5add90088b8236a101cb36a7148b05c678d2f8ce","urls":["bzz-raw://05d1686b40ce43c7ebb674c64ec6695c7822f3380954028c218bf59b64f8165d","dweb:/ipfs/Qmc6Vr8Ru1EpupJ7gp6kmdPA5BqcoPY5GqF8ZLvMPzvBaX"],"license":"MIT"},"node_modules/solady/src/auth/Ownable.sol":{"keccak256":"0xc208cdd9de02bbf4b5edad18b88e23a2be7ff56d2287d5649329dc7cda64b9a3","urls":["bzz-raw://e8fba079cc7230c617f7493a2e97873f88e59a53a5018fcb2e2b6ac42d8aa5a3","dweb:/ipfs/QmTXg8GSt8hsK2cZhbPFrund1mrwVdkLQmEPoQaFy4fhjs"],"license":"MIT"},"node_modules/solady/src/utils/ECDSA.sol":{"keccak256":"0x5a37fbc86ff99139e1cffad4ec05ffeeef17c1d1401113f107665d08a6abe7df","urls":["bzz-raw://4253a9d0cf4eab99f858fe798904f02ddaabfca3133c07a6314dc479ddd2e217","dweb:/ipfs/QmXeK8yCQ8G4KsqkiP2Yewi2kPV9vdpUU9Qi1xcdX92p8v"],"license":"MIT"}},"version":1},"id":1} \ No newline at end of file diff --git a/scripts/bash-deploy/artifacts/Deployer/verify.json b/scripts/bash-deploy/artifacts/Deployer/verify.json new file mode 100644 index 0000000..c30f459 --- /dev/null +++ b/scripts/bash-deploy/artifacts/Deployer/verify.json @@ -0,0 +1 @@ +{"language":"Solidity","sources":{"contracts/utils/Deployer.sol":{"content":"//SPDX-License-Identifier: Unlicense\npragma solidity 0.8.27;\n\nimport \"./Create3.sol\";\nimport \"./SoladyOwnable.sol\";\nimport {ECDSA} from \"solady/utils/ECDSA.sol\";\n\ncontract Deployer is SoladyOwnable {\n event ContractDeployed(address indexed contractAddress);\n error InvalidBytecodeSignature();\n\n using ECDSA for bytes32;\n\n constructor(address _owner) SoladyOwnable(_owner) {}\n\n function deploy(bytes32 _salt, bytes calldata _creationCode, bytes calldata signature) external returns (address deployedContract) {\n bytes32 hash = keccak256(abi.encode(_creationCode, _salt, block.chainid));\n if (!_verifySignature(hash, signature)) revert InvalidBytecodeSignature();\n deployedContract = Create3.create3(_salt, _creationCode);\n emit ContractDeployed(deployedContract);\n }\n\n function deploy(bytes32 _salt, bytes calldata _creationCode) onlyOwner external returns (address deployedContract) { \n deployedContract = Create3.create3(_salt, _creationCode);\n emit ContractDeployed(deployedContract);\n }\n\n function addressOf(bytes32 _salt) external view returns (address) {\n return Create3.addressOf(_salt);\n }\n\n function _verifySignature(bytes32 hash, bytes calldata signature) internal view returns (bool) {\n if (hash.recoverCalldata(signature) == owner())\n return true;\n if (hash.toEthSignedMessageHash().recoverCalldata(signature) == owner())\n return true;\n return false;\n }\n}\n"},"contracts/utils/Create3.sol":{"content":"//SPDX-License-Identifier: Unlicense\npragma solidity 0.8.27;\n\n/**\n @title A library for deploying contracts EIP-3171 style.\n @author Agustin Aguilar \n*/\nlibrary Create3 {\n error ErrorCreatingProxy();\n error ErrorCreatingContract();\n error TargetAlreadyExists();\n\n /**\n @notice The bytecode for a contract that proxies the creation of another contract\n @dev If this code is deployed using CREATE2 it can be used to decouple `creationCode` from the child contract address\n\n 0x67363d3d37363d34f03d5260086018f3:\n 0x00 0x67 0x67XXXXXXXXXXXXXXXX PUSH8 bytecode 0x363d3d37363d34f0\n 0x01 0x3d 0x3d RETURNDATASIZE 0 0x363d3d37363d34f0\n 0x02 0x52 0x52 MSTORE\n 0x03 0x60 0x6008 PUSH1 08 8\n 0x04 0x60 0x6018 PUSH1 18 24 8\n 0x05 0xf3 0xf3 RETURN\n\n 0x363d3d37363d34f0:\n 0x00 0x36 0x36 CALLDATASIZE cds\n 0x01 0x3d 0x3d RETURNDATASIZE 0 cds\n 0x02 0x3d 0x3d RETURNDATASIZE 0 0 cds\n 0x03 0x37 0x37 CALLDATACOPY\n 0x04 0x36 0x36 CALLDATASIZE cds\n 0x05 0x3d 0x3d RETURNDATASIZE 0 cds\n 0x06 0x34 0x34 CALLVALUE val 0 cds\n 0x07 0xf0 0xf0 CREATE addr\n */\n\n bytes internal constant PROXY_CHILD_BYTECODE =\n hex\"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3\";\n\n // KECCAK256_PROXY_CHILD_BYTECODE = keccak256(PROXY_CHILD_BYTECODE);\n bytes32 internal constant KECCAK256_PROXY_CHILD_BYTECODE =\n 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f;\n\n /**\n @notice Returns the size of the code on a given address\n @param _addr Address that may or may not contain code\n @return size of the code on the given `_addr`\n */\n function codeSize(address _addr) internal view returns (uint256 size) {\n assembly {\n size := extcodesize(_addr)\n }\n }\n\n /**\n @notice Creates a new contract with given `_creationCode` and `_salt`\n @param _salt Salt of the contract creation, resulting address will be derivated from this value only\n @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address\n @return addr of the deployed contract, reverts on error\n */\n function create3(\n bytes32 _salt,\n bytes memory _creationCode\n ) internal returns (address addr) {\n return create3(_salt, _creationCode, 0);\n }\n\n /**\n @notice Creates a new contract with given `_creationCode` and `_salt`\n @param _salt Salt of the contract creation, resulting address will be derivated from this value only\n @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address\n @param _value In WEI of ETH to be forwarded to child contract\n @return addr of the deployed contract, reverts on error\n */\n function create3(\n bytes32 _salt,\n bytes memory _creationCode,\n uint256 _value\n ) internal returns (address addr) {\n // Creation code\n bytes memory creationCode = PROXY_CHILD_BYTECODE;\n\n // Get target final address\n addr = addressOf(_salt);\n if (codeSize(addr) != 0) revert TargetAlreadyExists();\n\n // Create CREATE2 proxy\n address proxy;\n assembly {\n proxy := create2(\n 0,\n add(creationCode, 32),\n mload(creationCode),\n _salt\n )\n }\n if (proxy == address(0)) revert ErrorCreatingProxy();\n\n // Call proxy with final init code\n (bool success, ) = proxy.call{value: _value}(_creationCode);\n if (!success || codeSize(addr) == 0) revert ErrorCreatingContract();\n }\n\n function addressOfProxy(bytes32 _salt) internal view returns (address) {\n return\n address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n hex\"ff\",\n address(this),\n _salt,\n KECCAK256_PROXY_CHILD_BYTECODE\n )\n )\n )\n )\n );\n }\n\n /**\n @notice Computes the resulting address of a contract deployed using address(this) and the given `_salt`\n @param _salt Salt of the contract creation, resulting address will be derivated from this value only\n @return addr of the deployed contract, reverts on error\n\n @dev The address creation formula is: keccak256(rlp([keccak256(0xff ++ address(this) ++ _salt ++ keccak256(childBytecode))[12:], 0x01]))\n */\n function addressOf(bytes32 _salt) internal view returns (address) {\n address proxy = addressOfProxy(_salt);\n return\n address(\n uint160(\n uint256(\n keccak256(abi.encodePacked(hex\"d6_94\", proxy, hex\"01\"))\n )\n )\n );\n }\n}\n"},"contracts/utils/SoladyOwnable.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.27;\n\nimport { Ownable } from \"solady/auth/Ownable.sol\";\n\ncontract SoladyOwnable is Ownable {\n constructor(address _owner) Ownable() {\n assembly {\n if iszero(shl(96, _owner)) {\n mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.\n revert(0x1c, 0x04)\n }\n }\n _initializeOwner(_owner);\n }\n}\n"},"node_modules/solady/src/utils/ECDSA.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Gas optimized ECDSA wrapper.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol)\n/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol)\n///\n/// @dev Note:\n/// - The recovery functions use the ecrecover precompile (0x1).\n/// - As of Solady version 0.0.68, the `recover` variants will revert upon recovery failure.\n/// This is for more safety by default.\n/// Use the `tryRecover` variants if you need to get the zero address back\n/// upon recovery failure instead.\n/// - As of Solady version 0.0.134, all `bytes signature` variants accept both\n/// regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures.\n/// See: https://eips.ethereum.org/EIPS/eip-2098\n/// This is for calldata efficiency on smart accounts prevalent on L2s.\n///\n/// WARNING! Do NOT directly use signatures as unique identifiers:\n/// - The recovery operations do NOT check if a signature is non-malleable.\n/// - Use a nonce in the digest to prevent replay attacks on the same contract.\n/// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts.\n/// EIP-712 also enables readable signing of typed data for better user safety.\n/// - If you need a unique hash from a signature, please use the `canonicalHash` functions.\nlibrary ECDSA {\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* CONSTANTS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev The order of the secp256k1 elliptic curve.\n uint256 internal constant N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141;\n\n /// @dev `N/2 + 1`. Used for checking the malleability of the signature.\n uint256 private constant _HALF_N_PLUS_1 =\n 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1;\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* CUSTOM ERRORS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev The signature is invalid.\n error InvalidSignature();\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* RECOVERY OPERATIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`.\n function recover(bytes32 hash, bytes memory signature) internal view returns (address result) {\n /// @solidity memory-safe-assembly\n assembly {\n for { let m := mload(0x40) } 1 {\n mstore(0x00, 0x8baa579f) // `InvalidSignature()`.\n revert(0x1c, 0x04)\n } {\n switch mload(signature)\n case 64 {\n let vs := mload(add(signature, 0x40))\n mstore(0x20, add(shr(255, vs), 27)) // `v`.\n mstore(0x60, shr(1, shl(1, vs))) // `s`.\n }\n case 65 {\n mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.\n mstore(0x60, mload(add(signature, 0x40))) // `s`.\n }\n default { continue }\n mstore(0x00, hash)\n mstore(0x40, mload(add(signature, 0x20))) // `r`.\n result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20))\n mstore(0x60, 0) // Restore the zero slot.\n mstore(0x40, m) // Restore the free memory pointer.\n // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n if returndatasize() { break }\n }\n }\n }\n\n /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`.\n function recoverCalldata(bytes32 hash, bytes calldata signature)\n internal\n view\n returns (address result)\n {\n /// @solidity memory-safe-assembly\n assembly {\n for { let m := mload(0x40) } 1 {\n mstore(0x00, 0x8baa579f) // `InvalidSignature()`.\n revert(0x1c, 0x04)\n } {\n switch signature.length\n case 64 {\n let vs := calldataload(add(signature.offset, 0x20))\n mstore(0x20, add(shr(255, vs), 27)) // `v`.\n mstore(0x40, calldataload(signature.offset)) // `r`.\n mstore(0x60, shr(1, shl(1, vs))) // `s`.\n }\n case 65 {\n mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`.\n calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`.\n }\n default { continue }\n mstore(0x00, hash)\n result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20))\n mstore(0x60, 0) // Restore the zero slot.\n mstore(0x40, m) // Restore the free memory pointer.\n // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n if returndatasize() { break }\n }\n }\n }\n\n /// @dev Recovers the signer's address from a message digest `hash`,\n /// and the EIP-2098 short form signature defined by `r` and `vs`.\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) {\n /// @solidity memory-safe-assembly\n assembly {\n let m := mload(0x40) // Cache the free memory pointer.\n mstore(0x00, hash)\n mstore(0x20, add(shr(255, vs), 27)) // `v`.\n mstore(0x40, r)\n mstore(0x60, shr(1, shl(1, vs))) // `s`.\n result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20))\n // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n if iszero(returndatasize()) {\n mstore(0x00, 0x8baa579f) // `InvalidSignature()`.\n revert(0x1c, 0x04)\n }\n mstore(0x60, 0) // Restore the zero slot.\n mstore(0x40, m) // Restore the free memory pointer.\n }\n }\n\n /// @dev Recovers the signer's address from a message digest `hash`,\n /// and the signature defined by `v`, `r`, `s`.\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)\n internal\n view\n returns (address result)\n {\n /// @solidity memory-safe-assembly\n assembly {\n let m := mload(0x40) // Cache the free memory pointer.\n mstore(0x00, hash)\n mstore(0x20, and(v, 0xff))\n mstore(0x40, r)\n mstore(0x60, s)\n result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20))\n // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n if iszero(returndatasize()) {\n mstore(0x00, 0x8baa579f) // `InvalidSignature()`.\n revert(0x1c, 0x04)\n }\n mstore(0x60, 0) // Restore the zero slot.\n mstore(0x40, m) // Restore the free memory pointer.\n }\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* TRY-RECOVER OPERATIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n // WARNING!\n // These functions will NOT revert upon recovery failure.\n // Instead, they will return the zero address upon recovery failure.\n // It is critical that the returned address is NEVER compared against\n // a zero address (e.g. an uninitialized address variable).\n\n /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`.\n function tryRecover(bytes32 hash, bytes memory signature)\n internal\n view\n returns (address result)\n {\n /// @solidity memory-safe-assembly\n assembly {\n for { let m := mload(0x40) } 1 {} {\n switch mload(signature)\n case 64 {\n let vs := mload(add(signature, 0x40))\n mstore(0x20, add(shr(255, vs), 27)) // `v`.\n mstore(0x60, shr(1, shl(1, vs))) // `s`.\n }\n case 65 {\n mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.\n mstore(0x60, mload(add(signature, 0x40))) // `s`.\n }\n default { break }\n mstore(0x00, hash)\n mstore(0x40, mload(add(signature, 0x20))) // `r`.\n pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20))\n mstore(0x60, 0) // Restore the zero slot.\n // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n result := mload(xor(0x60, returndatasize()))\n mstore(0x40, m) // Restore the free memory pointer.\n break\n }\n }\n }\n\n /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`.\n function tryRecoverCalldata(bytes32 hash, bytes calldata signature)\n internal\n view\n returns (address result)\n {\n /// @solidity memory-safe-assembly\n assembly {\n for { let m := mload(0x40) } 1 {} {\n switch signature.length\n case 64 {\n let vs := calldataload(add(signature.offset, 0x20))\n mstore(0x20, add(shr(255, vs), 27)) // `v`.\n mstore(0x40, calldataload(signature.offset)) // `r`.\n mstore(0x60, shr(1, shl(1, vs))) // `s`.\n }\n case 65 {\n mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`.\n calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`.\n }\n default { break }\n mstore(0x00, hash)\n pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20))\n mstore(0x60, 0) // Restore the zero slot.\n // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n result := mload(xor(0x60, returndatasize()))\n mstore(0x40, m) // Restore the free memory pointer.\n break\n }\n }\n }\n\n /// @dev Recovers the signer's address from a message digest `hash`,\n /// and the EIP-2098 short form signature defined by `r` and `vs`.\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs)\n internal\n view\n returns (address result)\n {\n /// @solidity memory-safe-assembly\n assembly {\n let m := mload(0x40) // Cache the free memory pointer.\n mstore(0x00, hash)\n mstore(0x20, add(shr(255, vs), 27)) // `v`.\n mstore(0x40, r)\n mstore(0x60, shr(1, shl(1, vs))) // `s`.\n pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20))\n mstore(0x60, 0) // Restore the zero slot.\n // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n result := mload(xor(0x60, returndatasize()))\n mstore(0x40, m) // Restore the free memory pointer.\n }\n }\n\n /// @dev Recovers the signer's address from a message digest `hash`,\n /// and the signature defined by `v`, `r`, `s`.\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)\n internal\n view\n returns (address result)\n {\n /// @solidity memory-safe-assembly\n assembly {\n let m := mload(0x40) // Cache the free memory pointer.\n mstore(0x00, hash)\n mstore(0x20, and(v, 0xff))\n mstore(0x40, r)\n mstore(0x60, s)\n pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20))\n mstore(0x60, 0) // Restore the zero slot.\n // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n result := mload(xor(0x60, returndatasize()))\n mstore(0x40, m) // Restore the free memory pointer.\n }\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* HASHING OPERATIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Returns an Ethereum Signed Message, created from a `hash`.\n /// This produces a hash corresponding to the one signed with the\n /// [`eth_sign`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign)\n /// JSON-RPC method as part of EIP-191.\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) {\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x20, hash) // Store into scratch space for keccak256.\n mstore(0x00, \"\\x00\\x00\\x00\\x00\\x19Ethereum Signed Message:\\n32\") // 28 bytes.\n result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`.\n }\n }\n\n /// @dev Returns an Ethereum Signed Message, created from `s`.\n /// This produces a hash corresponding to the one signed with the\n /// [`eth_sign`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign)\n /// JSON-RPC method as part of EIP-191.\n /// Note: Supports lengths of `s` up to 999999 bytes.\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) {\n /// @solidity memory-safe-assembly\n assembly {\n let sLength := mload(s)\n let o := 0x20\n mstore(o, \"\\x19Ethereum Signed Message:\\n\") // 26 bytes, zero-right-padded.\n mstore(0x00, 0x00)\n // Convert the `s.length` to ASCII decimal representation: `base10(s.length)`.\n for { let temp := sLength } 1 {} {\n o := sub(o, 1)\n mstore8(o, add(48, mod(temp, 10)))\n temp := div(temp, 10)\n if iszero(temp) { break }\n }\n let n := sub(0x3a, o) // Header length: `26 + 32 - o`.\n // Throw an out-of-offset error (consumes all gas) if the header exceeds 32 bytes.\n returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20))\n mstore(s, or(mload(0x00), mload(n))) // Temporarily store the header.\n result := keccak256(add(s, sub(0x20, n)), add(n, sLength))\n mstore(s, sLength) // Restore the length.\n }\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* CANONICAL HASH FUNCTIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n // The following functions returns the hash of the signature in it's canonicalized format,\n // which is the 65-byte `abi.encodePacked(r, s, uint8(v))`, where `v` is either 27 or 28.\n // If `s` is greater than `N / 2` then it will be converted to `N - s`\n // and the `v` value will be flipped.\n // If the signature has an invalid length, or if `v` is invalid,\n // a uniquely corrupt hash will be returned.\n // These functions are useful for \"poor-mans-VRF\".\n\n /// @dev Returns the canonical hash of `signature`.\n function canonicalHash(bytes memory signature) internal pure returns (bytes32 result) {\n // @solidity memory-safe-assembly\n assembly {\n let l := mload(signature)\n for {} 1 {} {\n mstore(0x00, mload(add(signature, 0x20))) // `r`.\n let s := mload(add(signature, 0x40))\n let v := mload(add(signature, 0x41))\n if eq(l, 64) {\n v := add(shr(255, s), 27)\n s := shr(1, shl(1, s))\n }\n if iszero(lt(s, _HALF_N_PLUS_1)) {\n v := xor(v, 7)\n s := sub(N, s)\n }\n mstore(0x21, v)\n mstore(0x20, s)\n result := keccak256(0x00, 0x41)\n mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.\n break\n }\n\n // If the length is neither 64 nor 65, return a uniquely corrupted hash.\n if iszero(lt(sub(l, 64), 2)) {\n // `bytes4(keccak256(\"InvalidSignatureLength\"))`.\n result := xor(keccak256(add(signature, 0x20), l), 0xd62f1ab2)\n }\n }\n }\n\n /// @dev Returns the canonical hash of `signature`.\n function canonicalHashCalldata(bytes calldata signature)\n internal\n pure\n returns (bytes32 result)\n {\n // @solidity memory-safe-assembly\n assembly {\n for {} 1 {} {\n mstore(0x00, calldataload(signature.offset)) // `r`.\n let s := calldataload(add(signature.offset, 0x20))\n let v := calldataload(add(signature.offset, 0x21))\n if eq(signature.length, 64) {\n v := add(shr(255, s), 27)\n s := shr(1, shl(1, s))\n }\n if iszero(lt(s, _HALF_N_PLUS_1)) {\n v := xor(v, 7)\n s := sub(N, s)\n }\n mstore(0x21, v)\n mstore(0x20, s)\n result := keccak256(0x00, 0x41)\n mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.\n break\n }\n // If the length is neither 64 nor 65, return a uniquely corrupted hash.\n if iszero(lt(sub(signature.length, 64), 2)) {\n calldatacopy(mload(0x40), signature.offset, signature.length)\n // `bytes4(keccak256(\"InvalidSignatureLength\"))`.\n result := xor(keccak256(mload(0x40), signature.length), 0xd62f1ab2)\n }\n }\n }\n\n /// @dev Returns the canonical hash of `signature`.\n function canonicalHash(bytes32 r, bytes32 vs) internal pure returns (bytes32 result) {\n // @solidity memory-safe-assembly\n assembly {\n mstore(0x00, r) // `r`.\n let v := add(shr(255, vs), 27)\n let s := shr(1, shl(1, vs))\n mstore(0x21, v)\n mstore(0x20, s)\n result := keccak256(0x00, 0x41)\n mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.\n }\n }\n\n /// @dev Returns the canonical hash of `signature`.\n function canonicalHash(uint8 v, bytes32 r, bytes32 s) internal pure returns (bytes32 result) {\n // @solidity memory-safe-assembly\n assembly {\n mstore(0x00, r) // `r`.\n if iszero(lt(s, _HALF_N_PLUS_1)) {\n v := xor(v, 7)\n s := sub(N, s)\n }\n mstore(0x21, v)\n mstore(0x20, s)\n result := keccak256(0x00, 0x41)\n mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.\n }\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* EMPTY CALLDATA HELPERS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Returns an empty calldata bytes.\n function emptySignature() internal pure returns (bytes calldata signature) {\n /// @solidity memory-safe-assembly\n assembly {\n signature.length := 0\n }\n }\n}\n"},"node_modules/solady/src/auth/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)\n///\n/// @dev Note:\n/// This implementation does NOT auto-initialize the owner to `msg.sender`.\n/// You MUST call the `_initializeOwner` in the constructor / initializer.\n///\n/// While the ownable portion follows\n/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,\n/// the nomenclature for the 2-step ownership handover may be unique to this codebase.\nabstract contract Ownable {\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* CUSTOM ERRORS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev The caller is not authorized to call the function.\n error Unauthorized();\n\n /// @dev The `newOwner` cannot be the zero address.\n error NewOwnerIsZeroAddress();\n\n /// @dev The `pendingOwner` does not have a valid handover request.\n error NoHandoverRequest();\n\n /// @dev Cannot double-initialize.\n error AlreadyInitialized();\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* EVENTS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev The ownership is transferred from `oldOwner` to `newOwner`.\n /// This event is intentionally kept the same as OpenZeppelin's Ownable to be\n /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),\n /// despite it not being as lightweight as a single argument event.\n event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);\n\n /// @dev An ownership handover to `pendingOwner` has been requested.\n event OwnershipHandoverRequested(address indexed pendingOwner);\n\n /// @dev The ownership handover to `pendingOwner` has been canceled.\n event OwnershipHandoverCanceled(address indexed pendingOwner);\n\n /// @dev `keccak256(bytes(\"OwnershipTransferred(address,address)\"))`.\n uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =\n 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;\n\n /// @dev `keccak256(bytes(\"OwnershipHandoverRequested(address)\"))`.\n uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =\n 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;\n\n /// @dev `keccak256(bytes(\"OwnershipHandoverCanceled(address)\"))`.\n uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =\n 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* STORAGE */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev The owner slot is given by:\n /// `bytes32(~uint256(uint32(bytes4(keccak256(\"_OWNER_SLOT_NOT\")))))`.\n /// It is intentionally chosen to be a high value\n /// to avoid collision with lower slots.\n /// The choice of manual storage layout is to enable compatibility\n /// with both regular and upgradeable contracts.\n bytes32 internal constant _OWNER_SLOT =\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;\n\n /// The ownership handover slot of `newOwner` is given by:\n /// ```\n /// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))\n /// let handoverSlot := keccak256(0x00, 0x20)\n /// ```\n /// It stores the expiry timestamp of the two-step ownership handover.\n uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* INTERNAL FUNCTIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.\n function _guardInitializeOwner() internal pure virtual returns (bool guard) {}\n\n /// @dev Initializes the owner directly without authorization guard.\n /// This function must be called upon initialization,\n /// regardless of whether the contract is upgradeable or not.\n /// This is to enable generalization to both regular and upgradeable contracts,\n /// and to save gas in case the initial owner is not the caller.\n /// For performance reasons, this function will not check if there\n /// is an existing owner.\n function _initializeOwner(address newOwner) internal virtual {\n if (_guardInitializeOwner()) {\n /// @solidity memory-safe-assembly\n assembly {\n let ownerSlot := _OWNER_SLOT\n if sload(ownerSlot) {\n mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.\n revert(0x1c, 0x04)\n }\n // Clean the upper 96 bits.\n newOwner := shr(96, shl(96, newOwner))\n // Store the new value.\n sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\n // Emit the {OwnershipTransferred} event.\n log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\n }\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n // Clean the upper 96 bits.\n newOwner := shr(96, shl(96, newOwner))\n // Store the new value.\n sstore(_OWNER_SLOT, newOwner)\n // Emit the {OwnershipTransferred} event.\n log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\n }\n }\n }\n\n /// @dev Sets the owner directly without authorization guard.\n function _setOwner(address newOwner) internal virtual {\n if (_guardInitializeOwner()) {\n /// @solidity memory-safe-assembly\n assembly {\n let ownerSlot := _OWNER_SLOT\n // Clean the upper 96 bits.\n newOwner := shr(96, shl(96, newOwner))\n // Emit the {OwnershipTransferred} event.\n log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\n // Store the new value.\n sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\n }\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n let ownerSlot := _OWNER_SLOT\n // Clean the upper 96 bits.\n newOwner := shr(96, shl(96, newOwner))\n // Emit the {OwnershipTransferred} event.\n log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\n // Store the new value.\n sstore(ownerSlot, newOwner)\n }\n }\n }\n\n /// @dev Throws if the sender is not the owner.\n function _checkOwner() internal view virtual {\n /// @solidity memory-safe-assembly\n assembly {\n // If the caller is not the stored owner, revert.\n if iszero(eq(caller(), sload(_OWNER_SLOT))) {\n mstore(0x00, 0x82b42900) // `Unauthorized()`.\n revert(0x1c, 0x04)\n }\n }\n }\n\n /// @dev Returns how long a two-step ownership handover is valid for in seconds.\n /// Override to return a different value if needed.\n /// Made internal to conserve bytecode. Wrap it in a public function if needed.\n function _ownershipHandoverValidFor() internal view virtual returns (uint64) {\n return 48 * 3600;\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* PUBLIC UPDATE FUNCTIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Allows the owner to transfer the ownership to `newOwner`.\n function transferOwnership(address newOwner) public payable virtual onlyOwner {\n /// @solidity memory-safe-assembly\n assembly {\n if iszero(shl(96, newOwner)) {\n mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.\n revert(0x1c, 0x04)\n }\n }\n _setOwner(newOwner);\n }\n\n /// @dev Allows the owner to renounce their ownership.\n function renounceOwnership() public payable virtual onlyOwner {\n _setOwner(address(0));\n }\n\n /// @dev Request a two-step ownership handover to the caller.\n /// The request will automatically expire in 48 hours (172800 seconds) by default.\n function requestOwnershipHandover() public payable virtual {\n unchecked {\n uint256 expires = block.timestamp + _ownershipHandoverValidFor();\n /// @solidity memory-safe-assembly\n assembly {\n // Compute and set the handover slot to `expires`.\n mstore(0x0c, _HANDOVER_SLOT_SEED)\n mstore(0x00, caller())\n sstore(keccak256(0x0c, 0x20), expires)\n // Emit the {OwnershipHandoverRequested} event.\n log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())\n }\n }\n }\n\n /// @dev Cancels the two-step ownership handover to the caller, if any.\n function cancelOwnershipHandover() public payable virtual {\n /// @solidity memory-safe-assembly\n assembly {\n // Compute and set the handover slot to 0.\n mstore(0x0c, _HANDOVER_SLOT_SEED)\n mstore(0x00, caller())\n sstore(keccak256(0x0c, 0x20), 0)\n // Emit the {OwnershipHandoverCanceled} event.\n log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())\n }\n }\n\n /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.\n /// Reverts if there is no existing ownership handover requested by `pendingOwner`.\n function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {\n /// @solidity memory-safe-assembly\n assembly {\n // Compute and set the handover slot to 0.\n mstore(0x0c, _HANDOVER_SLOT_SEED)\n mstore(0x00, pendingOwner)\n let handoverSlot := keccak256(0x0c, 0x20)\n // If the handover does not exist, or has expired.\n if gt(timestamp(), sload(handoverSlot)) {\n mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.\n revert(0x1c, 0x04)\n }\n // Set the handover slot to 0.\n sstore(handoverSlot, 0)\n }\n _setOwner(pendingOwner);\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* PUBLIC READ FUNCTIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Returns the owner of the contract.\n function owner() public view virtual returns (address result) {\n /// @solidity memory-safe-assembly\n assembly {\n result := sload(_OWNER_SLOT)\n }\n }\n\n /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.\n function ownershipHandoverExpiresAt(address pendingOwner)\n public\n view\n virtual\n returns (uint256 result)\n {\n /// @solidity memory-safe-assembly\n assembly {\n // Compute the handover slot.\n mstore(0x0c, _HANDOVER_SLOT_SEED)\n mstore(0x00, pendingOwner)\n // Load the handover slot.\n result := sload(keccak256(0x0c, 0x20))\n }\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* MODIFIERS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Marks a function as only callable by the owner.\n modifier onlyOwner() virtual {\n _checkOwner();\n _;\n }\n}\n"}},"settings":{"remappings":["@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/","@prb/test/=node_modules/@prb/test/","@nexus/=node_modules/nexus/","forge-std/=lib/forge-std/src/","account-abstraction/=node_modules/account-abstraction/contracts/","@ERC4337/account-abstraction/=node_modules/account-abstraction/","@modulekit/=node_modules/modulekit/src/","sentinellist/=node_modules/sentinellist/src/","solady/=node_modules/solady/src/","@uniswap/v3-periphery/contracts/=node_modules/@uniswap/v3-periphery/contracts/","@uniswap/v3-core/contracts/=node_modules/@uniswap/v3-core/contracts/","@uniswap/swap-router-contracts/contracts/=node_modules/@uniswap/swap-router-contracts/contracts/","solady/src/=node_modules/solady/src/","excessively-safe-call/=node_modules/excessively-safe-call/src/","modulekit/=node_modules/@rhinestone/modulekit/src/","module-bases/=node_modules/module-bases/src/","erc7579/=node_modules/erc7579/src/","kernel/=node_modules/@zerodev/kernel/src/","@safe-global/=node_modules/@safe-global/","solarray/=node_modules/solarray/src/","erc7739Validator/=node_modules/erc7739-validator-base/src/","@biconomy-devx/=node_modules/@biconomy-devx/","@erc7579/=node_modules/@erc7579/","@gnosis.pm/=node_modules/@gnosis.pm/","@prb/math/=node_modules/erc7739-validator-base/node_modules/@prb/math/src/","@rhinestone/=node_modules/@rhinestone/","@zerodev/=node_modules/@zerodev/","ExcessivelySafeCall/=node_modules/erc7739-validator-base/node_modules/excessively-safe-call/src/","account-abstraction-v0.6/=node_modules/account-abstraction-v0.6/","accountabstraction/=node_modules/accountabstraction/","base64-sol/=node_modules/base64-sol/","ds-test/=node_modules/ds-test/","enumerableset4337/=node_modules/erc7739-validator-base/node_modules/@erc7579/enumerablemap4337/src/","erc4337-validation/=node_modules/erc7739-validator-base/node_modules/@rhinestone/erc4337-validation/src/","erc7739-validator-base/=node_modules/erc7739-validator-base/","hardhat-deploy/=node_modules/hardhat-deploy/","hardhat/=node_modules/hardhat/","nexus/=node_modules/nexus/","registry/=node_modules/modulekit/node_modules/@rhinestone/registry/src/","safe7579/=node_modules/erc7739-validator-base/node_modules/@rhinestone/safe7579/src/"],"optimizer":{"enabled":true,"runs":800},"metadata":{"useLiteralContent":false,"bytecodeHash":"none","appendCBOR":true},"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"]}},"evmVersion":"cancun","viaIR":true,"libraries":{}}} diff --git a/scripts/bash-deploy/deploy-gasdaddy.sh b/scripts/bash-deploy/deploy-gasdaddy.sh index 8f7449f..b5e3787 100644 --- a/scripts/bash-deploy/deploy-gasdaddy.sh +++ b/scripts/bash-deploy/deploy-gasdaddy.sh @@ -78,6 +78,7 @@ if [ $proceed = "y" ]; then printf "Creating verification artifacts\n" forge verify-contract --show-standard-json-input $(cast address-zero) BiconomySponsorshipPaymaster > ./artifacts/BiconomySponsorshipPaymaster/verify.json + forge verify-contract --show-standard-json-input $(cast address-zero) BiconomyTokenPaymaster > ./artifacts/BiconomyTokenPaymaster/verify.json else printf "Using precompiled artifacts\n" diff --git a/scripts/bash-deploy/deploy-prerequisites.sh b/scripts/bash-deploy/deploy-prerequisites.sh index e87ba95..8feff97 100644 --- a/scripts/bash-deploy/deploy-prerequisites.sh +++ b/scripts/bash-deploy/deploy-prerequisites.sh @@ -124,7 +124,7 @@ fi ### Create3 Deployer ### -CREATE3_DEPLOYER_SIZE=$(cast codesize --rpc-url $CHAIN_NAME 0x000000aFCC4940A247A53bEa5f3f4602433fe815) +CREATE3_DEPLOYER_SIZE=$(cast codesize --rpc-url $CHAIN_NAME $CREATE3_DEPLOYER_ADDRESS) # printf "CREATE3 DEPLOYER Codesize: $CREATE3_DEPLOYER_SIZE\n" if [ $CREATE3_DEPLOYER_SIZE -eq 0 ]; then @@ -137,6 +137,7 @@ if [ $CREATE3_DEPLOYER_SIZE -eq 0 ]; then printf "Rebuilding create3 deployer artifacts...\n" forge build > /dev/null cp ../../out/Deployer.sol/Deployer.json ./artifacts/Deployer/. + forge verify-contract --show-standard-json-input $(cast address-zero) Deployer > ./artifacts/Deployer/verify.json else printf "Using existing create3 deployer artifacts\n" fi diff --git a/scripts/foundry/DeployDeployer.s.sol b/scripts/foundry/DeployDeployer.s.sol index 4decec4..ad34e6d 100644 --- a/scripts/foundry/DeployDeployer.s.sol +++ b/scripts/foundry/DeployDeployer.s.sol @@ -6,7 +6,7 @@ import {DeterministicDeployerLib} from "./utils/DeterministicDeployerLib.sol"; contract DeployDeployer is Script { - bytes32 constant CREATE3_DEPLOYER_DEPLOYMENT_SALT = 0x00000000000000000000000000000000000000007d24613b61566e02484a50c5; + bytes32 constant CREATE3_DEPLOYER_DEPLOYMENT_SALT = 0x000000000000000000000000000000000000000068be161e3f742b0423335623; // => 0x0000003d8fE88f1591774CCD958baF0211Ee2183 address constant DEPLOYER_OWNER = 0x336A8f5251F3b0723d04FBDD25858fca02BB22E3; bytes32 constant DEPLOYER_BYTECODE_HASH = 0xb474e2c7cd2df923dc66b1fbf61eb752b66b7aecb94e055878c3c75061de219c; @@ -19,6 +19,7 @@ contract DeployDeployer is Script { address expectedDeployer = DeterministicDeployerLib.computeAddress(bytecode, args, CREATE3_DEPLOYER_DEPLOYMENT_SALT); // initcode hash to look for the salt + console.log("Deployer bytecode hash for salt generation: "); console.logBytes32(keccak256(abi.encodePacked(bytecode, args))); bytes32 deployerBytecodeHash; @@ -29,9 +30,6 @@ contract DeployDeployer is Script { deployerBytecodeHash := extcodehash(expectedDeployer) } - //console.logBytes32(deployerBytecodeHash); - //console.log("Size", codeLength); - if (codeLength != 0) { if (deployerBytecodeHash != DEPLOYER_BYTECODE_HASH) { revert("Deployer bytecode hash mismatch"); diff --git a/scripts/foundry/DeployGasdaddy.s.sol b/scripts/foundry/DeployGasdaddy.s.sol index beb3699..e2e717c 100644 --- a/scripts/foundry/DeployGasdaddy.s.sol +++ b/scripts/foundry/DeployGasdaddy.s.sol @@ -30,9 +30,6 @@ contract DeployGasdaddy is Script { bytes32 constant SPONSORSHIP_PAYMASTER_DEPLOYMENT_SALT = 0x3e81534a95d3368136d6c49522f8e20ada0b768931512a65c785c15a83178777; // bytes32 constant TOKEN_PAYMASTER_DEPLOYMENT_SALT = 0xf5516e76713013dc560228c61d8ad21680be770b25fcaed28edf3071e09bb777; // - // CREATE3 DEPLOYER ADDRESS - address constant CREATE3_DEPLOYER_ADDRESS = 0x000000aFCC4940A247A53bEa5f3f4602433fe815; - // CONSTRUCTOR ARGS address constant VERIFYING_PAYMASTER_OWNER = 0x2cf491602ad22944D9047282aBC00D3e52F56B37; address constant VERIFYING_SIGNER = 0xC6dAB8652E5E9749523bA948F42d5944584E4e73; @@ -42,16 +39,13 @@ contract DeployGasdaddy is Script { uint256 constant PAYMASTER_ID_WITHDRAWAL_DELAY = 3600; // 1 hour address constant ENTRY_POINT_V07 = 0x0000000071727De22E5E9d8BAf0edAc6f37da032; - mapping (uint256 => bytes) public signaturesForMinDeposits; mapping (uint256 chainId => TokenPMConfig) public tokenPMConfigs; Create3Deployer create3Deployer; function setUp() public { - create3Deployer = Create3Deployer(CREATE3_DEPLOYER_ADDRESS); - - _fillSignaturesForMinDepositsSponsPM(); + create3Deployer = Create3Deployer(vm.envAddress("CREATE3_DEPLOYER_ADDRESS")); _fillTokenPMConfigs(); @@ -90,34 +84,9 @@ contract DeployGasdaddy is Script { PAYMASTER_ID_WITHDRAWAL_DELAY, minDeposit ); - console.log("args abi encoded: "); + console.log("args abi encoded for sponsorship PM: "); console.logBytes(args); - // Use this block to get initcode hashes to sign - /* - uint256[] memory minDeposits = new uint256[](5); - minDeposits[0] = 1e15; - minDeposits[1] = 1e16; - minDeposits[2] = 1e17; - minDeposits[3] = 1e18; - minDeposits[4] = 1e19; - - for (uint256 i = 0; i < minDeposits.length; i++) { - minDeposit = minDeposits[i]; - args = abi.encode( - VERIFYING_PAYMASTER_OWNER, - ENTRY_POINT_V07, - VERIFYING_SIGNER, - FEE_COLLECTOR, - SPONSORSHIP_PM_UNACCOUNTED_GAS, - PAYMASTER_ID_WITHDRAWAL_DELAY, - minDeposit - ); - console.log("min deposit: ", (minDeposit)); - console.logBytes32(keccak256(abi.encodePacked(bytecode, args))); - } - */ - /// /// TOKEN PAYMASTER /// @@ -127,10 +96,35 @@ contract DeployGasdaddy is Script { codeSize := extcodesize(tokenPM) } console.log("Token Paymaster address: ", tokenPM, " || >> Code Size: ", codeSize); + + TokenPMConfig memory config = tokenPMConfigs[block.chainid]; + args = abi.encode( + VERIFYING_PAYMASTER_OWNER, + VERIFYING_SIGNER, + ENTRY_POINT_V07, + TOKEN_PM_UNACCOUNTED_GAS, + config.nativeAssetDecimals, + config.nativeAssetToUsdOracle, + config.nativeAssetPriceExpiryDuration, + config.swapRouter, + config.wrappedNativeAddress, + config.independentTokens, + config.tokenInfos, + new address[](0), // swappable tokens + new uint24[](0) // swappable token fees + ); + console.log("args abi encoded for token PM: "); + console.logBytes(args); } + // + // DEPLOY GASDADDY + // + function deployGasDaddy(uint256 minDeposit) public returns (uint256 contractsDeployedCount) { + uint256 create3deployerOwnerPk = vm.envUint("CREATE3_OWNER_PK"); + // // SPONSORSHIP PAYMASTER // @@ -153,8 +147,8 @@ contract DeployGasdaddy is Script { console.log("Sponsorship Paymaster already deployed at", sponsorshipPM); } else { bytes memory initcode = abi.encodePacked(bytecode, args); - bytes memory signature = signaturesForMinDeposits[minDeposit]; - sponsorshipPM = create3Deployer.deploy(SPONSORSHIP_PAYMASTER_DEPLOYMENT_SALT, initcode, signature); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(create3deployerOwnerPk, keccak256(abi.encode(initcode, SPONSORSHIP_PAYMASTER_DEPLOYMENT_SALT, block.chainid))); + sponsorshipPM = create3Deployer.deploy(SPONSORSHIP_PAYMASTER_DEPLOYMENT_SALT, initcode, abi.encodePacked(r, s, v)); console.log("Sponsorship Paymaster deployed at", sponsorshipPM); contractsDeployedCount++; } @@ -162,7 +156,6 @@ contract DeployGasdaddy is Script { /// /// TOKEN PAYMASTER /// - uint256 create3deployerOwnerPk = vm.envUint("CREATE3_OWNER_PK"); bytecode = vm.getCode("scripts/bash-deploy/artifacts/BiconomyTokenPaymaster/BiconomyTokenPaymaster.json"); TokenPMConfig memory config = tokenPMConfigs[block.chainid]; @@ -198,22 +191,13 @@ contract DeployGasdaddy is Script { return contractsDeployedCount; } else { bytes memory initcode = abi.encodePacked(bytecode, args); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(create3deployerOwnerPk, keccak256(initcode)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(create3deployerOwnerPk, keccak256(abi.encode(initcode, TOKEN_PAYMASTER_DEPLOYMENT_SALT, block.chainid))); tokenPM = create3Deployer.deploy(TOKEN_PAYMASTER_DEPLOYMENT_SALT, initcode, abi.encodePacked(r, s, v)); console.log("Token Paymaster deployed at", tokenPM); contractsDeployedCount++; } } - function _fillSignaturesForMinDepositsSponsPM() internal { - // Signatures for Sponsorship PM - signaturesForMinDeposits[1e15] = hex'f799f0e37b89b42d667d6cf6ca461bb4e1d9818a5568a640ad89dbe74a16b18b105a3ecbe06828faaf91153bf2238bd5bf9f52cda834eb2ddc81c5665b77901f1b'; //0.001 native token - signaturesForMinDeposits[1e16] = hex'3d4fc4d9a447fb205cc50dce4b74230f0e0baea776bbce2cced39e1b82f612bc5de05607fdeaf3734f8577a8b829b0dd05bb0fe760e4fe9dda28b729d45c95d21c'; //0.01 native token - signaturesForMinDeposits[1e17] = hex'f121c54fabc0f95a2baa1cc296135d125f636532d489a9850a0ea3fe7f52694a2954b6f5cd42aca1e2203e7e39108a878477bfe2f90ed6a38ec578199e5586111c'; //0.1 native token - signaturesForMinDeposits[1e18] = hex'0e2f4921b34b8a2a6ceab67bd7db9655c0e272a725cbb5da84acaad1d023237817a1cb754fd65dd45bebc43312dafb9b53c8e58619da7da5acc9ea96294534141b'; //1 native token - signaturesForMinDeposits[1e19] = hex'6e559e01580bc8cd18fabef2d0aa018f35dc5cb1aa0c26e8cb8b9c45478382cf0fcc208ad2564d693418957e417a90b9081716fa1c01cba65e8442edaed584541c'; //10 native tokens - } - function _fillTokenPMConfigs() internal { // in case we want to support independent tokens /*