mirror of
				https://github.com/Instadapp/Gelato-automations.git
				synced 2024-07-29 22:28:07 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			249 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			249 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // running `npx hardhat test` automatically makes use of hardhat-waffle plugin
 | |
| // => only dependency we need is "chai"
 | |
| const { expect } = require("chai");
 | |
| const hre = require("hardhat");
 | |
| const { ethers } = hre;
 | |
| const GelatoCoreLib = require("@gelatonetwork/core");
 | |
| //const { sleep } = GelatoCoreLib;
 | |
| 
 | |
| // Constants
 | |
| const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
 | |
| 
 | |
| // Contracts
 | |
| const InstaIndex = require("../../pre-compiles/InstaIndex.json");
 | |
| const InstaList = require("../../pre-compiles/InstaList.json");
 | |
| const InstaConnectors = require("../../pre-compiles/InstaConnectors.json");
 | |
| const InstaAccount = require("../../pre-compiles/InstaAccount.json");
 | |
| const ConnectAuth = require("../../pre-compiles/ConnectAuth.json");
 | |
| const ConnectBasic = require("../../pre-compiles/ConnectBasic.json");
 | |
| const ProviderModuleDsa_ABI = require("../../pre-compiles/ProviderModuleDsa_ABI.json");
 | |
| 
 | |
