From bf399fc5416d6d6c0624e4b51fa5f85ae2ec97d0 Mon Sep 17 00:00:00 2001 From: cujowolf <92617969+cujowolf@users.noreply.github.com> Date: Fri, 17 Feb 2023 13:32:50 -0600 Subject: [PATCH] Add upgrade script and correct issue on not incrementing project retirement totals (#35) --- .../facets/Bridges/C3/RetireC3C3TFacet.sol | 4 +- .../Bridges/Toucan/RetireToucanTCO2Facet.sol | 4 +- .../diamond/init/InitProjectTotals.sol | 19 + .../infinity/diamond/init/_EmptyInit.sol | 8 + contracts/infinity/libraries/LibRetire.sol | 1 + hardhat.config.js | 19 + scripts/diamond.js | 519 ++++++++++++++++++ scripts/infinity/deploy_dao_fee_split.js | 30 + scripts/infinity/deploy_redeem_swap.js | 22 + test/utils/constants.js | 3 + utils/contracts.js | 9 + 11 files changed, 634 insertions(+), 4 deletions(-) create mode 100644 contracts/infinity/diamond/init/InitProjectTotals.sol create mode 100644 contracts/infinity/diamond/init/_EmptyInit.sol create mode 100644 scripts/diamond.js create mode 100644 scripts/infinity/deploy_dao_fee_split.js create mode 100644 scripts/infinity/deploy_redeem_swap.js create mode 100644 utils/contracts.js diff --git a/contracts/infinity/diamond/facets/Bridges/C3/RetireC3C3TFacet.sol b/contracts/infinity/diamond/facets/Bridges/C3/RetireC3C3TFacet.sol index 33413cbd..d499cce8 100644 --- a/contracts/infinity/diamond/facets/Bridges/C3/RetireC3C3TFacet.sol +++ b/contracts/infinity/diamond/facets/Bridges/C3/RetireC3C3TFacet.sol @@ -34,7 +34,7 @@ contract RetireC3C3TFacet is ReentrancyGuard { * @param fromMode From Mode for transfering tokens * @return retirementIndex The latest retirement index for the beneficiary address */ - function c3_retireExactC3T( + function c3RetireExactC3T( address carbonToken, uint256 amount, address beneficiaryAddress, @@ -73,7 +73,7 @@ contract RetireC3C3TFacet is ReentrancyGuard { * @param fromMode From Mode for transfering tokens * @return retirementIndex The latest retirement index for the beneficiary address */ - function c3_retireExactC3TWithEntity( + function c3RetireExactC3TWithEntity( address carbonToken, uint256 amount, string memory retiringEntityString, diff --git a/contracts/infinity/diamond/facets/Bridges/Toucan/RetireToucanTCO2Facet.sol b/contracts/infinity/diamond/facets/Bridges/Toucan/RetireToucanTCO2Facet.sol index 775bb269..5fee6998 100644 --- a/contracts/infinity/diamond/facets/Bridges/Toucan/RetireToucanTCO2Facet.sol +++ b/contracts/infinity/diamond/facets/Bridges/Toucan/RetireToucanTCO2Facet.sol @@ -34,7 +34,7 @@ contract RetireToucanTCO2Facet is ReentrancyGuard { * @param fromMode From Mode for transfering tokens * @return retirementIndex The latest retirement index for the beneficiary address */ - function toucan_retireExactTCO2( + function toucanRetireExactTCO2( address carbonToken, uint256 amount, address beneficiaryAddress, @@ -73,7 +73,7 @@ contract RetireToucanTCO2Facet is ReentrancyGuard { * @param fromMode From Mode for transfering tokens * @return retirementIndex The latest retirement index for the beneficiary address */ - function toucan_retireExactTCO2WithEntity( + function toucanRetireExactTCO2WithEntity( address carbonToken, uint256 amount, string memory retiringEntityString, diff --git a/contracts/infinity/diamond/init/InitProjectTotals.sol b/contracts/infinity/diamond/init/InitProjectTotals.sol new file mode 100644 index 00000000..a6c9f078 --- /dev/null +++ b/contracts/infinity/diamond/init/InitProjectTotals.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../AppStorage.sol"; + +contract InitProjectTotals { + + AppStorage internal s; + + function init() external { + // Update the project amounts retired for transactions sent through V2 thus far + + s.a[0x20A580444DD4A90Cc8990DA7B480C5E3d605a26f].totalProjectRetired[0xb139C4cC9D20A3618E9a2268D73Eff18C496B991] += uint(1000000000000000); + s.a[0x808b891a69f2cF52f84228DA61f2F4F5b08297DE].totalProjectRetired[0xb139C4cC9D20A3618E9a2268D73Eff18C496B991] += uint(956844938827); + s.a[0x808b891a69f2cF52f84228DA61f2F4F5b08297DE].totalProjectRetired[0xb139C4cC9D20A3618E9a2268D73Eff18C496B991] += uint(956844938829); + s.a[0xDdfF75A29EB4BFEcF65380de9a75ad08C140eA49].totalProjectRetired[0xb139C4cC9D20A3618E9a2268D73Eff18C496B991] += uint(966561401954341706); + s.a[0x6F9F81eb4f54512Be8c91833783ee0074328E062].totalProjectRetired[0xb139C4cC9D20A3618E9a2268D73Eff18C496B991] += uint(1000000000000000); + } +} diff --git a/contracts/infinity/diamond/init/_EmptyInit.sol b/contracts/infinity/diamond/init/_EmptyInit.sol new file mode 100644 index 00000000..c19afb51 --- /dev/null +++ b/contracts/infinity/diamond/init/_EmptyInit.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract _EmptyInit { + + function init() external { + } +} diff --git a/contracts/infinity/libraries/LibRetire.sol b/contracts/infinity/libraries/LibRetire.sol index 49170d81..33b9c600 100644 --- a/contracts/infinity/libraries/LibRetire.sol +++ b/contracts/infinity/libraries/LibRetire.sol @@ -275,6 +275,7 @@ library LibRetire { // Save the details of the retirement s.a[beneficiaryAddress].retirements[currentRetirementIndex].projectTokenAddress = projectToken; + s.a[beneficiaryAddress].totalProjectRetired[projectToken] += amount; } /* ========== Account Getters ========== */ diff --git a/hardhat.config.js b/hardhat.config.js index 881242ec..34dc3529 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -1,6 +1,7 @@ const { utils } = require("ethers"); const fs = require("fs"); const chalk = require("chalk"); +const { daoFeeUpgrade } = require("./scripts/infinity/deploy_dao_fee_split"); require("@nomiclabs/hardhat-etherscan"); require("@tenderly/hardhat-tenderly"); @@ -12,6 +13,7 @@ require("@openzeppelin/hardhat-upgrades"); require("dotenv").config(); require("@nomiclabs/hardhat-etherscan"); +require("hardhat-contract-sizer") require("hardhat-gas-reporter"); require("solidity-coverage"); @@ -31,6 +33,11 @@ task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { } }); +task("upgrade", async () => { + account = await ethers.getSigner() + await daoFeeUpgrade(true, account) +}) + task('diamondABI', 'Generates ABI file for diamond, includes all ABIs of facets and subdirectories', async () => { var walk = function (dir) { var results = []; @@ -183,6 +190,13 @@ module.exports = { accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], }, + polygon: { + url: process.env.POLYGON_URL || "", + gasPrice: 150e9, + timeout: 100000, + accounts: + process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + }, }, gasReporter: { enabled: process.env.REPORT_GAS !== undefined, @@ -190,6 +204,11 @@ module.exports = { }, etherscan: { apiKey: process.env.ETHERSCAN_API_KEY, + customChains: [], + }, + polygonscan: { + apiKey: process.env.ETHERSCAN_API_KEY, + customChains: [], }, }; diff --git a/scripts/diamond.js b/scripts/diamond.js new file mode 100644 index 00000000..e7c458ef --- /dev/null +++ b/scripts/diamond.js @@ -0,0 +1,519 @@ +const { INFINITY } = require("../test/utils/constants") +// const { impersonateInfinity } = require("./impersonate") +const fs = require('fs') + +const FacetCutAction = { + Add: 0, + Replace: 1, + Remove: 2 +} + +// eslint-disable-next-line no-unused-vars +function getSignatures(contract) { + return Object.keys(contract.interface.functions) +} + +function addCommas(nStr) { + nStr += '' + const x = nStr.split('.') + let x1 = x[0] + const x2 = x.length > 1 ? '.' + x[1] : '' + var rgx = /(\d+)(\d{3})/ + while (rgx.test(x1)) { + x1 = x1.replace(rgx, '$1' + ',' + '$2') + } + return x1 + x2 +} + +function strDisplay(str) { + return addCommas(str.toString()) +} + +function getSelectors(contract) { + const signatures = Object.keys(contract.interface.functions) + const selectors = signatures.reduce((acc, val) => { + if (val !== 'init(bytes)' && val !== 'c_0x4820c4cf(bytes32)') { + acc.push(contract.interface.getSighash(val)) + } + return acc + }, []) + return selectors +} + +async function deployFacets(facets, verbose = false) { + if (verbose) console.log('--') + const deployed = [] + for (const facet of facets) { + if (Array.isArray(facet)) { + if (typeof facet[0] !== 'string') { + throw Error(`Error using facet: facet name must be a string. Bad input: ${facet[0]}`) + } + if (!(facet[1] instanceof ethers.Contract)) { + throw Error(`Error using facet: facet must be a Contract. Bad input: ${facet[1]}`) + } + if (verbose) console.log(`Using already deployed ${facet[0]}: ${facet[1].address}`) + if (verbose) console.log('--') + deployed.push(facet) + } else { + if (typeof facet !== 'string') { + throw Error(`Error deploying facet: facet name must be a string. Bad input: ${facet}`) + } + const facetFactory = await ethers.getContractFactory(facet, account) + if (verbose) console.log(`Deploying ${facet}`) + const deployedFactory = await facetFactory.deploy() + await deployedFactory.deployed() + await deployedFactory.deployTransaction.wait() + if (verbose) console.log(`${facet} deployed: ${deployedFactory.address}`) + if (verbose) console.log('--') + deployed.push([facet, deployedFactory]) + } + } + return deployed +} + +async function deploy({ + diamondName, + initDiamond, + facets, + owner, + libraryNames = [], + facetLibraries = {}, + args = [], + verbose = false, + txArgs = {}, + impersonate = false +}) { + if (arguments.length !== 1) { + throw Error(`Requires only 1 map argument. ${arguments.length} arguments used.`) + } + facets = await deployFacets(facets, verbose) + const diamondFactory = await ethers.getContractFactory('Diamond') + const diamondCut = [] + if (verbose) { + console.log('--') + console.log('Setting up diamondCut args') + console.log('--') + } + for (const [name, deployedFacet] of facets) { + if (verbose) { + console.log(name) + console.log(getSignatures(deployedFacet)) + console.log('--') + } + diamondCut.push([ + deployedFacet.address, + FacetCutAction.Add, + getSelectors(deployedFacet) + ]) + } + if (verbose) console.log('--') + + let result + if (typeof initDiamond === 'string') { + const initDiamondName = initDiamond + if (verbose) console.log(`Deploying ${initDiamondName}`) + initDiamond = await ethers.getContractFactory(initDiamond) + initDiamond = await initDiamond.deploy() + await initDiamond.deployed() + result = await initDiamond.deployTransaction.wait() + if (!result.status) { + throw (Error(`Deploying ${initDiamondName} TRANSACTION FAILED!!! -------------------------------------------`)) + } + } + + if (verbose) console.log('Encoding diamondCut init function call') + const functionCall = initDiamond.interface.encodeFunctionData('init', args) + + if (verbose) console.log(`Deploying ${diamondName}`) + + let deployedDiamond + if (!impersonate) { + deployedDiamond = await diamondFactory.deploy(owner) + await deployedDiamond.deployed() + result = await deployedDiamond.deployTransaction.wait() + if (!result.status) { + console.log('Deploying diamond TRANSACTION FAILED!!! -------------------------------------------') + console.log('See block explorer app for details.') + console.log('Transaction hash:' + deployedDiamond.deployTransaction.hash) + throw (Error('failed to deploy diamond')) + } + if (verbose) console.log('Diamond deploy transaction hash:' + deployedDiamond.deployTransaction.hash) + + if (verbose) console.log(`${diamondName} deployed: ${deployedDiamond.address}`) + if (verbose) console.log(`Diamond owner: ${owner}`) + } else { + // await impersonateInfinity(owner) + // deployedDiamond = await ethers.getContractAt('Diamond', INFINITY) + } + + const diamondCutFacet = await ethers.getContractAt('DiamondCutFacet', deployedDiamond.address) + const tx = await diamondCutFacet.diamondCut(diamondCut, initDiamond.address, functionCall, txArgs) + + // console.log(`${diamondName} diamondCut arguments:`) + // console.log(JSON.stringify([facets, initDiamond.address, args], null, 4)) + result = await tx.wait() + if (!result.status) { + console.log('TRANSACTION FAILED!!! -------------------------------------------') + console.log('See block explorer app for details.') + } + if (verbose) console.log('DiamondCut success!') + if (verbose) console.log('Transaction hash:' + tx.hash) + if (verbose) console.log('--') + return [deployedDiamond, result] +} + +function inFacets(selector, facets) { + for (const facet of facets) { + if (facet.functionSelectors.includes(selector)) { + return true + } + } + return false +} + +async function upgrade({ + diamondAddress, + diamondCut, + txArgs = {}, + initFacetName = undefined, + initArgs +}) { + if (arguments.length !== 1) { + throw Error(`Requires only 1 map argument. ${arguments.length} arguments used.`) + } + const diamondCutFacet = await ethers.getContractAt('DiamondCutFacet', diamondAddress) + const diamondLoupeFacet = await ethers.getContractAt('DiamondLoupeFacet', diamondAddress) + const existingFacets = await diamondLoupeFacet.facets() + const facetFactories = new Map() + + console.log('Facet Signatures and Selectors: ') + for (const facet of diamondCut) { + const functions = new Map() + const selectors = [] + console.log('Facet: ' + facet) + let facetName + let contract + if (Array.isArray(facet[0])) { + facetName = facet[0][0] + contract = facet[0][1] + if (!(typeof facetName === 'string')) { + throw Error('First value in facet[0] array must be a string.') + } + if (!(contract instanceof ethers.Contract)) { + throw Error('Second value in facet[0] array must be a Contract object.') + } + facet[0] = facetName + } else { + facetName = facet[0] + if (!(typeof facetName === 'string') && facetName) { + throw Error('facet[0] must be a string or an array or false.') + } + } + for (const signature of facet[2]) { + const selector = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(signature)).slice(0, 10) + console.log(`Function: ${selector} ${signature}`) + selectors.push(selector) + functions.set(selector, signature) + } + if (facet[1] === FacetCutAction.Remove) { + if (facetName) { + throw (Error(`Can't remove functions because facet name must have a false value not ${facetName}.`)) + } + facet[0] = ethers.constants.AddressZero + for (const selector of selectors) { + if (!inFacets(selector, existingFacets)) { + const signature = functions.get(selector) + throw Error(`Can't remove '${signature}'. It doesn't exist in deployed diamond.`) + } + } + facet[2] = selectors + } else if (facet[1] === FacetCutAction.Replace) { + let facetFactory = facetFactories.get(facetName) + if (!facetFactory) { + if (contract) { + facetFactories.set(facetName, contract) + } else { + facetFactory = await ethers.getContractFactory(facetName) + facetFactories.set(facetName, facetFactory) + } + } + for (const signature of facet[2]) { + if (!Object.prototype.hasOwnProperty.call(facetFactory.interface.functions, signature)) { + throw (Error(`Can't replace '${signature}'. It doesn't exist in ${facetName} source code.`)) + } + } + for (const selector of selectors) { + if (!inFacets(selector, existingFacets)) { + const signature = functions.get(selector) + throw Error(`Can't replace '${signature}'. It doesn't exist in deployed diamond.`) + } + } + facet[2] = selectors + } else if (facet[1] === FacetCutAction.Add) { + let facetFactory = facetFactories.get(facetName) + if (!facetFactory) { + if (contract) { + facetFactories.set(facetName, contract) + } else { + facetFactory = await ethers.getContractFactory(facetName, account) + facetFactories.set(facetName, facetFactory) + } + } + for (const signature of facet[2]) { + if (!Object.prototype.hasOwnProperty.call(facetFactory.interface.functions, signature)) { + throw (Error(`Can't add ${signature}. It doesn't exist in ${facetName} source code.`)) + } + } + for (const selector of selectors) { + if (inFacets(selector, existingFacets)) { + const signature = functions.get(selector) + throw Error(`Can't add '${signature}'. It already exists in deployed diamond.`) + } + } + facet[2] = selectors + } else { + throw (Error('Incorrect FacetCutAction value. Must be 0, 1 or 2. Value used: ' + facet[1])) + } + } + // deploying new facets + const alreadDeployed = new Map() + for (const facet of diamondCut) { + if (facet[1] !== FacetCutAction.Remove) { + const existingAddress = alreadDeployed.get(facet[0]) + if (existingAddress) { + facet[0] = existingAddress + continue + } + console.log(`Deploying ${facet[0]}`) + const facetFactory = facetFactories.get(facet[0]) + let deployedFacet = facetFactory + if (!(deployedFacet instanceof ethers.Contract)) { + deployedFacet = await facetFactory.deploy() + await deployedFacet.deployed() + await deployedFacet.deployTransaction.wait() + } + facetFactories.set(facet[0], deployedFacet) + console.log(`${facet[0]} deployed: ${deployedFacet.address}`) + alreadDeployed.set(facet[0], deployedFacet.address) + facet[0] = deployedFacet.address + } + } + + console.log('diamondCut arg:') + console.log(diamondCut) + + let initFacetAddress = ethers.constants.AddressZero + let functionCall = '0x' + if (initFacetName !== undefined) { + let initFacet = facetFactories.get(initFacetName) + if (!initFacet) { + const InitFacet = await ethers.getContractFactory(initFacetName, account) + initFacet = await InitFacet.deploy() + await initFacet.deployed() + await initFacet.deployTransaction.wait() + console.log('Deployed init facet: ' + initFacet.address) + } else { + console.log('Using init facet: ' + initFacet.address) + } + functionCall = initFacet.interface.encodeFunctionData('init', initArgs) + console.log('Function call: ') + console.log(functionCall) + initFacetAddress = initFacet.address + } + + const result = await diamondCutFacet.diamondCut( + diamondCut, + initFacetAddress, + functionCall, + txArgs + ) + const receipt = await result.wait() + if (!receipt.status) { + console.log('TRANSACTION FAILED!!! -------------------------------------------') + console.log('See block explorer app for details.') + } + console.log('------') + console.log('Upgrade transaction hash: ' + result.hash) + return result +} + +async function upgradeWithNewFacets({ + diamondAddress, + facetNames = [], + facetLibraries = {}, + libraryNames = [], + selectorsToRemove = [], + selectorsToAdd = {}, + initFacetName = undefined, + initArgs = [], + libraries = {}, + initFacetAddress = ethers.constants.AddressZero, + object = false, + p = 0, + verbose = false, + account = null +}) { + + let totalGasUsed = ethers.BigNumber.from('0') + + if (arguments.length !== 1) { + throw Error(`Requires only 1 map argument. ${arguments.length} arguments used.`) + } + const diamondCutFacet = await ethers.getContractAt('DiamondCutFacet', diamondAddress) + const diamondLoupeFacet = await ethers.getContractAt('DiamondLoupeFacet', diamondAddress) + + const diamondCut = [] + const existingFacets = await diamondLoupeFacet.facets() + const undeployed = [] + const deployed = [] + if (verbose && libraryNames.length > 0) console.log('Deploying Libraries') + for (const name of libraryNames) { + if (!Object.keys(libraries).includes(name)) { + if (verbose) console.log(`Deploying: ${name}`) + let libraryFactory = await ethers.getContractFactory(name, account) + libraryFactory = await libraryFactory.deploy() + await libraryFactory.deployed() + const receipt = await libraryFactory.deployTransaction.wait() + if (verbose) console.log(`${name} deploy gas used: ` + strDisplay(receipt.gasUsed)) + totalGasUsed = totalGasUsed.add(receipt.gasUsed) + if (verbose) console.log(`Deployed at ${libraryFactory.address}`) + libraries[name] = libraryFactory.address + } + } + if (verbose && facetNames.length > 0) console.log('\nDeploying Facets') + for (const name of facetNames) { + let facetFactory + if (facetLibraries[name] !== undefined) { + let facetLibrary = Object.keys(libraries).reduce((acc, val) => { + if (facetLibraries[name].includes(val)) acc[val] = libraries[val]; + return acc; + }, {}); + facetFactory = await ethers.getContractFactory(name, { + libraries: facetLibrary + }, + account + ); + } + else facetFactory = await ethers.getContractFactory(name, account) + undeployed.push([name, facetFactory]) + } + if (verbose) console.log('') + if (selectorsToRemove.length > 0) { + // check if any selectorsToRemove are already gone + for (const selector of selectorsToRemove) { + if (!inFacets(selector, existingFacets)) { + throw Error('Function selector to remove is already gone.') + } + } + diamondCut.push([ + ethers.constants.AddressZero, + FacetCutAction.Remove, + selectorsToRemove + ]) + } + + for (const [name, facetFactory] of undeployed) { + const deployedFactory = await facetFactory.deploy(); + if (verbose) console.log(`${name} hash: ${deployedFactory.deployTransaction.hash}`); + await deployedFactory.deployed() + const receipt = await deployedFactory.deployTransaction.wait() + if (verbose) console.log(`${name} deploy gas used: ` + strDisplay(receipt.gasUsed)) + totalGasUsed = totalGasUsed.add(receipt.gasUsed) + if (verbose) console.log(`${name} deployed: ${deployedFactory.address}`) + if (verbose) console.log('--') + const add = [] + const replace = [] + const selectors = selectorsToAdd[name] !== undefined ? selectorsToAdd[name] : getSelectors(deployedFactory) + for (const selector of selectors) { + if (!inFacets(selector, existingFacets)) { + add.push(selector) + } else { + replace.push(selector) + } + } + if (add.length > 0) { + diamondCut.push([deployedFactory.address, FacetCutAction.Add, add]) + } + if (replace.length > 0) { + diamondCut.push([ + deployedFactory.address, + FacetCutAction.Replace, + replace + ]) + } + } + if (verbose) { + console.log('diamondCut arg:') + console.log(diamondCut) + console.log('------') + } + + let functionCall = '0x' + if (initFacetName !== undefined) { + let initFacet + for (const [name, deployedFactory] of deployed) { + if (name === initFacetName) { + initFacet = deployedFactory + const receipt = await deployedFactory.deployTransaction.wait() + if (verbose) console.log(`${name} deploy gas used: ` + strDisplay(receipt.gasUsed)) + totalGasUsed = totalGasUsed.add(receipt.gasUsed) + break + } + } + + if (!initFacet) { + const InitFacet = await ethers.getContractFactory(initFacetName, account) + initFacet = await InitFacet.deploy() + await initFacet.deployed() + const receipt = await initFacet.deployTransaction.wait() + if (verbose) console.log(`Init Diamond deploy gas used: ` + strDisplay(receipt.gasUsed)) + totalGasUsed = totalGasUsed.add(receipt.gasUsed) + if (verbose) console.log('Deployed init facet: ' + initFacet.address) + } else { + if (verbose) console.log('Using init facet: ' + initFacet.address) + } + functionCall = initFacet.interface.encodeFunctionData('init', initArgs) + if (verbose) console.log(`Function call: ${functionCall.toString().substring(0, 100)}`) + initFacetAddress = initFacet.address + } + let result; + if (object) { + dc = { + diamondCut: diamondCut, + initFacetAddress: initFacetAddress, + functionCall: functionCall + } + const encodedDiamondCut = await diamondCutFacet.interface.encodeFunctionData('diamondCut', Object.values(dc)) + console.log(JSON.stringify(dc, null, 4)) + console.log("Encoded: -------------------------------------------------------------") + console.log(encodedDiamondCut) + const dcName = `diamondCut-${initFacetName}-${Math.floor(Date.now() / 1000)}-${facetNames.length}-facets.json` + await fs.writeFileSync(`./diamondCuts/${dcName}`, JSON.stringify({ diamondCut: dc, encoded: encodedDiamondCut }, null, 4)); + return dc + } + + result = await diamondCutFacet.connect(account).diamondCut( + diamondCut, + initFacetAddress, + functionCall + ) + + const receipt = await result.wait(); + totalGasUsed = totalGasUsed.add(receipt.gasUsed) + if (verbose) { + console.log('------') + console.log('Upgrade transaction hash: ' + result.hash) + console.log(`Diamond Cut Gas Used: ` + strDisplay(receipt.gasUsed)); + console.log('Total gas used: ' + strDisplay(totalGasUsed)) + } + return result +} + +exports.FacetCutAction = FacetCutAction +exports.upgrade = upgrade +exports.upgradeWithNewFacets = upgradeWithNewFacets +exports.getSelectors = getSelectors +exports.deployFacets = deployFacets +exports.deploy = deploy +exports.inFacets = inFacets +exports.upgrade = upgrade diff --git a/scripts/infinity/deploy_dao_fee_split.js b/scripts/infinity/deploy_dao_fee_split.js new file mode 100644 index 00000000..dce291d1 --- /dev/null +++ b/scripts/infinity/deploy_dao_fee_split.js @@ -0,0 +1,30 @@ +const { getInfinity } = require("../../utils/contracts") +const fs = require('fs'); +const { upgradeWithNewFacets } = require("../diamond"); +const { INFINITY } = require("../../test/utils/constants"); + +// const EVENTS_JSON = './scripts/path-to-data.json' + +async function daoFeeUpgrade(mock = true, account = undefined) { + + infinity = await getInfinity() + await upgradeWithNewFacets({ + diamondAddress: INFINITY, + facetNames: [ + 'RedeemC3PoolFacet', + 'RetireC3C3TFacet', + 'RedeemToucanPoolFacet', + 'RetireToucanTCO2Facet', + 'RetireCarbonFacet', + 'RetireSourceFacet' + ], + initFacetName: 'InitProjectTotals', + // initArgs: [], + selectorsToRemove: ['0x2687d2f1', '0xb1d2b058', '0xa9f2bd90', '0x72d09fe2'], + object: !mock, + verbose: true, + account: account + }); +} + +exports.daoFeeUpgrade = daoFeeUpgrade diff --git a/scripts/infinity/deploy_redeem_swap.js b/scripts/infinity/deploy_redeem_swap.js new file mode 100644 index 00000000..02583966 --- /dev/null +++ b/scripts/infinity/deploy_redeem_swap.js @@ -0,0 +1,22 @@ +const { getInfinity } = require("../../utils/contracts") +const fs = require('fs'); +const { upgradeWithNewFacets } = require("../diamond"); +const { INFINITY } = require("../../test/utils/constants"); + +async function redeemSwap(mock = true, account = undefined) { + + + infinity = await getInfinity() + await upgradeWithNewFacets({ + diamondAddress: INFINITY, + facetNames: ['RetirementQuoter'], + // initFacetName: , + // initArgs: [], + // selectorsToRemove: ['0xf0ff264c', '0x79f5e053', '0x7eed24a2'], + object: !mock, + verbose: true, + account: account + }); +} + +exports.redeemSwap = redeemSwap diff --git a/test/utils/constants.js b/test/utils/constants.js index 2ff3d275..6e406d38 100644 --- a/test/utils/constants.js +++ b/test/utils/constants.js @@ -8,6 +8,9 @@ module.exports = { SKLIMA: '0xb0C22d8D350C67420f06F48936654f567C73E8C8', WSKLIMA: '0x6f370dba99E32A3cAD959b341120DB3C9E280bA6', DAO: '0x65a5076c0ba74e5f3e069995dc3dab9d197d995c', + + INFINITY: '0x8cE54d9625371fb2a068986d32C85De8E6e995f8', + // Carbon Tokens BCT: '0x2F800Db0fdb5223b3C3f354886d907A671414A7F', NCT: '0xD838290e877E0188a4A44700463419ED96c16107', diff --git a/utils/contracts.js b/utils/contracts.js new file mode 100644 index 00000000..c53b8970 --- /dev/null +++ b/utils/contracts.js @@ -0,0 +1,9 @@ +const fs = require('fs'); +const infinityABI = require("../abi/KlimaInfinity.json"); +const { INFINITY } = require('../test/utils/constants'); + +async function getInfinity() { + return await ethers.getContractAt(infinityABI, INFINITY); +} + +exports.getInfinity = getInfinity;