diff --git a/packages/smart-contracts/README.md b/packages/smart-contracts/README.md index 0f7ad08fd..39cfb75e8 100644 --- a/packages/smart-contracts/README.md +++ b/packages/smart-contracts/README.md @@ -67,7 +67,7 @@ The package stores the following smart contracts: - `RequestOpenHashSubmitter` entry point to add hashes in `RequestHashStorage`. It gives the rules to get the right to submit hashes and collect the fees. This contract must be whitelisted in `RequestHashStorage`. The only condition for adding hash is to pay the fees. - `StorageFeeCollector` parent contract (not deployed) of `RequestOpenHashSubmitter`, computes the fees and send them to the burner. -**Smart contracts for advanced-logic package** +**Smart contracts for payments (advanced-logic package)** - `TestERC20` minimal erc20 token used for tests. - `ERC20Proxy` used to pay requests with an ERC20 proxy contract payment network diff --git a/packages/smart-contracts/scripts-create2/compute-one-address.ts b/packages/smart-contracts/scripts-create2/compute-one-address.ts index f3bff6789..4d30a4afb 100644 --- a/packages/smart-contracts/scripts-create2/compute-one-address.ts +++ b/packages/smart-contracts/scripts-create2/compute-one-address.ts @@ -40,6 +40,10 @@ export async function computeCreate2DeploymentAddress( ); return computedAddress; } catch (e) { + console.warn('Error while computing the deployment address', { + 'deploymentParams.contract': deploymentParams.contract, + WEB3_PROVIDER_URL: process.env.WEB3_PROVIDER_URL, + }); throw new Error(e.toString()); } } diff --git a/packages/smart-contracts/scripts-create2/deploy.ts b/packages/smart-contracts/scripts-create2/deploy.ts index 4eee974b5..4270763d4 100644 --- a/packages/smart-contracts/scripts-create2/deploy.ts +++ b/packages/smart-contracts/scripts-create2/deploy.ts @@ -15,11 +15,12 @@ import { setupContract } from './contract-setup/setups'; export const deployOneWithCreate2 = async ( deploymentParams: IDeploymentParams, hre: HardhatRuntimeEnvironmentExtended, -): Promise => { +): Promise<{ deployed: 'success' | 'yes' | 'no'; address: string }> => { if (!hre.config.xdeploy.networks || hre.config.xdeploy.networks.length === 0) { throw new Error('Invalid networks'); } // Deploy the contract on several network through xdeployer + let deployed: 'success' | 'yes' | 'no' = 'no'; const deploymentResult = await xdeploy(deploymentParams, hre); hre.config.xdeploy.networks.forEach((network, i) => { if (deploymentResult[i].deployed) { @@ -27,11 +28,13 @@ export const deployOneWithCreate2 = async ( console.log(` On network: ${network}`); console.log(` At address: ${deploymentResult[i].address}`); console.log(` At block: ${deploymentResult[i].receipt.blockNumber}`); + deployed = 'success'; } else { if (isContractDeployed(deploymentParams.contract, network, deploymentResult[i].address)) { console.log(`${deploymentParams.contract} already deployed:`); console.log(` On network: ${network}`); console.log(` At address: ${deploymentResult[i].address}`); + deployed = 'yes'; } else { console.log(`${deploymentParams.contract} has not been deployed:`); console.log(` On network: ${network}`); @@ -42,7 +45,7 @@ export const deployOneWithCreate2 = async ( } } }); - return deploymentResult[0].address; + return { deployed, address: deploymentResult[0].address }; }; /** @@ -53,11 +56,15 @@ export const deployOneWithCreate2 = async ( export const deployWithCreate2FromList = async ( hre: HardhatRuntimeEnvironmentExtended, ): Promise => { + const network = hre.config.xdeploy.networks[0]; + EvmChains.assertChainSupported(network); for (const contract of create2ContractDeploymentList) { - const network = hre.config.xdeploy.networks[0]; - EvmChains.assertChainSupported(network); const constructorArgs = getConstructorArgs(contract, network); - const address = await deployOneWithCreate2({ contract, constructorArgs }, hre); + const { deployed, address } = await deployOneWithCreate2({ contract, constructorArgs }, hre); + if (deployed === 'no') { + console.warn('Skipping contract setup'); + continue; + } await setupContract({ contractAddress: address, contractName: contract, diff --git a/packages/smart-contracts/scripts-create2/verify.ts b/packages/smart-contracts/scripts-create2/verify.ts index f04520210..4228250a2 100644 --- a/packages/smart-contracts/scripts-create2/verify.ts +++ b/packages/smart-contracts/scripts-create2/verify.ts @@ -34,6 +34,9 @@ export async function VerifyCreate2FromList(hre: HardhatRuntimeEnvironmentExtend }; let address: string; + const network = hre.config.xdeploy.networks[0]; + EvmChains.assertChainSupported(network); + console.debug(`Verifying ${create2ContractDeploymentList.length} contracts on ${network}`); for (const contract of create2ContractDeploymentList) { try { await delay(); @@ -53,11 +56,11 @@ export async function VerifyCreate2FromList(hre: HardhatRuntimeEnvironmentExtend case 'SingleRequestProxyFactory': case 'ERC20RecurringPaymentProxy': case 'ERC20CommerceEscrowWrapper': { - const network = hre.config.xdeploy.networks[0]; - EvmChains.assertChainSupported(network); const constructorArgs = getConstructorArgs(contract, network); address = await computeCreate2DeploymentAddress({ contract, constructorArgs }, hre); + console.debug(`Verifying ${contract} at ${address} on ${network}`); await verifyOne(address, { contract, constructorArgs }, hre); + console.debug(`Verified ${contract} on ${network}`); break; } // Other cases to add when necessary diff --git a/packages/smart-contracts/scripts-create2/xdeployer.ts b/packages/smart-contracts/scripts-create2/xdeployer.ts index be8c9a195..f45ec7fc0 100644 --- a/packages/smart-contracts/scripts-create2/xdeployer.ts +++ b/packages/smart-contracts/scripts-create2/xdeployer.ts @@ -16,6 +16,9 @@ export const xdeploy = async ( hre: HardhatRuntimeEnvironmentExtended, ): Promise> => { const { contract, constructorArgs } = deploymentParams; + if (!hre.config.xdeploy.signer) { + throw new Error('Xdeployer signer (process.env.ADMIN_PRIVATE_KEY) missing'); + } console.log( `Deployment of ${contract} through xdeployer starting now, with ${ new hre.ethers.Wallet(hre.config.xdeploy.signer).address @@ -73,6 +76,7 @@ export const xdeploy = async ( 'Contract address could not be computed, check your contract name and arguments', ); } + console.log(`... at ${computedContractAddress}`); let receipt = undefined; let deployed = false; @@ -99,7 +103,11 @@ export const xdeploy = async ( receipt = createReceipt; deployed = true; } catch (err) { - error = err; + if (err?.message?.match(/insufficient funds for intrinsic transaction cost/)) { + error = 'Insufficient funds'; + } else { + error = err; + } } result.push({ network, diff --git a/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/0.2.0.json b/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/0.2.0.json new file mode 100644 index 000000000..97ec78d7a --- /dev/null +++ b/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/0.2.0.json @@ -0,0 +1,766 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_paymentErc20Proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_paymentNativeProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_paymentErc20ConversionProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_paymentNativeConversionFeeProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_chainlinkConversionPath", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "NativeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestAmount", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "paymentReference", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxToSpend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxRateTimespan", + "type": "uint256" + } + ], + "internalType": "struct BatchNoConversionPayments.RequestDetail[]", + "name": "requestDetails", + "type": "tuple[]" + }, + { + "internalType": "address[][]", + "name": "pathsToUSD", + "type": "address[][]" + }, + { + "internalType": "address", + "name": "feeAddress", + "type": "address" + } + ], + "name": "batchERC20Payments", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "batchFee", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "batchFeeAmountUSDLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestAmount", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "paymentReference", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxToSpend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxRateTimespan", + "type": "uint256" + } + ], + "internalType": "struct BatchNoConversionPayments.RequestDetail[]", + "name": "requestDetails", + "type": "tuple[]" + }, + { + "internalType": "address[][]", + "name": "pathsToUSD", + "type": "address[][]" + }, + { + "internalType": "address", + "name": "feeAddress", + "type": "address" + } + ], + "name": "batchMultiERC20ConversionPayments", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestAmount", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "paymentReference", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxToSpend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxRateTimespan", + "type": "uint256" + } + ], + "internalType": "struct BatchNoConversionPayments.RequestDetail[]", + "name": "requestDetails", + "type": "tuple[]" + }, + { + "internalType": "address[][]", + "name": "pathsToUSD", + "type": "address[][]" + }, + { + "internalType": "address", + "name": "feeAddress", + "type": "address" + } + ], + "name": "batchMultiERC20Payments", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestAmount", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "paymentReference", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxToSpend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxRateTimespan", + "type": "uint256" + } + ], + "internalType": "struct BatchNoConversionPayments.RequestDetail[]", + "name": "requestDetails", + "type": "tuple[]" + }, + { + "internalType": "bool", + "name": "skipFeeUSDLimit", + "type": "bool" + }, + { + "internalType": "address payable", + "name": "feeAddress", + "type": "address" + } + ], + "name": "batchNativeConversionPayments", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestAmount", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "paymentReference", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxToSpend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxRateTimespan", + "type": "uint256" + } + ], + "internalType": "struct BatchNoConversionPayments.RequestDetail[]", + "name": "requestDetails", + "type": "tuple[]" + }, + { + "internalType": "bool", + "name": "skipFeeUSDLimit", + "type": "bool" + }, + { + "internalType": "address payable", + "name": "feeAddress", + "type": "address" + } + ], + "name": "batchNativePayments", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "paymentNetworkId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestAmount", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "paymentReference", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxToSpend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxRateTimespan", + "type": "uint256" + } + ], + "internalType": "struct BatchNoConversionPayments.RequestDetail[]", + "name": "requestDetails", + "type": "tuple[]" + } + ], + "internalType": "struct BatchConversionPayments.MetaDetail[]", + "name": "metaDetails", + "type": "tuple[]" + }, + { + "internalType": "address[][]", + "name": "pathsToUSD", + "type": "address[][]" + }, + { + "internalType": "address", + "name": "feeAddress", + "type": "address" + } + ], + "name": "batchPayments", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkConversionPath", + "outputs": [ + { + "internalType": "contract ChainlinkConversionPath", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "pathsNativeToUSD", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paymentErc20ConversionProxy", + "outputs": [ + { + "internalType": "contract IERC20ConversionProxy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paymentErc20Proxy", + "outputs": [ + { + "internalType": "contract IERC20FeeProxy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paymentNativeConversionProxy", + "outputs": [ + { + "internalType": "contract IEthConversionProxy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paymentNativeProxy", + "outputs": [ + { + "internalType": "contract IEthereumFeeProxy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "erc20TokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "recipientAddress", + "type": "address" + } + ], + "name": "rescueERC20Funds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_batchFee", + "type": "uint16" + } + ], + "name": "setBatchFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_batchFeeAmountUSDLimit", + "type": "uint64" + } + ], + "name": "setBatchFeeAmountUSDLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_chainlinkConversionPath", + "type": "address" + } + ], + "name": "setChainlinkConversionPath", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_NativeAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_USDAddress", + "type": "address" + } + ], + "name": "setNativeAndUSDAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_paymentErc20ConversionProxy", + "type": "address" + } + ], + "name": "setPaymentErc20ConversionProxy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_paymentErc20Proxy", + "type": "address" + } + ], + "name": "setPaymentErc20Proxy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_paymentNativeConversionProxy", + "type": "address" + } + ], + "name": "setPaymentNativeConversionProxy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_paymentNativeProxy", + "type": "address" + } + ], + "name": "setPaymentNativeProxy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] +} diff --git a/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/index.ts b/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/index.ts index 98ebd5b6a..ebed5edf5 100644 --- a/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/index.ts @@ -1,6 +1,7 @@ import { ContractArtifact } from '../../ContractArtifact'; import { abi as ABI_0_1_0 } from './0.1.0.json'; +import { abi as ABI_0_2_0 } from './0.2.0.json'; // @ts-ignore Cannot find module import type { BatchConversionPayments } from '../../../types'; @@ -97,6 +98,15 @@ export const batchConversionPaymentsArtifact = new ContractArtifact