| describe("DSA setup with Gelato Tests", function () {
 | |
|   this.timeout(50000);
 | |
|   if (hre.network.name !== "hardhat") {
 | |
|     console.error("Test Suite is meant to be run on hardhat only");
 | |
|     process.exit(1);
 | |
|   }
 | |
| 
 | |
|   // Wallet to use for local testing
 | |
|   let userWallet;
 | |
|   let userAddress;
 | |
|   let dsaAddress;
 | |
| 
 | |
|   // Deployed instances
 | |
|   let instaIndex;
 | |
|   let instaList;
 | |
|   let instaConnectors;
 | |
|   let instaAccount;
 | |
|   let gelatoCore;
 | |
|   let providerModuleDSA;
 | |
| 
 | |
|   // Contracts to deploy and use for local testing
 | |
|   let dsa;
 | |
| 
 | |
|   // Other variables
 | |
|   let dsaVersion;
 | |
|   let dsaID;
 | |
| 
 | |
|   before(async function () {
 | |
|     // Get Test Wallet for local testnet
 | |
|     [userWallet] = await ethers.getSigners();
 | |
|     userAddress = await userWallet.getAddress();
 | |
| 
 | |
|     // ===== DSA LOCAL SETUP ==================
 | |
|     instaIndex = await ethers.getContractAt(
 | |
|       InstaIndex.abi,
 | |
|       hre.network.config.InstaIndex
 | |
|     );
 | |
|     instaList = await ethers.getContractAt(
 | |
|       InstaList.abi,
 | |
|       hre.network.config.InstaList
 | |
|     );
 | |
|     instaConnectors = await ethers.getContractAt(
 | |
|       InstaConnectors.abi,
 | |
|       hre.network.config.InstaConnectors
 | |
|     );
 | |
|     instaAccount = await ethers.getContractAt(
 | |
|       InstaAccount.abi,
 | |
|       hre.network.config.InstaAccount
 | |
|     );
 | |
| 
 | |
|     dsaVersion = await instaAccount.version();
 | |
|     dsaID = await instaList.accounts();
 | |
| 
 | |
|     // Deploy DSA and get and verify ID of newly deployed DSA
 | |
|     await expect(instaIndex.build(userAddress, 1, userAddress)).to.emit(
 | |
|       instaIndex,
 | |
|       "LogAccountCreated"
 | |
|     );
 | |
|     await expect(await instaList.accounts()).to.be.equal(dsaID.add(1));
 | |
|     dsaID = dsaID.add(1);
 | |
| 
 | |
|     // Instantiate the DSA
 | |
|     dsaAddress = await instaList.accountAddr(dsaID);
 | |
|     dsa = await ethers.getContractAt(InstaAccount.abi, dsaAddress);
 | |
| 
 | |
|     // ===== GELATO LOCAL SETUP ==================
 | |
|     gelatoCore = await ethers.getContractAt(
 | |
|       GelatoCoreLib.GelatoCore.abi,
 | |
|       hre.network.config.GelatoCore
 | |
|     );
 | |
|     providerModuleDSA = await ethers.getContractAt(
 | |
|       ProviderModuleDsa_ABI,
 | |
|       hre.network.config.ProviderModuleDsa
 | |
|     );
 | |
|   });
 | |
| 
 | |
|   it("#1: Forks InstaDapp Mainnet config", async function () {
 | |
|     expect(await instaIndex.list()).to.be.equal(instaList.address);
 | |
|     expect(dsaVersion).to.be.equal(1);
 | |
|     expect(await instaIndex.connectors(dsaVersion)).to.be.equal(
 | |
|       instaConnectors.address
 | |
|     );
 | |
|     expect(await instaConnectors.connectors(hre.network.config.ConnectAuth)).to
 | |
|       .be.true;
 | |
|     expect(await instaConnectors.connectors(hre.network.config.ConnectBasic)).to
 | |
|       .be.true;
 | |
|     expect(await instaConnectors.connectors(hre.network.config.ConnectMaker)).to
 | |
|       .be.true;
 | |
|     expect(await instaConnectors.connectors(hre.network.config.ConnectCompound))
 | |
|       .to.be.true;
 | |
|   });
 | |
| 
 | |
|   it("#2: Deploys a DSA with user as authority", async function () {
 | |
|     expect(await dsa.isAuth(userAddress)).to.be.true;
 | |
|   });
 | |
| 
 | |
|   it("#3: Let's User deposit and withdraw funds from DSA", async function () {
 | |
|     // Send withdraw TX via DSA.cast delegatecall
 | |
|     const gasLimit = ethers.BigNumber.from(1000000);
 | |
|     const gasPrice = ethers.utils.parseUnits("20", "gwei");
 | |
|     const gasCostMax = gasLimit.mul(gasPrice);
 | |
| 
 | |
|     // Deposit funds into DSA
 | |
|     const initialWalletBalance = await userWallet.getBalance();
 | |
|     expect(await ethers.provider.getBalance(dsaAddress)).to.be.equal(0);
 | |
|     await userWallet.sendTransaction({
 | |
|       to: dsaAddress,
 | |
|       value: ethers.utils.parseEther("1"),
 | |
|       gasLimit,
 | |
|       gasPrice,
 | |
|     });
 | |
|     expect(await userWallet.getBalance()).to.be.lt(
 | |
|       initialWalletBalance.sub(ethers.utils.parseEther("1"))
 | |
|     );
 | |
|     expect(await ethers.provider.getBalance(dsaAddress)).to.be.equal(
 | |
|       ethers.utils.parseEther("1")
 | |
|     );
 | |
| 
 | |
|     // Encode Payloads for ConnectBasic.withdraw
 | |
|     const withdrawData = await hre.run("abi-encode-withselector", {
 | |
|       abi: ConnectBasic.abi,
 | |
|       functionname: "withdraw",
 | |
|       inputs: [ETH, ethers.utils.parseEther("1"), userAddress, 0, 0],
 | |
|     });
 | |
| 
 | |
|     await expect(
 | |
|       dsa.cast([hre.network.config.ConnectBasic], [withdrawData], userAddress, {
 | |
|         gasLimit,
 | |
|         gasPrice,
 | |
|       })
 | |
|     )
 | |
|       .to.emit(dsa, "LogCast")
 | |
|       .withArgs(userAddress, userAddress, 0);
 | |
| 
 | |
|     expect(await ethers.provider.getBalance(dsaAddress)).to.be.equal(0);
 | |
|     expect(await userWallet.getBalance()).to.be.gte(
 | |
|       initialWalletBalance.sub(gasCostMax.mul(2))
 | |
|     );
 | |
|   });
 | |
| 
 | |
|   it("#4: Enables GelatoCore as a User of the DSA", async function () {
 | |
|     expect(await dsa.isAuth(gelatoCore.address)).to.be.false;
 | |
| 
 | |
|     // Encode Payloads for ConnectAuth.addModule
 | |
|     const addAuthData = await hre.run("abi-encode-withselector", {
 | |
|       abi: ConnectAuth.abi,
 | |
|       functionname: "add",
 | |
|       inputs: [gelatoCore.address],
 | |
|     });
 | |
| 
 | |
|     await expect(
 | |
|       dsa.cast([hre.network.config.ConnectAuth], [addAuthData], userAddress)
 | |
|     )
 | |
|       .to.emit(dsa, "LogCast")
 | |
|       .withArgs(userAddress, userAddress, 0);
 | |
| 
 | |
|     expect(await dsa.isAuth(gelatoCore.address)).to.be.true;
 | |
|   });
 | |
| 
 | |
|   it("#5: ConnectGelato is deployed and whitelisted on mainnet", async function () {
 | |
|     expect(
 | |
|       await instaConnectors.isConnector([hre.network.config.ConnectGelato])
 | |
|     ).to.be.true;
 | |
|   });
 | |
| 
 | |
|   it("#6: Gelato ProviderModuleDsa returns correct execPayload", async function () {
 | |
|     // Deposit 1 ETH into DSA
 | |
|     await userWallet.sendTransaction({
 | |
|       to: dsaAddress,
 | |
|       value: ethers.utils.parseEther("1"),
 | |
|     });
 | |
|     expect(await ethers.provider.getBalance(dsaAddress)).to.be.equal(
 | |
|       ethers.utils.parseEther("1")
 | |
|     );
 | |
| 
 | |
|     // We withdraw to otherWallet to ignore gasUsed during test
 | |
|     const { 1: otherWallet } = await ethers.getSigners();
 | |
| 
 | |
|     // Instantiate Gelato ConnectBasic.withdraw Task
 | |
|     const withdrawFromDSATask = new GelatoCoreLib.Task({
 | |
|       actions: [
 | |
|         new GelatoCoreLib.Action({
 | |
|           addr: hre.network.config.ConnectBasic,
 | |
|           data: await hre.run("abi-encode-withselector", {
 | |
|             abi: ConnectBasic.abi,
 | |
|             functionname: "withdraw",
 | |
|             inputs: [
 | |
|               ETH,
 | |
|               ethers.utils.parseEther("1"),
 | |
|               await otherWallet.getAddress(),
 | |
|               0,
 | |
|               0,
 | |
|             ],
 | |
|           }),
 | |
|           operation: GelatoCoreLib.Operation.Delegatecall, // placeholder
 | |
|         }),
 | |
|       ],
 | |
|     });
 | |
| 
 | |
|     // otherWallet needs to be an authority to qualify as withdraw to address.
 | |
|     const addAuthData = await hre.run("abi-encode-withselector", {
 | |
|       abi: ConnectAuth.abi,
 | |
|       functionname: "add",
 | |
|       inputs: [await otherWallet.getAddress()],
 | |
|     });
 | |
|     await dsa.cast(
 | |
|       [hre.network.config.ConnectAuth],
 | |
|       [addAuthData],
 | |
|       userAddress
 | |
|     );
 | |
| 
 | |
|     const [execPayload] = await providerModuleDSA.execPayload(
 | |
|       0, // placeholder
 | |
|       ethers.constants.AddressZero, // placeholder
 | |
|       ethers.constants.AddressZero, // placeholder
 | |
|       withdrawFromDSATask,
 | |
|       0 // placeholder
 | |
|     );
 | |
| 
 | |
|     await expect(() =>
 | |
|       userWallet.sendTransaction({
 | |
|         to: dsaAddress,
 | |
|         data: execPayload,
 | |
|       })
 | |
|     ).to.changeBalance(otherWallet, ethers.utils.parseEther("1"));
 | |
|     expect(await ethers.provider.getBalance(dsaAddress)).to.be.equal(0);
 | |
|   });
 | |
| });
 | 
