From a194821a22dfc39a6451764d88ec76a44681942f Mon Sep 17 00:00:00 2001 From: Aimen Sahnoun Date: Wed, 30 Oct 2024 15:30:58 +0300 Subject: [PATCH 1/4] feat: add `SingleRequestProxyFactory` artifacts to getArtifacts method --- packages/smart-contracts/scripts-create2/utils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/smart-contracts/scripts-create2/utils.ts b/packages/smart-contracts/scripts-create2/utils.ts index 90db473d0..b71761ae8 100644 --- a/packages/smart-contracts/scripts-create2/utils.ts +++ b/packages/smart-contracts/scripts-create2/utils.ts @@ -57,6 +57,8 @@ export const getArtifact = (contract: string): artifacts.ContractArtifact Date: Wed, 30 Oct 2024 15:46:33 +0300 Subject: [PATCH 2/4] feat: add task to update the `SingleRequestProxyFactory` fee proxy addresses --- packages/smart-contracts/hardhat.config.ts | 12 +++ .../contract-setup/update-fee-proxies.ts | 85 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 packages/smart-contracts/scripts-create2/contract-setup/update-fee-proxies.ts diff --git a/packages/smart-contracts/hardhat.config.ts b/packages/smart-contracts/hardhat.config.ts index 6d3c6028a..c19203c78 100644 --- a/packages/smart-contracts/hardhat.config.ts +++ b/packages/smart-contracts/hardhat.config.ts @@ -22,6 +22,7 @@ import { tenderlyImportAll } from './scripts-create2/tenderly'; import { updateContractsFromList } from './scripts-create2/update-contracts-setup'; import deployStorage from './scripts/deploy-storage'; import { transferOwnership } from './scripts-create2/transfer-ownership'; +import { updateFeeProxies } from './scripts-create2/contract-setup/update-fee-proxies'; config(); @@ -403,3 +404,14 @@ subtask(DEPLOYER_KEY_GUARD, 'prevent usage of the deployer master key').setActio throw new Error('The deployer master key should not be used for this action'); } }); + +task( + 'update-fee-proxies-for-single-request-proxy-factory', + 'Update the proxy addresses in SingleRequestProxyFactory', +) + .addFlag('eoa', 'Is the update to be performed in an EOA context') + .setAction(async (args, hre) => { + const signWithEoa = args.eoa ?? false; + await hre.run(DEPLOYER_KEY_GUARD); + await updateFeeProxies(hre as HardhatRuntimeEnvironmentExtended, signWithEoa); + }); diff --git a/packages/smart-contracts/scripts-create2/contract-setup/update-fee-proxies.ts b/packages/smart-contracts/scripts-create2/contract-setup/update-fee-proxies.ts new file mode 100644 index 000000000..09319bf7b --- /dev/null +++ b/packages/smart-contracts/scripts-create2/contract-setup/update-fee-proxies.ts @@ -0,0 +1,85 @@ +import { + singleRequestProxyFactoryArtifact, + erc20FeeProxyArtifact, + ethereumFeeProxyArtifact, +} from '../../src/lib'; +import { HardhatRuntimeEnvironmentExtended } from '../types'; +import { getSignerAndGasFees } from './adminTasks'; +import { EvmChains } from '@requestnetwork/currency'; +import { executeContractMethod } from './execute-contract-method'; +import { Contract } from 'ethers'; + +/** + * Update the proxy addresses in the SingleRequestProxyFactory contract + * @param hre Hardhat runtime environment + * @param signWithEoa Are transactions to be signed by an EOA + */ +export const updateFeeProxies = async ( + hre: HardhatRuntimeEnvironmentExtended, + signWithEoa: boolean, +): Promise => { + for (const network of hre.config.xdeploy.networks) { + try { + EvmChains.assertChainSupported(network); + + const factoryAddress = singleRequestProxyFactoryArtifact.getAddress(network); + const erc20ProxyAddress = erc20FeeProxyArtifact.getAddress(network); + const ethereumProxyAddress = ethereumFeeProxyArtifact.getAddress(network); + + if (!factoryAddress || !erc20ProxyAddress || !ethereumProxyAddress) { + console.info(`Missing contract deployment on ${network}`); + continue; + } + + const { signer, txOverrides } = await getSignerAndGasFees(network, hre); + + const factory = new Contract(factoryAddress, factoryAbi, signer); + + // Check current values + const currentErc20Proxy = await factory.erc20FeeProxy(); + const currentEthereumProxy = await factory.ethereumFeeProxy(); + + // Update ERC20 proxy if needed + if (currentErc20Proxy.toLowerCase() !== erc20ProxyAddress.toLowerCase()) { + await executeContractMethod({ + network, + contract: factory, + method: 'setERC20FeeProxy', + props: [erc20ProxyAddress], + txOverrides, + signer, + signWithEoa, + }); + console.log(`Updated ERC20FeeProxy to ${erc20ProxyAddress} on ${network}`); + } else { + console.log(`ERC20FeeProxy is already set to ${erc20ProxyAddress} on ${network}`); + } + + // Update Ethereum proxy if needed + if (currentEthereumProxy.toLowerCase() !== ethereumProxyAddress.toLowerCase()) { + await executeContractMethod({ + network, + contract: factory, + method: 'setEthereumFeeProxy', + props: [ethereumProxyAddress], + txOverrides, + signer, + signWithEoa, + }); + console.log(`Updated EthereumFeeProxy to ${ethereumProxyAddress} on ${network}`); + } else { + console.log(`EthereumFeeProxy is already set to ${ethereumProxyAddress} on ${network}`); + } + } catch (err) { + console.warn(`An error occurred updating proxies on ${network}`); + console.warn(err); + } + } +}; + +const factoryAbi = [ + 'function erc20FeeProxy() view returns (address)', + 'function ethereumFeeProxy() view returns (address)', + 'function setERC20FeeProxy(address _newERC20FeeProxy)', + 'function setEthereumFeeProxy(address _newEthereumFeeProxy)', +]; From d354a0a4b5ffd1afc4814c529f1f6d7691f362f0 Mon Sep 17 00:00:00 2001 From: Aimen Sahnoun Date: Mon, 4 Nov 2024 14:29:37 +0300 Subject: [PATCH 3/4] refactor: refactor admin scripts --- packages/smart-contracts/hardhat.config.ts | 12 --- .../contract-setup/adminTasks.ts | 72 +++++++++++++++- .../setupSingleRequestProxyFactory.ts | 69 +++++++++++++++ .../scripts-create2/contract-setup/setups.ts | 5 ++ .../contract-setup/update-fee-proxies.ts | 85 ------------------- 5 files changed, 145 insertions(+), 98 deletions(-) create mode 100644 packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts delete mode 100644 packages/smart-contracts/scripts-create2/contract-setup/update-fee-proxies.ts diff --git a/packages/smart-contracts/hardhat.config.ts b/packages/smart-contracts/hardhat.config.ts index c19203c78..6d3c6028a 100644 --- a/packages/smart-contracts/hardhat.config.ts +++ b/packages/smart-contracts/hardhat.config.ts @@ -22,7 +22,6 @@ import { tenderlyImportAll } from './scripts-create2/tenderly'; import { updateContractsFromList } from './scripts-create2/update-contracts-setup'; import deployStorage from './scripts/deploy-storage'; import { transferOwnership } from './scripts-create2/transfer-ownership'; -import { updateFeeProxies } from './scripts-create2/contract-setup/update-fee-proxies'; config(); @@ -404,14 +403,3 @@ subtask(DEPLOYER_KEY_GUARD, 'prevent usage of the deployer master key').setActio throw new Error('The deployer master key should not be used for this action'); } }); - -task( - 'update-fee-proxies-for-single-request-proxy-factory', - 'Update the proxy addresses in SingleRequestProxyFactory', -) - .addFlag('eoa', 'Is the update to be performed in an EOA context') - .setAction(async (args, hre) => { - const signWithEoa = args.eoa ?? false; - await hre.run(DEPLOYER_KEY_GUARD); - await updateFeeProxies(hre as HardhatRuntimeEnvironmentExtended, signWithEoa); - }); diff --git a/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts b/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts index 16be222ba..698ddb372 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts @@ -1,7 +1,7 @@ import { chainlinkConversionPath } from '../../src/lib'; import { uniswapV2RouterAddresses } from '../../scripts/utils'; import * as artifacts from '../../src/lib'; -import { BigNumber, Overrides, Wallet, Contract } from 'ethers'; +import { BigNumber, Overrides, Wallet, Contract, ethers } from 'ethers'; import { HardhatRuntimeEnvironmentExtended } from '../types'; import { parseUnits } from 'ethers/lib/utils'; import { @@ -411,3 +411,73 @@ export const getSignerAndGasFees = async ( txOverrides, }; }; + +/** + * Updates the ERC20 fee proxy address in the SingleRequestProxyFactory contract + * @param contract SingleRequestProxyFactory contract + * @param network The network used + * @param txOverrides information related to gas fees + * @param signer Who is performing the updating + * @param signWithEoa Is the transaction to be signed by an EOA + */ +export const updateERC20FeeProxyAddress = async ( + contract: Contract, + network: CurrencyTypes.EvmChainName, + txOverrides: Overrides, + signer: Wallet, + signWithEoa: boolean, +): Promise => { + const erc20ProxyAddress = artifacts.erc20FeeProxyArtifact.getAddress(network); + const currentErc20Proxy = await contract.erc20FeeProxy(); + + if (ethers.utils.getAddress(currentErc20Proxy) !== ethers.utils.getAddress(erc20ProxyAddress)) { + await executeContractMethod({ + network, + contract, + method: 'setERC20FeeProxy', + props: [erc20ProxyAddress], + txOverrides, + signer, + signWithEoa, + }); + console.log(`Updated ERC20FeeProxy to ${erc20ProxyAddress} on ${network}`); + } else { + console.log(`ERC20FeeProxy is already set to ${erc20ProxyAddress} on ${network}`); + } +}; + +/** + * Updates the Ethereum fee proxy address in the SingleRequestProxyFactory contract + * @param contract SingleRequestProxyFactory contract + * @param network The network used + * @param txOverrides information related to gas fees + * @param signer Who is performing the updating + * @param signWithEoa Is the transaction to be signed by an EOA + */ +export const updateEthereumFeeProxyAddress = async ( + contract: Contract, + network: CurrencyTypes.EvmChainName, + txOverrides: Overrides, + signer: Wallet, + signWithEoa: boolean, +): Promise => { + const ethereumProxyAddress = artifacts.ethereumFeeProxyArtifact.getAddress(network); + const currentEthereumProxy = await contract.ethereumFeeProxy(); + + if ( + ethers.utils.getAddress(currentEthereumProxy) !== ethers.utils.getAddress(ethereumProxyAddress) + ) { + await executeContractMethod({ + network, + contract, + method: 'setEthereumFeeProxy', + props: [ethereumProxyAddress], + txOverrides, + signer, + signWithEoa, + }); + console.log(`Updated EthereumFeeProxy to ${ethereumProxyAddress} on ${network}`); + } else { + console.log(`EthereumFeeProxy is already set to ${ethereumProxyAddress} on ${network}`); + } +}; diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts new file mode 100644 index 000000000..c0d4ea260 --- /dev/null +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts @@ -0,0 +1,69 @@ +import { EvmChains } from '@requestnetwork/currency'; +import { singleRequestProxyFactoryArtifact } from '../../src/lib'; +import { HardhatRuntimeEnvironmentExtended } from '../types'; +import { + getSignerAndGasFees, + updateERC20FeeProxyAddress, + updateEthereumFeeProxyAddress, +} from './adminTasks'; + +/** + * Setup the SingleRequestProxyFactory values once deployed + * @param contractAddress address of the SingleRequestProxyFactory contract + * If not provided fallback to the latest deployment address + * @param hre Hardhat runtime environment + * @param signWithEoa Are transactions to be signed by an EOA + */ +export const setupSingleRequestProxyFactory = async ({ + contractAddress, + hre, + signWithEoa, +}: { + contractAddress?: string; + hre: HardhatRuntimeEnvironmentExtended; + signWithEoa: boolean; +}): Promise => { + await Promise.all( + hre.config.xdeploy.networks.map(async (network: string) => { + try { + EvmChains.assertChainSupported(network); + if (!contractAddress) { + contractAddress = singleRequestProxyFactoryArtifact.getAddress(network); + } + if (!contractAddress) { + console.warn(`Missing SingleRequestProxyFactory deployment on ${network}`); + return; + } + + const factory = new hre.ethers.Contract( + contractAddress, + singleRequestProxyFactoryArtifact.getContractAbi(), + ); + const { signer, txOverrides } = await getSignerAndGasFees(network, hre); + const factoryConnected = factory.connect(signer); + + await updateERC20FeeProxyAddress( + factoryConnected, + network, + txOverrides, + signer, + signWithEoa, + ); + await updateEthereumFeeProxyAddress( + factoryConnected, + network, + txOverrides, + signer, + signWithEoa, + ); + + console.log(`Setup of SingleRequestProxyFactory successful on ${network}`); + } catch (err) { + console.warn( + `An error occurred during the setup of SingleRequestProxyFactory on ${network}`, + ); + console.warn(err); + } + }), + ); +}; diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setups.ts b/packages/smart-contracts/scripts-create2/contract-setup/setups.ts index 4a8dac327..1e9e98ff0 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setups.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setups.ts @@ -5,6 +5,7 @@ import { setupERC20SwapToConversion } from './setupERC20SwapToConversion'; import { setupERC20SwapToPay } from './setupERC20SwapToPay'; import { setupChainlinkConversionPath } from './setupChainlinkConversionPath'; import { setupErc20ConversionProxy } from './setupErc20ConversionProxy'; +import { setupSingleRequestProxyFactory } from './setupSingleRequestProxyFactory'; /** * Administrate the specified contract at the specified address @@ -50,6 +51,10 @@ export const setupContract = async ({ await setupBatchConversionPayments({ contractAddress, hre, signWithEoa }); break; } + case 'SingleRequestProxyFactory': { + await setupSingleRequestProxyFactory({ contractAddress, hre, signWithEoa }); + break; + } default: { console.log(`No setup to perform for contract ${contractName}`); break; diff --git a/packages/smart-contracts/scripts-create2/contract-setup/update-fee-proxies.ts b/packages/smart-contracts/scripts-create2/contract-setup/update-fee-proxies.ts deleted file mode 100644 index 09319bf7b..000000000 --- a/packages/smart-contracts/scripts-create2/contract-setup/update-fee-proxies.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { - singleRequestProxyFactoryArtifact, - erc20FeeProxyArtifact, - ethereumFeeProxyArtifact, -} from '../../src/lib'; -import { HardhatRuntimeEnvironmentExtended } from '../types'; -import { getSignerAndGasFees } from './adminTasks'; -import { EvmChains } from '@requestnetwork/currency'; -import { executeContractMethod } from './execute-contract-method'; -import { Contract } from 'ethers'; - -/** - * Update the proxy addresses in the SingleRequestProxyFactory contract - * @param hre Hardhat runtime environment - * @param signWithEoa Are transactions to be signed by an EOA - */ -export const updateFeeProxies = async ( - hre: HardhatRuntimeEnvironmentExtended, - signWithEoa: boolean, -): Promise => { - for (const network of hre.config.xdeploy.networks) { - try { - EvmChains.assertChainSupported(network); - - const factoryAddress = singleRequestProxyFactoryArtifact.getAddress(network); - const erc20ProxyAddress = erc20FeeProxyArtifact.getAddress(network); - const ethereumProxyAddress = ethereumFeeProxyArtifact.getAddress(network); - - if (!factoryAddress || !erc20ProxyAddress || !ethereumProxyAddress) { - console.info(`Missing contract deployment on ${network}`); - continue; - } - - const { signer, txOverrides } = await getSignerAndGasFees(network, hre); - - const factory = new Contract(factoryAddress, factoryAbi, signer); - - // Check current values - const currentErc20Proxy = await factory.erc20FeeProxy(); - const currentEthereumProxy = await factory.ethereumFeeProxy(); - - // Update ERC20 proxy if needed - if (currentErc20Proxy.toLowerCase() !== erc20ProxyAddress.toLowerCase()) { - await executeContractMethod({ - network, - contract: factory, - method: 'setERC20FeeProxy', - props: [erc20ProxyAddress], - txOverrides, - signer, - signWithEoa, - }); - console.log(`Updated ERC20FeeProxy to ${erc20ProxyAddress} on ${network}`); - } else { - console.log(`ERC20FeeProxy is already set to ${erc20ProxyAddress} on ${network}`); - } - - // Update Ethereum proxy if needed - if (currentEthereumProxy.toLowerCase() !== ethereumProxyAddress.toLowerCase()) { - await executeContractMethod({ - network, - contract: factory, - method: 'setEthereumFeeProxy', - props: [ethereumProxyAddress], - txOverrides, - signer, - signWithEoa, - }); - console.log(`Updated EthereumFeeProxy to ${ethereumProxyAddress} on ${network}`); - } else { - console.log(`EthereumFeeProxy is already set to ${ethereumProxyAddress} on ${network}`); - } - } catch (err) { - console.warn(`An error occurred updating proxies on ${network}`); - console.warn(err); - } - } -}; - -const factoryAbi = [ - 'function erc20FeeProxy() view returns (address)', - 'function ethereumFeeProxy() view returns (address)', - 'function setERC20FeeProxy(address _newERC20FeeProxy)', - 'function setEthereumFeeProxy(address _newEthereumFeeProxy)', -]; From 3beb884eaa75ea1eb7f85d7c9a2805e0ec937228 Mon Sep 17 00:00:00 2001 From: Aimen Sahnoun Date: Tue, 5 Nov 2024 14:44:56 +0300 Subject: [PATCH 4/4] refactor: rename `SRPF` functions --- .../scripts-create2/contract-setup/adminTasks.ts | 4 ++-- .../contract-setup/setupSingleRequestProxyFactory.ts | 10 +++++----- .../scripts-create2/contract-setup/setups.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts b/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts index 698ddb372..12b134668 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts @@ -420,7 +420,7 @@ export const getSignerAndGasFees = async ( * @param signer Who is performing the updating * @param signWithEoa Is the transaction to be signed by an EOA */ -export const updateERC20FeeProxyAddress = async ( +export const updateSRPFERC20FeeProxyAddress = async ( contract: Contract, network: CurrencyTypes.EvmChainName, txOverrides: Overrides, @@ -454,7 +454,7 @@ export const updateERC20FeeProxyAddress = async ( * @param signer Who is performing the updating * @param signWithEoa Is the transaction to be signed by an EOA */ -export const updateEthereumFeeProxyAddress = async ( +export const updateSRPFEthereumFeeProxyAddress = async ( contract: Contract, network: CurrencyTypes.EvmChainName, txOverrides: Overrides, diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts index c0d4ea260..61f16c0d9 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts @@ -3,8 +3,8 @@ import { singleRequestProxyFactoryArtifact } from '../../src/lib'; import { HardhatRuntimeEnvironmentExtended } from '../types'; import { getSignerAndGasFees, - updateERC20FeeProxyAddress, - updateEthereumFeeProxyAddress, + updateSRPFERC20FeeProxyAddress, + updateSRPFEthereumFeeProxyAddress, } from './adminTasks'; /** @@ -14,7 +14,7 @@ import { * @param hre Hardhat runtime environment * @param signWithEoa Are transactions to be signed by an EOA */ -export const setupSingleRequestProxyFactory = async ({ +export const setupSRPF = async ({ contractAddress, hre, signWithEoa, @@ -42,14 +42,14 @@ export const setupSingleRequestProxyFactory = async ({ const { signer, txOverrides } = await getSignerAndGasFees(network, hre); const factoryConnected = factory.connect(signer); - await updateERC20FeeProxyAddress( + await updateSRPFERC20FeeProxyAddress( factoryConnected, network, txOverrides, signer, signWithEoa, ); - await updateEthereumFeeProxyAddress( + await updateSRPFEthereumFeeProxyAddress( factoryConnected, network, txOverrides, diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setups.ts b/packages/smart-contracts/scripts-create2/contract-setup/setups.ts index 1e9e98ff0..943178528 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setups.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setups.ts @@ -5,7 +5,7 @@ import { setupERC20SwapToConversion } from './setupERC20SwapToConversion'; import { setupERC20SwapToPay } from './setupERC20SwapToPay'; import { setupChainlinkConversionPath } from './setupChainlinkConversionPath'; import { setupErc20ConversionProxy } from './setupErc20ConversionProxy'; -import { setupSingleRequestProxyFactory } from './setupSingleRequestProxyFactory'; +import { setupSRPF } from './setupSingleRequestProxyFactory'; /** * Administrate the specified contract at the specified address @@ -52,7 +52,7 @@ export const setupContract = async ({ break; } case 'SingleRequestProxyFactory': { - await setupSingleRequestProxyFactory({ contractAddress, hre, signWithEoa }); + await setupSRPF({ contractAddress, hre, signWithEoa }); break; } default: {