Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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 updateSRPFERC20FeeProxyAddress = async (
contract: Contract,
network: CurrencyTypes.EvmChainName,
txOverrides: Overrides,
signer: Wallet,
signWithEoa: boolean,
): Promise<void> => {
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 updateSRPFEthereumFeeProxyAddress = async (
contract: Contract,
network: CurrencyTypes.EvmChainName,
txOverrides: Overrides,
signer: Wallet,
signWithEoa: boolean,
): Promise<void> => {
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}`);
}
};
Comment on lines +423 to +483
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider refactoring to reduce code duplication between proxy update functions.

The two functions share almost identical structure and differ only in method names and variable names. Consider refactoring into a single function with a type parameter:

-export const updateSRPFERC20FeeProxyAddress = async (
-  contract: Contract,
-  network: CurrencyTypes.EvmChainName,
-  txOverrides: Overrides,
-  signer: Wallet,
-  signWithEoa: boolean,
-): Promise<void> => {
-  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}`);
-  }
-};
-
-export const updateSRPFEthereumFeeProxyAddress = async (
-  contract: Contract,
-  network: CurrencyTypes.EvmChainName,
-  txOverrides: Overrides,
-  signer: Wallet,
-  signWithEoa: boolean,
-): Promise<void> => {
-  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}`);
-  }
-};
+type ProxyType = 'ERC20' | 'Ethereum';
+
+const updateSRPFFeeProxyAddress = async (
+  proxyType: ProxyType,
+  contract: Contract,
+  network: CurrencyTypes.EvmChainName,
+  txOverrides: Overrides,
+  signer: Wallet,
+  signWithEoa: boolean,
+): Promise<void> => {
+  const config = {
+    ERC20: {
+      getAddress: () => artifacts.erc20FeeProxyArtifact.getAddress(network),
+      getCurrentProxy: () => contract.erc20FeeProxy(),
+      setMethod: 'setERC20FeeProxy',
+    },
+    Ethereum: {
+      getAddress: () => artifacts.ethereumFeeProxyArtifact.getAddress(network),
+      getCurrentProxy: () => contract.ethereumFeeProxy(),
+      setMethod: 'setEthereumFeeProxy',
+    },
+  }[proxyType];
+
+  const proxyAddress = config.getAddress();
+  const currentProxy = await config.getCurrentProxy();
+
+  if (ethers.utils.getAddress(currentProxy) !== ethers.utils.getAddress(proxyAddress)) {
+    await executeContractMethod({
+      network,
+      contract,
+      method: config.setMethod,
+      props: [proxyAddress],
+      txOverrides,
+      signer,
+      signWithEoa,
+    });
+    console.log(`Updated ${proxyType}FeeProxy to ${proxyAddress} on ${network}`);
+  } else {
+    console.log(`${proxyType}FeeProxy is already set to ${proxyAddress} on ${network}`);
+  }
+};
+
+export const updateSRPFERC20FeeProxyAddress = (
+  contract: Contract,
+  network: CurrencyTypes.EvmChainName,
+  txOverrides: Overrides,
+  signer: Wallet,
+  signWithEoa: boolean,
+): Promise<void> =>
+  updateSRPFFeeProxyAddress('ERC20', contract, network, txOverrides, signer, signWithEoa);
+
+export const updateSRPFEthereumFeeProxyAddress = (
+  contract: Contract,
+  network: CurrencyTypes.EvmChainName,
+  txOverrides: Overrides,
+  signer: Wallet,
+  signWithEoa: boolean,
+): Promise<void> =>
+  updateSRPFFeeProxyAddress('Ethereum', contract, network, txOverrides, signer, signWithEoa);

This refactoring:

  1. Reduces code duplication
  2. Makes it easier to maintain and update both proxy types
  3. Keeps the same public API
  4. Improves type safety with the ProxyType type
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const updateSRPFERC20FeeProxyAddress = async (
contract: Contract,
network: CurrencyTypes.EvmChainName,
txOverrides: Overrides,
signer: Wallet,
signWithEoa: boolean,
): Promise<void> => {
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 updateSRPFEthereumFeeProxyAddress = async (
contract: Contract,
network: CurrencyTypes.EvmChainName,
txOverrides: Overrides,
signer: Wallet,
signWithEoa: boolean,
): Promise<void> => {
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}`);
}
};
type ProxyType = 'ERC20' | 'Ethereum';
const updateSRPFFeeProxyAddress = async (
proxyType: ProxyType,
contract: Contract,
network: CurrencyTypes.EvmChainName,
txOverrides: Overrides,
signer: Wallet,
signWithEoa: boolean,
): Promise<void> => {
const config = {
ERC20: {
getAddress: () => artifacts.erc20FeeProxyArtifact.getAddress(network),
getCurrentProxy: () => contract.erc20FeeProxy(),
setMethod: 'setERC20FeeProxy',
},
Ethereum: {
getAddress: () => artifacts.ethereumFeeProxyArtifact.getAddress(network),
getCurrentProxy: () => contract.ethereumFeeProxy(),
setMethod: 'setEthereumFeeProxy',
},
}[proxyType];
const proxyAddress = config.getAddress();
const currentProxy = await config.getCurrentProxy();
if (ethers.utils.getAddress(currentProxy) !== ethers.utils.getAddress(proxyAddress)) {
await executeContractMethod({
network,
contract,
method: config.setMethod,
props: [proxyAddress],
txOverrides,
signer,
signWithEoa,
});
console.log(`Updated ${proxyType}FeeProxy to ${proxyAddress} on ${network}`);
} else {
console.log(`${proxyType}FeeProxy is already set to ${proxyAddress} on ${network}`);
}
};
export const updateSRPFERC20FeeProxyAddress = (
contract: Contract,
network: CurrencyTypes.EvmChainName,
txOverrides: Overrides,
signer: Wallet,
signWithEoa: boolean,
): Promise<void> =>
updateSRPFFeeProxyAddress('ERC20', contract, network, txOverrides, signer, signWithEoa);
export const updateSRPFEthereumFeeProxyAddress = (
contract: Contract,
network: CurrencyTypes.EvmChainName,
txOverrides: Overrides,
signer: Wallet,
signWithEoa: boolean,
): Promise<void> =>
updateSRPFFeeProxyAddress('Ethereum', contract, network, txOverrides, signer, signWithEoa);

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { EvmChains } from '@requestnetwork/currency';
import { singleRequestProxyFactoryArtifact } from '../../src/lib';
import { HardhatRuntimeEnvironmentExtended } from '../types';
import {
getSignerAndGasFees,
updateSRPFERC20FeeProxyAddress,
updateSRPFEthereumFeeProxyAddress,
} 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 setupSRPF = async ({
contractAddress,
hre,
signWithEoa,
}: {
contractAddress?: string;
hre: HardhatRuntimeEnvironmentExtended;
signWithEoa: boolean;
}): Promise<void> => {
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 updateSRPFERC20FeeProxyAddress(
factoryConnected,
network,
txOverrides,
signer,
signWithEoa,
);
await updateSRPFEthereumFeeProxyAddress(
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);
}
}),
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { setupERC20SwapToConversion } from './setupERC20SwapToConversion';
import { setupERC20SwapToPay } from './setupERC20SwapToPay';
import { setupChainlinkConversionPath } from './setupChainlinkConversionPath';
import { setupErc20ConversionProxy } from './setupErc20ConversionProxy';
import { setupSRPF } from './setupSingleRequestProxyFactory';

/**
* Administrate the specified contract at the specified address
Expand Down Expand Up @@ -50,6 +51,10 @@ export const setupContract = async ({
await setupBatchConversionPayments({ contractAddress, hre, signWithEoa });
break;
}
case 'SingleRequestProxyFactory': {
await setupSRPF({ contractAddress, hre, signWithEoa });
break;
}
default: {
console.log(`No setup to perform for contract ${contractName}`);
break;
Expand Down
2 changes: 2 additions & 0 deletions packages/smart-contracts/scripts-create2/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export const getArtifact = (contract: string): artifacts.ContractArtifact<Contra
return artifacts.batchConversionPaymentsArtifact;
case 'ERC20TransferableReceivable':
return artifacts.erc20TransferableReceivableArtifact;
case 'SingleRequestProxyFactory':
return artifacts.singleRequestProxyFactoryArtifact;
default:
throw new Error('Contract unknown');
}
Expand Down