/ integrationTest / index.js
index.js
  1  import { ethers, Contract, ContractFactory, Wallet } from "ethers";
  2  import priceOracleArtifact from "../out/PriceOracle.sol/PriceOracle.json" assert { type: 'json' };
  3  import gasBrokerArtifact from "../out/GasBroker.sol/GasBroker.json" assert { type: 'json' };
  4  import fundUSDCArtifact from "../out/FundUSDC.sol/FundUSDC.json" assert { type: 'json' };
  5  
  6  const { PROVIDER_URL, SIGNER_PRIVATE_KEY } = config;
  7  
  8  const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL);
  9  const signer = new Wallet(SIGNER_PRIVATE_KEY, provider);
 10  const customer = new Wallet("08d11cc57eca3df70d53ad570de0f2c6926c33fb93bc16fb9b9dcd25d54818bf", provider);
 11  
 12  const USDC = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
 13  
 14  async function setUp() {
 15    const chainId = (await provider.getNetwork()).chainId;
 16    // deploy contracts
 17    const priceOracleContract = await deployContract('PriceOracle', priceOracleArtifact);
 18    const priceOracleAddress = await priceOracleContract.address;
 19    const gasBrokerContract = await deployContract('GasBroker', gasGatewayArtifact, chainId, priceOracleAddress);
 20    const gasBrokerAddress = await gasBrokerContract.address;
 21  
 22    const fundUSDCcontract = await deployContract('FundUSDC', fundUSDCArtifact);
 23    const tx = await fundUSDCcontract.connect(signer).swapExactOutputSingle(100e6, 10n ** 18n, { value: 10n ** 18n });
 24    await tx.wait();
 25  
 26    console.log(`Deployer USDC ballance is ${await usdcContract.balanceOf(signer.address)}`);
 27    tx = await usdcContract.connect(signer).transfer(customer.address, 100e6);
 28    await tx.wait();
 29    console.log(`Customer USDC ballance is ${await usdcContract.balanceOf(customer.address)}`);
 30    console.log(`Customer ETH ballance is ${await provider.getBalance(customer.address)}`);
 31  
 32    //prepare signature
 33    const { r: permitR, v: permitV, s: permitS, deadline } = await getPermitSignature(gasBrokerAddress);
 34    const abiCoder = ethers.utils.defaultAbiCoder;
 35    console.log({ permitR, permitV, permitS, deadline });
 36    const permitHash = ethers.utils.keccak256(
 37      abiCoder.encode(
 38        ["uint8", "bytes32", "bytes32"],
 39        [ permitR, permitV, permitS ]
 40      )
 41    );
 42    const { r: rewardR, v: rewardV, s: rewardS } = await getRewardSignature(10e6, permitHash);
 43    console.log({ rewardR, rewardV, rewardS });
 44  
 45    const value = await gasBroker.getEthAmount(USDC, 90e6);
 46  
 47    console.log("Value to sent to customer: ", value);
 48  
 49    await gasBroker.connect(signer).swap(
 50      customer.address,
 51      USDC,
 52      100e6,
 53      deadline,
 54      10e6,
 55      permitV,
 56      permitR,
 57      permitS,
 58      rewardV,
 59      rewardR,
 60      rewardS,
 61      { value }
 62    );
 63  }
 64  
 65  async function deployContract(name, artifact, ...constructorArgs) {
 66    const { abi, bytecode } = artifact
 67    const factory = new ContractFactory(abi, bytecode, signer);
 68    const contract = await factory.deploy(...constructorArgs);
 69    await contract.deployTransaction.wait();
 70    console.log(`Contract ${name} deployed at address ${await contract.address}`);
 71    return contract;
 72  }
 73  
 74  
 75  async function getPermitSignature(gasBrokerAddress) {
 76  
 77    const chainId = (await provider.getNetwork()).chainId;
 78    // set the domain parameters
 79    const domain = {
 80      name: await usdcContract.name(),
 81      version: await usdcContract.version(),
 82      chainId: chainId,
 83      verifyingContract: USDC
 84    };
 85  
 86    console.log(domain);
 87  
 88    // set the Permit type parameters
 89    const types = {
 90      Permit: [{
 91          name: "owner",
 92          type: "address"
 93        },
 94        {
 95          name: "spender",
 96          type: "address"
 97        },
 98        {
 99          name: "value",
100          type: "uint256"
101        },
102        {
103          name: "nonce",
104          type: "uint256"
105        },
106        {
107          name: "deadline",
108          type: "uint256"
109        },
110      ],
111    };
112    const deadline = (await provider.getBlock("latest")).timestamp + 3600000;
113    const values = {
114      owner: customer.address,
115      spender: gasBrokerAddress,
116      value: 100e6,
117      nonce: await usdcContract.nonces(customer.address),
118      deadline
119    };
120    console.log("Values: ", values);
121    const signature = await customer._signTypedData(domain, types, values);
122  
123    const { v, r, s } = ethers.utils.splitSignature(signature);
124    console.log({ v, r, s});
125  
126    const nonce = await usdcContract.nonces(customer.address);
127    console.log({ nonce });
128  
129    return { r, v, s, deadline};
130  }
131  
132  
133  async function getRewardSignature(value, permitHash) {
134  
135    const chainId = (await provider.getNetwork()).chainId;
136    // set the domain parameters
137    const domain = {
138      name: await gasBrokerContract.name(),
139      version: await gasBrokerContract.version(),
140      chainId: chainId,
141      verifyingContract: gasBrokerAddress
142    };
143  
144    console.log(domain);
145  
146    // set the Permit type parameters
147    const types = {
148      Reward: [{
149          name: "value",
150          type: "uint256"
151        },
152        {
153          name: "permitHash",
154          type: "bytes32"
155        }
156      ],
157    };
158    const deadline = (await provider.getBlock("latest")).timestamp + 3600000;
159    const values = {
160      value,
161      permitHash
162    };
163    console.log("Values: ", values);
164    const signature = await customer._signTypedData(domain, types, values);
165  
166    const { v, r, s } = ethers.utils.splitSignature(signature);
167  
168    return { r, v, s };
169  }
170  
171