diff --git a/README.md b/README.md index d830db9..f204c76 100644 --- a/README.md +++ b/README.md @@ -136,11 +136,11 @@ Gas used for the deployment is 84,540 (or a little more for some blockchains), s The SKYBITLite factory contract will be deployed to this address (if the transaction bytecode is unchanged): ``` -0xe3dCDc516f75Fcd8CA7f3Ecb8387fb85CF0AbEDd +0xcAb20EC9d599aCc6253be7fbfB1fa215E8c9f993 ``` The derived address of the account that would sign the deployment transaction, and that you'd need to fund in order to pay the gas fee, is: ``` -0x62dF0289c0120c00A7a67a353cD2600A882d8198 +0xb40a5c3217929e1b2631debb680b7C50ec054EBc ``` @@ -225,11 +225,11 @@ In `hardhat.config.js` do the following: Set `accounts` to the one(s) that you will use. -Check whether the blockchains you will use are listed in [@wagmi/chains](https://github.com/wagmi-dev/references/blob/main/packages/chains/src/index.ts). If not, then add the blockchain info in `additionalNetworks`. +Check whether the blockchains you will use are listed in [@wagmi/chains](https://github.com/wagmi-dev/viem/blob/main/src/chains/index.ts). If not, then add the blockchain info in `additionalNetworks`. -For the few blockchain names in [@wagmi/chains](https://github.com/wagmi-dev/references/blob/main/packages/chains/src/index.ts) that don't match exactly with names in [hardhat-verify](https://github.com/NomicFoundation/hardhat/blob/main/packages/hardhat-verify/src/internal/chain-config.ts), use the [hardhat-verify](https://github.com/NomicFoundation/hardhat/blob/main/packages/hardhat-verify/src/internal/chain-config.ts) version as shown in this table: +For the few blockchain names in [@wagmi/chains](https://github.com/wagmi-dev/viem/blob/main/src/chains/index.ts) that don't match exactly with names in [hardhat-verify](https://github.com/NomicFoundation/hardhat/blob/main/packages/hardhat-verify/src/internal/chain-config.ts), use the [hardhat-verify](https://github.com/NomicFoundation/hardhat/blob/main/packages/hardhat-verify/src/internal/chain-config.ts) version as shown in this table: -| In [@wagmi/chains](https://github.com/wagmi-dev/references/blob/main/packages/chains/src/index.ts) | In [hardhat-verify](https://github.com/NomicFoundation/hardhat/blob/main/packages/hardhat-verify/src/internal/chain-config.ts) (use these) | +| In [@wagmi/chains](https://github.com/wagmi-dev/viem/blob/main/src/chains/index.ts) | In [hardhat-verify](https://github.com/NomicFoundation/hardhat/blob/main/packages/hardhat-verify/src/internal/chain-config.ts) (use these) | |--|--| | arbitrum | arbitrumOne | | avalancheFuji | avalancheFujiTestnet | diff --git a/artifacts-saved/contracts/SKYBITCREATE3FactoryLite.yul/SKYBITCREATE3FactoryLite.json b/artifacts-saved/contracts/SKYBITCREATE3FactoryLite.yul/SKYBITCREATE3FactoryLite.json index 889bc9e..07854de 100644 --- a/artifacts-saved/contracts/SKYBITCREATE3FactoryLite.yul/SKYBITCREATE3FactoryLite.json +++ b/artifacts-saved/contracts/SKYBITCREATE3FactoryLite.yul/SKYBITCREATE3FactoryLite.json @@ -3,7 +3,7 @@ "contractName": "SKYBITCREATE3FactoryLite", "sourceName": "contracts/SKYBITCREATE3FactoryLite.yul", "abi": [], - "bytecode": "0x60918061000b5f395ff3fe34608d575f6f67363d3d37363d34f03d5260086018f38152336020528035604052604060202060108083f59081156080578160145261d6948152600160345380806017601e20938180601f1936019283602083375af115607357813b15606657526014600cf35b63326bd13990526004601cfd5b63ec4cb4b690526004601cfd5b63335e7dd590526004601cfd5b5f80fd", + "bytecode": "0x60898061000b5f395ff3fe34606b575f601980607083393360205281356040526040602020908280f58015605e57816014918180601f1936019283602083375af115605157805115604457601490f35b63326bd13990526004601cfd5b63ec4cb4b690526004601cfd5b636e0df51b82526004601cfd5b5f80fdfe600f80600a5f395ff3fe365f8037365f80f05f526014600cf3", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/contracts/SKYBITCREATE3FactoryLite.yul b/contracts/SKYBITCREATE3FactoryLite.yul index 992a7dd..8724836 100644 --- a/contracts/SKYBITCREATE3FactoryLite.yul +++ b/contracts/SKYBITCREATE3FactoryLite.yul @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -/// @notice A factory contract that deploys a contract from bytecode using "CREATE3" method. Derived from https://github.com/Vectorized/solady/blob/main/src/utils/CREATE3.sol +/// @notice A factory contract that deploys a contract from bytecode using "CREATE3" method. /// @author SKYBIT (https://github.com/SKYBITDev3/SKYBIT-Keyless-Deployment) object "SKYBITCREATE3FactoryLite" { code { // Constructor code of the contract @@ -12,76 +12,55 @@ object "SKYBITCREATE3FactoryLite" { code { // Executable code of the object if gt(callvalue(), 0) { revert(0, 0) } // Protection against sending Ether - /** - @notice The bytecode for a contract that proxies the creation of another contract - @dev If this code is deployed using CREATE2 it can be used to decouple `creationCode` from the child contract address - - 0x67363d3d37363d34f03d5260086018f3: - 0x00 0x67 0x67XXXXXXXXXXXXXXXX PUSH8 bytecode 0x363d3d37363d34f0 - 0x01 0x3d 0x3d RETURNDATASIZE 0 0x363d3d37363d34f0 - 0x02 0x52 0x52 MSTORE - 0x03 0x60 0x6008 PUSH1 08 8 - 0x04 0x60 0x6018 PUSH1 18 24 8 - 0x05 0xf3 0xf3 RETURN - - 0x363d3d37363d34f0: - 0x00 0x36 0x36 CALLDATASIZE cds - 0x01 0x3d 0x3d RETURNDATASIZE 0 cds - 0x02 0x3d 0x3d RETURNDATASIZE 0 0 cds - 0x03 0x37 0x37 CALLDATACOPY - 0x04 0x36 0x36 CALLDATASIZE cds - 0x05 0x3d 0x3d RETURNDATASIZE 0 cds - 0x06 0x34 0x34 CALLVALUE val 0 cds - 0x07 0xf0 0xf0 CREATE addr - */ - mstore(0, 0x67363d3d37363d34f03d5260086018f3) // Store the CREATE proxy bytecode (16 bytes) into scratch space. - + datacopy(0, dataoffset("CREATEFactory"), datasize("CREATEFactory")) // Write CREATEFactory bytecode to memory position 0. 25 bytes on left of slot, 0-padded on right mstore(0x20, caller()) // 32 bytes. to be hashed with salt to help ensure unique address. mstore(0x40, calldataload(0)) // User-provided salt (32 bytes) - let proxy:= create2(0, 0x10, 0x10, keccak256(0x20, 0x40)) // Deploy the CREATE proxy via CREATE2, store address on the stack + let createFactoryAddress := create2(0, 0, datasize("CREATEFactory"), keccak256(0x20, 0x40)) // Deploy the CREATE factory via CREATE2, store address on the stack - if iszero(proxy) { - mstore(0, 0x335e7dd5) // Store ABI encoding of `Deployment of CREATE proxy failed` + if iszero(createFactoryAddress) { + mstore(0, 0x6e0df51b) // Store ABI encoding of `Deployment of CREATEFactory contract failed` revert(0x1c, 4) // Revert with the stored 4 bytes skipping 0-padding } - mstore(0x14, proxy) // Store the proxy's address. The actual address starts at 0x20 because of 0-padding on left. Positioned so that RLP encoding prefix can be placed just before. - - // "if a string is 0-55 bytes long, the RLP encoding consists of a single byte with value 0x80 (dec. 128) plus the length of the string followed by the string." - // "If the total payload of a list (i.e. the combined length of all its items being RLP encoded) is 0-55 bytes long, the RLP encoding consists of a single byte with value 0xc0 plus the length of the list followed by the concatenation of the RLP encodings of the items" - // Source: https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp - // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01) - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) - mstore(0, 0xd694) // Store RLP encoding prefix just before proxy address - mstore8(0x34, 1) // Store single byte: nonce of the proxy contract just after proxy address. EIP-161 specifies contract nonce to start at 1. - - let deployed:= keccak256(0x1e, 0x17) // Address from CREATE = hash of RLP-encoded proxy address and nonce - - calldatacopy(0, 32, sub(calldatasize(), 32)) // Overwrite scratch at memory position 0 with incoming creationCode. We take full control of memory because it won't return to Solidity code. We don't need the previously stored data anymore. + calldatacopy(0, 32, sub(calldatasize(), 32)) // Overwrite scratch at memory position 0 with incoming creation code (skipping first 32 bytes which is salt), saving gas. We take full control of memory because it won't return to Solidity code. We don't need the previously stored data anymore. if iszero( - call( // Use the CREATE proxy to deploy the users' contract. Returns 1 if successful. + call( // Use the deployed CREATEFactory to deploy the users' contract. Returns 0 on error (eg. out of gas) and 1 on success. gas(), // Gas remaining - proxy, // Proxy's address + createFactoryAddress, 0, // Ether value - 0, // Start of `creationCode` - sub(calldatasize(), 32), // Length of `creationCode` - 0, // Offset of output - 0 // Length of output + 0, // Start of contract bytecode or "creation code" + sub(calldatasize(), 32), // Length of contract bytecode + 0, // Offset of output (resulting address of deployed user's contract) + 20 // Length of output ) ) { - mstore(0, 0xec4cb4b6) // Store ABI encoding of `CREATE proxy call failed` + mstore(0, 0xec4cb4b6) // Store ABI encoding of `CREATEFactory call failed` revert(0x1c, 4) } - if iszero(extcodesize(deployed)) { + if iszero(mload(0)) { mstore(0, 0x326bd139) // Store ABI encoding of `Contract nonexistent at expected address` revert(0x1c, 4) } - mstore(0, deployed) - return (12, 20) // Addresses are only 20 bytes, so skip the first 12 bytes as it's just 0-padding + return (0, 20) // Return the call output, which is the address of the contract that was deployed via CREATEFactory + } + + object "CREATEFactory" { + code { + datacopy(0, dataoffset("runtime"), datasize("runtime")) + return (0, datasize("runtime")) + } + + object "runtime" { + code { + calldatacopy(0, 0, calldatasize()) + mstore(0, create(0, 0, calldatasize())) + return (12, 20) // Addresses are only 20 bytes, so skip the first 12 bytes + } + } } } } diff --git a/package.json b/package.json index dd0dbab..0c7bc55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "SKYBIT-Keyless-Deployment", - "version": "2.8.2", + "version": "2.9.0", "packageManager": "yarn@3.6.1", "devDependencies": { "@Vectorized/solady": "https://github.com/Vectorized/solady#03f3fd05fb1da76edc4df83ae6bf32a842c15f12", diff --git a/scripts/deployKeylessly-Create3Factory.js b/scripts/deployKeylessly-Create3Factory.js index b54143a..549abaa 100644 --- a/scripts/deployKeylessly-Create3Factory.js +++ b/scripts/deployKeylessly-Create3Factory.js @@ -70,7 +70,7 @@ const getGasLimit = (factory) => { break case `SKYBITLite`: default: - return 100000n // Gas cost: 84540 + return 100000n // Gas cost: 82812 } } diff --git a/scripts/deployViaCREATE3-TESTERC20.js b/scripts/deployViaCREATE3-TESTERC20.js index 917281a..5821f45 100644 --- a/scripts/deployViaCREATE3-TESTERC20.js +++ b/scripts/deployViaCREATE3-TESTERC20.js @@ -11,7 +11,7 @@ const { ethers, network } = require(`hardhat`) // const addressOfFactory = `0x619Bdd2F58Ba735e9390D7B177e5Ca3C410bf98c` // gas cost: 2140281 const factoryToUse = `SKYBITLite` -const addressOfFactory = `0xe3dCDc516f75Fcd8CA7f3Ecb8387fb85CF0AbEDd` // gas cost: 2115714 +const addressOfFactory = `0xcAb20EC9d599aCc6253be7fbfB1fa215E8c9f993` // gas cost: 2075520 // PASS YOUR OWN STRING HERE TO GENERATE A UNIQUE SALT. After doing your first production deployment, don't change it in order to have same address on other blockchains. diff --git a/scripts/deployViaCREATE3-TESTERC20UG.js b/scripts/deployViaCREATE3-TESTERC20UG.js index 14a30b5..6c9ee6d 100644 --- a/scripts/deployViaCREATE3-TESTERC20UG.js +++ b/scripts/deployViaCREATE3-TESTERC20UG.js @@ -12,7 +12,7 @@ const { ethers, network, upgrades } = require(`hardhat`) // const addressOfFactory = `0x619Bdd2F58Ba735e9390D7B177e5Ca3C410bf98c` const factoryToUse = `SKYBITLite` -const addressOfFactory = `0xe3dCDc516f75Fcd8CA7f3Ecb8387fb85CF0AbEDd` +const addressOfFactory = `0xcAb20EC9d599aCc6253be7fbfB1fa215E8c9f993` const isDeployEnabled = true // toggle in case you do deployment and verification separately.