From 1da76ab294e764e6313dffce21001eccedb17c2c Mon Sep 17 00:00:00 2001 From: test Date: Sun, 14 Jan 2024 15:07:41 +0800 Subject: [PATCH] Refactor scripts and adjust README --- contracts/README.md | 61 +++++++++++++++++++++++++++++++- contracts/package.json | 3 +- contracts/scripts/sendPayment.ts | 13 +++---- contracts/test/utils.ts | 22 +++++++----- 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/contracts/README.md b/contracts/README.md index d852b80..17f88d5 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -1 +1,60 @@ -# GHOPAY +# GHOPAY - Smart Contracts +This directory contains the smart contracts related tests, utilities and deployment addresses for the Payment Settlement. + +## How does it work ? +The smart contracts themselves have essentially three tasks: +1. Verify the user signature that was passed in by the Gelato relay in terms of amount and receiver +2. Use user signature to pull in GHO +3. Swap a fraction of the GHO for gas fee token (usually eth / native token) expected by relay +4. Pay the relay +5. Transfer remaining Gho to the receiver + + +## Installation +`yarn install` + +## Run tests +`yarn test` + + +## Sepolia Deployment + +### Warning: +Note that on Sepolia we have deployed the [PaymentSettlementTestHarness](contracts/contracts/test/PaymentSettlementTestHarness.sol) contract which extends the [PaymentSettlement](contracts/contracts/PaymentSettlement.sol) with some unsafe methods added for testing purposes. +One should NEVER deploy this version of the contract on a network were it will handle actual value. + + +### Run Deploy: +Delete deployment outputs of previous deployment if you want to redeploy: +`rm -rf deployments/sepolia` + +Deploy on actual sepolia: +`deploy:sepolia --network sepolia` + +Test deploy on local fork: +`deploy:sepolia --network localhost` + +## Send Payment (on Sepolia) + +You can use the [payment script](contracts/scripts/sendPayment.ts) to send a GHO payment gaslessly via the Gelato relay. +For this you will have to: +1. Adjust the `receiver` and `amount` variables in the script to your liking +2. Make sure you have set the `SEPOLIA_PRIVATE_KEY` environment variable to the private key of an account with sufficient GHO tokens on sepolia +3. Run `yarn send-payment:sepolia` to make the payment +4. Wait for the script to finish. In the success case the last emitted logs should llook something like this: +``` +Task Status { + chainId: 11155111, + taskId: '0xaa31e9ec7dc88958e8d263b59575b2c22452985815552c4e189baa11e7141104', + taskState: 'ExecSuccess', + creationDate: '2024-01-14T06:51:54.367Z', + transactionHash: '0xa38b90e8af1f66425961e3e09deca5bc184b94cf10be95535893338ce7dcf1c9', + executionDate: '2024-01-14T06:52:01.839Z', + blockNumber: 5083156, + gasUsed: '295101', + effectiveGasPrice: '153284042' +} +``` + + + diff --git a/contracts/package.json b/contracts/package.json index c41bbf3..3f8be56 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -8,7 +8,8 @@ "compile": "hardhat compile", "test": "hardhat test", "deploy:sepolia": "DEPLOY='v0.0.1.sepolia' hardhat deploy", - "verify:sepolia": "yarn hardhat etherscan-verify --network sepolia --api-url https://api-sepolia.etherscan.io/ --api-key $SEPOLIA_ETHERSCAN_API_KEY" + "verify:sepolia": "yarn hardhat etherscan-verify --network sepolia --api-url https://api-sepolia.etherscan.io/ --api-key $SEPOLIA_ETHERSCAN_API_KEY", + "send-payment:sepolia": "yarn hardhat run --network sepolia scripts/sendPayment.ts" }, "devDependencies": { "@gelatonetwork/relay-sdk": "^5.5.0", diff --git a/contracts/scripts/sendPayment.ts b/contracts/scripts/sendPayment.ts index 0b19806..4d9d9f5 100644 --- a/contracts/scripts/sendPayment.ts +++ b/contracts/scripts/sendPayment.ts @@ -8,7 +8,7 @@ import { import { ghoAddress, - wethAddress, + ethAddress, } from "../constants/addresses"; async function createTask( @@ -65,13 +65,13 @@ async function main() { }; console.log("chainId:", chainId); - let amount = ethers.utils.parseEther("0.01"); - let receiver = "0xef35B896e1c6c816177277924d04Ead587Bbc495"; + let amount = ethers.utils.parseEther("100"); + let receiver = "0x3C1a2E9CA00AF23Cd95000160f873f77F65a0041"; const gho = IERC20Complete__factory.connect(ghoAddress, deployerSigner); const relativeDeadline = 60 * 60; const deadline = Math.floor(new Date().getTime() / 1000) + relativeDeadline; const fee = ethers.utils.parseEther("0.000000000001"); - const feeToken = wethAddress; + const feeToken = ethAddress; let verifyCalldata = await generateVerificationCallData( gho, amount, @@ -87,13 +87,14 @@ async function main() { ghoAddress, amount, receiver, - paymentSettlement + paymentSettlement, + false ); const task = await createTask( payCalldata, paymentSettlement.address, chainId, - ghoAddress + feeToken ); await awaitTask(task); } diff --git a/contracts/test/utils.ts b/contracts/test/utils.ts index 3ed3d04..d3cebcf 100644 --- a/contracts/test/utils.ts +++ b/contracts/test/utils.ts @@ -215,16 +215,20 @@ export async function generatePayCallData( tokenAddress: string, amount: BigNumberish, receiver: string, - paymentSettlement: PaymentSettlement + paymentSettlement: PaymentSettlement, + verifyCalldata: boolean = true ) { - const result = await paymentSettlement.signer.provider?.call({ - to: paymentSettlement.address, - data: verifyCallData, - }); - const expectedResult = - "0x0000000000000000000000000000000000000000000000000000000000000001"; - if (result !== expectedResult) { - throw new Error("verifyData failed"); + + if(verifyCalldata) { + const result = await paymentSettlement.signer.provider?.call({ + to: paymentSettlement.address, + data: verifyCallData, + }); + const expectedResult = + "0x0000000000000000000000000000000000000000000000000000000000000001"; + if (result !== expectedResult) { + throw new Error("verifyData failed"); + } } const [paymentData, paySignature] = paymentSettlement.interface.decodeFunctionData(