From c907e102691e18e813e59bed17145b3255449e19 Mon Sep 17 00:00:00 2001 From: 0xdavinchee <0xdavinchee@gmail.com> Date: Fri, 20 Oct 2023 18:30:37 +0300 Subject: [PATCH 1/3] make deploy script compatible with ethers v6 --- packages/ethereum-contracts/CHANGELOG.md | 3 + .../dev-scripts/deploy-contracts-and-token.js | 2 +- .../dev-scripts/deploy-test-framework.js | 93 +++++++++++++------ packages/ethereum-contracts/package.json | 4 +- 4 files changed, 72 insertions(+), 30 deletions(-) diff --git a/packages/ethereum-contracts/CHANGELOG.md b/packages/ethereum-contracts/CHANGELOG.md index 7b267759a9..7a87587457 100644 --- a/packages/ethereum-contracts/CHANGELOG.md +++ b/packages/ethereum-contracts/CHANGELOG.md @@ -32,6 +32,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Simplification of Super App registration: use `registerApp` in all cases going forward. - Use `registerApp(uint256 configWord)` to be called by the super app in the constructor or `registerApp(ISuperApp app, uint256 configWord)` to be called by any address with a valid app registration config key +### Fixes +- [`dev-scripts/deploy-test-framework.js`](dev-scripts/deploy-test-framework.js) compatible with both ethers-v5 and ethers-v6 now + ## [v1.8.1] - 2023-08-28 ### Fixed diff --git a/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js b/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js index 6302928387..398e6aa1cd 100644 --- a/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js +++ b/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js @@ -8,7 +8,7 @@ const { async function deployContractsAndToken() { const [Deployer] = await ethers.getSigners(); - const {frameworkDeployer: deployer} = await deployTestFramework(); + const {frameworkDeployer: deployer} = await deployTestFramework(null, ethers.provider, Deployer); const framework = await deployer.getFramework(); const resolver = await ethers.getContractAt( diff --git a/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js b/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js index 626be673b1..15447cbe94 100644 --- a/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js +++ b/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js @@ -51,6 +51,17 @@ async function deployERC1820(provider) { } } +/** + * Gets the address of the deployed contract. + * This is for handling the different contract objects in ethers v5 (contract.address) + * vs ethers v6 (contract.target), that is, v6 does not have contract.address and vice versa. + * @param {ethers.Contract} contract + * @returns + */ +const getContractAddress = (contract) => { + return contract.address || contract.target; +}; + const _getFactoryAndReturnDeployedContract = async ( contractName, artifact, @@ -65,21 +76,36 @@ const _getFactoryAndReturnDeployedContract = async ( signerOrOptions ); const contract = await ContractFactory.deploy(...args); - await contract.deployed(); + + // ethers v5 + if (contract.deployed) { + await contract.deployed(); + } else if (!contract.deployed) { + // ethers v6 + await contract.waitForDeployment(); + } + if (process.env.DEBUG_CONSOLE === true) { - console.log(`${contractName} Deployed At:`, contract.address); + console.log( + `${contractName} Deployed At:`, + getContractAddress(contract) + ); } return contract; }; /** * Deploys Superfluid Framework in local testing environments. - * NOTE: This only works with Hardhat. + * NOTE: This only works with Hardhat + ethers v5/ethers v6 currently. + * @param privateKey NEVER USE A PRIVATE KEY WITH REAL FUNDS - a test account private key + * @param provider an ethers provider + * @param ethersV5Signer an ethers v5 signer * @returns */ -const deployTestFramework = async () => { - const signer = (await ethers.getSigners())[0]; - await deployERC1820(ethers.provider); +const deployTestFramework = async (privateKey, provider, ethersV5Signer) => { + // use a passed signer OR create one on the spot + const signer = ethersV5Signer || new ethers.Wallet(privateKey, provider); + await deployERC1820(provider); const SlotsBitmapLibrary = await _getFactoryAndReturnDeployedContract( "SlotsBitmapLibrary", SlotsBitmapLibraryArtifact, @@ -110,7 +136,7 @@ const deployTestFramework = async () => { { signer, libraries: { - SlotsBitmapLibrary: SlotsBitmapLibrary.address, + SlotsBitmapLibrary: getContractAddress(SlotsBitmapLibrary), }, } ); @@ -170,27 +196,38 @@ const deployTestFramework = async () => { { signer, libraries: { - SuperfluidGovDeployerLibrary: - SuperfluidGovDeployerLibrary.address, - SuperfluidHostDeployerLibrary: - SuperfluidHostDeployerLibrary.address, - SuperfluidCFAv1DeployerLibrary: - SuperfluidCFAv1DeployerLibrary.address, - SuperfluidIDAv1DeployerLibrary: - SuperfluidIDAv1DeployerLibrary.address, - SuperfluidPeripheryDeployerLibrary: - SuperfluidPeripheryDeployerLibrary.address, - SuperTokenDeployerLibrary: SuperTokenDeployerLibrary.address, - SuperfluidNFTLogicDeployerLibrary: - SuperfluidNFTLogicDeployerLibrary.address, - ProxyDeployerLibrary: ProxyDeployerLibrary.address, - CFAv1ForwarderDeployerLibrary: - CFAv1ForwarderDeployerLibrary.address, - IDAv1ForwarderDeployerLibrary: - IDAv1ForwarderDeployerLibrary.address, - SuperfluidLoaderDeployerLibrary: - SuperfluidLoaderDeployerLibrary.address, - TokenDeployerLibrary: TokenDeployerLibrary.address, + SuperfluidGovDeployerLibrary: getContractAddress( + SuperfluidGovDeployerLibrary + ), + SuperfluidHostDeployerLibrary: getContractAddress( + SuperfluidHostDeployerLibrary + ), + SuperfluidCFAv1DeployerLibrary: getContractAddress( + SuperfluidCFAv1DeployerLibrary + ), + SuperfluidIDAv1DeployerLibrary: getContractAddress( + SuperfluidIDAv1DeployerLibrary + ), + SuperfluidPeripheryDeployerLibrary: getContractAddress( + SuperfluidPeripheryDeployerLibrary + ), + SuperTokenDeployerLibrary: getContractAddress( + SuperTokenDeployerLibrary + ), + SuperfluidNFTLogicDeployerLibrary: getContractAddress( + SuperfluidNFTLogicDeployerLibrary + ), + ProxyDeployerLibrary: getContractAddress(ProxyDeployerLibrary), + CFAv1ForwarderDeployerLibrary: getContractAddress( + CFAv1ForwarderDeployerLibrary + ), + IDAv1ForwarderDeployerLibrary: getContractAddress( + IDAv1ForwarderDeployerLibrary + ), + SuperfluidLoaderDeployerLibrary: getContractAddress( + SuperfluidLoaderDeployerLibrary + ), + TokenDeployerLibrary: getContractAddress(TokenDeployerLibrary), }, } ); diff --git a/packages/ethereum-contracts/package.json b/packages/ethereum-contracts/package.json index 1a20f66c02..960943b820 100644 --- a/packages/ethereum-contracts/package.json +++ b/packages/ethereum-contracts/package.json @@ -78,10 +78,12 @@ }, "dependencies": { "@decentral.ee/web3-helpers": "0.5.3", + "@nomiclabs/hardhat-ethers": "^2.2.3", "@openzeppelin/contracts": "4.9.3", "@truffle/contract": "4.6.29", "ethereumjs-tx": "2.1.2", - "ethereumjs-util": "7.1.5" + "ethereumjs-util": "7.1.5", + "hardhat": "^2.17.3" }, "devDependencies": { "@nomiclabs/hardhat-truffle5": "^2.0.7", From ea3117d69382b6f06208ecd5959d2d042fe01f09 Mon Sep 17 00:00:00 2001 From: 0xdavinchee <0xdavinchee@gmail.com> Date: Mon, 23 Oct 2023 11:21:09 +0300 Subject: [PATCH 2/3] more meaningful jsdoc --- .../dev-scripts/deploy-contracts-and-token.js | 2 +- .../dev-scripts/deploy-test-framework.js | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js b/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js index 398e6aa1cd..653c9f9257 100644 --- a/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js +++ b/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js @@ -8,7 +8,7 @@ const { async function deployContractsAndToken() { const [Deployer] = await ethers.getSigners(); - const {frameworkDeployer: deployer} = await deployTestFramework(null, ethers.provider, Deployer); + const {frameworkDeployer: deployer} = await deployTestFramework(ethers.provider, null, Deployer); const framework = await deployer.getFramework(); const resolver = await ethers.getContractAt( diff --git a/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js b/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js index 15447cbe94..f92150af20 100644 --- a/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js +++ b/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js @@ -96,13 +96,16 @@ const _getFactoryAndReturnDeployedContract = async ( /** * Deploys Superfluid Framework in local testing environments. + * * NOTE: This only works with Hardhat + ethers v5/ethers v6 currently. - * @param privateKey NEVER USE A PRIVATE KEY WITH REAL FUNDS - a test account private key + * + * You must pass either a `privateKey` string OR an `ethersV5Signer` object * @param provider an ethers provider - * @param ethersV5Signer an ethers v5 signer + * @param {string} [privateKey] NEVER USE A PRIVATE KEY WITH REAL FUNDS - a test account private key + * @param {ethers.providers.Provider} [ethersV5Signer] an ethers v5 signer * @returns */ -const deployTestFramework = async (privateKey, provider, ethersV5Signer) => { +const deployTestFramework = async (provider, privateKey, ethersV5Signer) => { // use a passed signer OR create one on the spot const signer = ethersV5Signer || new ethers.Wallet(privateKey, provider); await deployERC1820(provider); @@ -235,7 +238,6 @@ const deployTestFramework = async (privateKey, provider, ethersV5Signer) => { for (let i = 0; i < numSteps; i++) { await sfDeployer.executeStep(i); } - const sf = await sfDeployer.getFramework(); return {frameworkDeployer: sfDeployer}; }; From 1756636afadf08082bbe9a423992d2fe13aba66f Mon Sep 17 00:00:00 2001 From: 0xdavinchee <0xdavinchee@gmail.com> Date: Tue, 24 Oct 2023 16:05:53 +0300 Subject: [PATCH 3/3] add new functions for dev-scripts deployment --- packages/ethereum-contracts/CHANGELOG.md | 4 ++ .../dev-scripts/deploy-contracts-and-token.js | 5 +- .../dev-scripts/deploy-test-framework.js | 68 ++++++++++++++----- .../ethereum-contracts/dev-scripts/index.js | 10 ++- 4 files changed, 68 insertions(+), 19 deletions(-) diff --git a/packages/ethereum-contracts/CHANGELOG.md b/packages/ethereum-contracts/CHANGELOG.md index 7a87587457..1e022c7bd3 100644 --- a/packages/ethereum-contracts/CHANGELOG.md +++ b/packages/ethereum-contracts/CHANGELOG.md @@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## Unreleased ### Breaking + - `TokenInfo` and `ERC20WithTokenInfo` interface/abstract contract are removed from the codebase, including the bundled ABI contracts - Migration: Use `IERC20Metadata` instead, as this replaces the previous contracts - `build/typechain-ethers-v5` is removed from the npm package @@ -25,8 +26,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Note that the admin is stored in the EIP-1967 admin storage slot (`0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`) - `SuperToken.getAdmin()` added to retrieve the admin address - `SuperTokenFactory.createERC20Wrapper()` overloads added to create a SuperToken AND explicitly initialize a SuperToken with an admin +- New explicit functions: `deployTestFrameworkWithEthersV5` and `deployTestFrameworkWithEthersV6` in `deploy-test-framework.js` + - `deployTestFramework` is still there, but it is considered deprecated now ### Changed + - Reuse config keys from `SuperfluidGovernanceConfigs` instead of duplicating them in `ConstantFlowAgreementV1`. - Deprecating `registerAppWithKey` and `registerAppByFactory`: DO NOT USE for new deployments - Simplification of Super App registration: use `registerApp` in all cases going forward. diff --git a/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js b/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js index 653c9f9257..a350f665eb 100644 --- a/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js +++ b/packages/ethereum-contracts/dev-scripts/deploy-contracts-and-token.js @@ -2,13 +2,14 @@ const {ethers} = require("hardhat"); const testResolverArtifact = require("@superfluid-finance/ethereum-contracts/build/hardhat/contracts/utils/TestResolver.sol/TestResolver.json"); const { - deployTestFramework, + deployTestFrameworkWithEthersV5, } = require("@superfluid-finance/ethereum-contracts/dev-scripts/deploy-test-framework"); async function deployContractsAndToken() { const [Deployer] = await ethers.getSigners(); - const {frameworkDeployer: deployer} = await deployTestFramework(ethers.provider, null, Deployer); + const {frameworkDeployer: deployer} = + await deployTestFrameworkWithEthersV5(Deployer); const framework = await deployer.getFramework(); const resolver = await ethers.getContractAt( diff --git a/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js b/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js index f92150af20..348b5b631a 100644 --- a/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js +++ b/packages/ethereum-contracts/dev-scripts/deploy-test-framework.js @@ -1,4 +1,5 @@ const {ethers} = require("hardhat"); +const {JsonRpcProvider} = require("@ethersproject/providers"); const SuperfluidGovDeployerLibraryArtifact = require("@superfluid-finance/ethereum-contracts/build/hardhat/contracts/utils/SuperfluidFrameworkDeploymentSteps.sol/SuperfluidGovDeployerLibrary.json"); const SuperfluidHostDeployerLibraryArtifact = require("@superfluid-finance/ethereum-contracts/build/hardhat/contracts/utils/SuperfluidFrameworkDeploymentSteps.sol/SuperfluidHostDeployerLibrary.json"); @@ -76,7 +77,6 @@ const _getFactoryAndReturnDeployedContract = async ( signerOrOptions ); const contract = await ContractFactory.deploy(...args); - // ethers v5 if (contract.deployed) { await contract.deployed(); @@ -94,20 +94,22 @@ const _getFactoryAndReturnDeployedContract = async ( return contract; }; -/** - * Deploys Superfluid Framework in local testing environments. - * - * NOTE: This only works with Hardhat + ethers v5/ethers v6 currently. - * - * You must pass either a `privateKey` string OR an `ethersV5Signer` object - * @param provider an ethers provider - * @param {string} [privateKey] NEVER USE A PRIVATE KEY WITH REAL FUNDS - a test account private key - * @param {ethers.providers.Provider} [ethersV5Signer] an ethers v5 signer - * @returns - */ -const deployTestFramework = async (provider, privateKey, ethersV5Signer) => { - // use a passed signer OR create one on the spot - const signer = ethersV5Signer || new ethers.Wallet(privateKey, provider); +const deployTestFrameworkWithEthersV6 = async (privateKey, provider) => { + if (!privateKey) throw new Error("You must pass a private key."); + if (!provider) throw new Error("You must pass a provider."); + + const signer = new ethers.Wallet(privateKey, provider); + + return await _deployTestFramework(provider, signer); +}; + +const deployTestFrameworkWithEthersV5 = async (ethersV5Signer) => { + if (!ethersV5Signer.provider) + throw new Error("Your signer must have a provider."); + return await _deployTestFramework(ethersV5Signer.provider, ethersV5Signer); +}; + +const _deployTestFramework = async (provider, signer) => { await deployERC1820(provider); const SlotsBitmapLibrary = await _getFactoryAndReturnDeployedContract( "SlotsBitmapLibrary", @@ -143,7 +145,6 @@ const deployTestFramework = async (provider, privateKey, ethersV5Signer) => { }, } ); - const SuperTokenDeployerLibrary = await _getFactoryAndReturnDeployedContract( "SuperTokenDeployerLibrary", @@ -241,6 +242,41 @@ const deployTestFramework = async (provider, privateKey, ethersV5Signer) => { return {frameworkDeployer: sfDeployer}; }; +const printProtocolFrameworkAddresses = (framework) => { + const output = { + Host: framework.host, + CFAv1: framework.cfa, + IDAv1: framework.ida, + SuperTokenFactory: framework.superTokenFactory, + SuperTokenLogic: framework.superTokenLogic, + ConstantOutflowNFT: framework.constantOutflowNFT, + ConstantInflowNFT: framework.constantInflowNFT, + Resolver: framework.resolver, + SuperfluidLoader: framework.superfluidLoader, + CFAv1Forwarder: framework.cfaV1Forwarder, + IDAv1Forwarder: framework.idaV1Forwarder, + }; + + console.log(JSON.stringify(output, null, 2)); + + return output; +}; + +/** + * {DEPRECATED} + * Deploys Superfluid Framework in local testing environments. + * + * NOTE: This only works with Hardhat + ethers v5. + * @returns SuperfluidFrameworkDeployer Contract object + */ +const deployTestFramework = async () => { + const signer = (await ethers.getSigners())[0]; + return await deployTestFrameworkWithEthersV5(signer); +}; + module.exports = { deployTestFramework, + deployTestFrameworkWithEthersV5, + deployTestFrameworkWithEthersV6, + printProtocolFrameworkAddresses, }; diff --git a/packages/ethereum-contracts/dev-scripts/index.js b/packages/ethereum-contracts/dev-scripts/index.js index feeb1da565..d2531ef3b7 100644 --- a/packages/ethereum-contracts/dev-scripts/index.js +++ b/packages/ethereum-contracts/dev-scripts/index.js @@ -1,5 +1,13 @@ -const deployTestFramework = require("./deploy-test-framework"); +const { + deployTestFramework, + deployTestFrameworkWithEthersV5, + deployTestFrameworkWithEthersV6, + printProtocolFrameworkAddresses +} = require("./deploy-test-framework"); module.exports = { + deployTestFrameworkWithEthersV6, + deployTestFrameworkWithEthersV5, deployTestFramework, + printProtocolFrameworkAddresses };