mirror of
https://github.com/Instadapp/Gelato-automations.git
synced 2024-07-29 22:28:07 +00:00
863 lines
27 KiB
JavaScript
863 lines
27 KiB
JavaScript
const {expect} = require("chai");
|
|
const hre = require("hardhat");
|
|
const {ethers} = hre;
|
|
const GelatoCoreLib = require("@gelatonetwork/core");
|
|
|
|
const InstaIndex = require("../../pre-compiles/InstaIndex.json");
|
|
const InstaList = require("../../pre-compiles/InstaList.json");
|
|
const InstaAccount = require("../../pre-compiles/InstaAccount.json");
|
|
const ConnectGelato = require("../../pre-compiles/ConnectGelato.json");
|
|
const ConnectMaker = require("../../pre-compiles/ConnectMaker.json");
|
|
const ConnectCompound = require("../../pre-compiles/ConnectCompound.json");
|
|
const ConnectInstaPool = require("../../pre-compiles/ConnectInstaPool.json");
|
|
const ConnectAuth = require("../../pre-compiles/ConnectAuth.json");
|
|
|
|
const InstaConnector = require("../../pre-compiles/InstaConnectors.json");
|
|
const InstaMapping = require("../../pre-compiles/InstaMapping.json");
|
|
const DssCdpManager = require("../../pre-compiles/DssCdpManager.json");
|
|
const GetCdps = require("../../pre-compiles/GetCdps.json");
|
|
const IERC20 = require("../../pre-compiles/IERC20.json");
|
|
const CTokenInterface = require("../../pre-compiles/CTokenInterface.json");
|
|
const CompoundResolver = require("../../pre-compiles/InstaCompoundResolver.json");
|
|
const PriceOracleResolverABI = require("../../artifacts/contracts/resolvers/PriceOracleResolver.sol/PriceOracleResolver.json")
|
|
.abi;
|
|
const ConnectGelatoProviderPaymentABI = require("../../artifacts/contracts/connectors/ConnectGelatoProviderPayment.sol/ConnectGelatoProviderPayment.json")
|
|
.abi;
|
|
const ConnectGelatoDebtBridgeFromMakerABI = require("../../artifacts/contracts/connectors/ConnectGelatoDebtBridgeFromMaker.sol/ConnectGelatoDebtBridgeFromMaker.json")
|
|
.abi;
|
|
|
|
const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
const GAS_LIMIT = "4000000";
|
|
const GAS_PRICE_CEIL = ethers.utils.parseUnits("1000", "gwei");
|
|
|
|
const MIN_COL_RATIO_MAKER = ethers.utils.parseUnits("3", 18);
|
|
|
|
// TO DO: make dynamic based on real time Collateral Price and Ratios
|
|
const MAKER_INITIAL_ETH = ethers.utils.parseEther("10");
|
|
const MAKER_INITIAL_DEBT = ethers.utils.parseUnits("1000", 18);
|
|
|
|
// #endregion
|
|
|
|
class Helper {
|
|
async address() {
|
|
let userWallet;
|
|
let userAddress;
|
|
let providerWallet;
|
|
let providerAddress;
|
|
let executorWallet;
|
|
let executorAddress;
|
|
|
|
[userWallet, providerWallet, executorWallet] = await ethers.getSigners();
|
|
userAddress = await userWallet.getAddress();
|
|
providerAddress = await providerWallet.getAddress();
|
|
executorAddress = await executorWallet.getAddress();
|
|
|
|
// Hardhat default accounts prefilled with 100 ETH
|
|
expect(await userWallet.getBalance()).to.be.gt(
|
|
ethers.utils.parseEther("10")
|
|
);
|
|
|
|
return {
|
|
userWallet: userWallet,
|
|
userAddress: userAddress,
|
|
providerWallet: providerWallet,
|
|
providerAddress: providerAddress,
|
|
executorWallet: executorWallet,
|
|
executorAddress: executorAddress,
|
|
};
|
|
}
|
|
|
|
async contracts() {
|
|
// Deployed instances
|
|
let connectGelato;
|
|
let connectMaker;
|
|
let connectInstaPool;
|
|
let connectCompound;
|
|
let instaIndex;
|
|
let instaList;
|
|
let dssCdpManager;
|
|
let getCdps;
|
|
let daiToken;
|
|
let gelatoCore;
|
|
let cDaiToken;
|
|
let cEthToken;
|
|
let instaMaster;
|
|
let instaMapping;
|
|
let instaConnectors;
|
|
let compoundResolver;
|
|
// Contracts to deploy and use for local testing
|
|
let conditionMakerVaultUnsafe;
|
|
let connectGelatoDebtBridgeFromMaker;
|
|
let connectGelatoProviderPayment;
|
|
let priceOracleResolver;
|
|
let dsaProviderModule;
|
|
|
|
instaMaster = await ethers.provider.getSigner(
|
|
hre.network.config.InstaMaster
|
|
);
|
|
|
|
// ===== Get Deployed Contract Instance ==================
|
|
instaIndex = await ethers.getContractAt(
|
|
InstaIndex.abi,
|
|
hre.network.config.InstaIndex
|
|
);
|
|
instaMapping = await ethers.getContractAt(
|
|
InstaMapping.abi,
|
|
hre.network.config.InstaMapping
|
|
);
|
|
instaList = await ethers.getContractAt(
|
|
InstaList.abi,
|
|
hre.network.config.InstaList
|
|
);
|
|
connectGelato = await ethers.getContractAt(
|
|
ConnectGelato.abi,
|
|
hre.network.config.ConnectGelato
|
|
);
|
|
connectMaker = await ethers.getContractAt(
|
|
ConnectMaker.abi,
|
|
hre.network.config.ConnectMaker
|
|
);
|
|
connectInstaPool = await ethers.getContractAt(
|
|
ConnectInstaPool.abi,
|
|
hre.network.config.ConnectInstaPool
|
|
);
|
|
connectCompound = await ethers.getContractAt(
|
|
ConnectCompound.abi,
|
|
hre.network.config.ConnectCompound
|
|
);
|
|
dssCdpManager = await ethers.getContractAt(
|
|
DssCdpManager.abi,
|
|
hre.network.config.DssCdpManager
|
|
);
|
|
getCdps = await ethers.getContractAt(
|
|
GetCdps.abi,
|
|
hre.network.config.GetCdps
|
|
);
|
|
daiToken = await ethers.getContractAt(IERC20.abi, hre.network.config.DAI);
|
|
gelatoCore = await ethers.getContractAt(
|
|
GelatoCoreLib.GelatoCore.abi,
|
|
hre.network.config.GelatoCore
|
|
);
|
|
cDaiToken = await ethers.getContractAt(
|
|
CTokenInterface.abi,
|
|
hre.network.config.CDAI
|
|
);
|
|
cEthToken = await ethers.getContractAt(
|
|
CTokenInterface.abi,
|
|
hre.network.config.CETH
|
|
);
|
|
instaConnectors = await ethers.getContractAt(
|
|
InstaConnector.abi,
|
|
hre.network.config.InstaConnectors
|
|
);
|
|
compoundResolver = await ethers.getContractAt(
|
|
CompoundResolver.abi,
|
|
hre.network.config.CompoundResolver
|
|
);
|
|
|
|
// ===== Deploy Needed Contract ==================
|
|
|
|
const PriceOracleResolver = await ethers.getContractFactory(
|
|
"PriceOracleResolver"
|
|
);
|
|
priceOracleResolver = await PriceOracleResolver.deploy();
|
|
await priceOracleResolver.deployed();
|
|
|
|
const ConditionMakerVaultUnsafe = await ethers.getContractFactory(
|
|
"ConditionMakerVaultUnsafe"
|
|
);
|
|
conditionMakerVaultUnsafe = await ConditionMakerVaultUnsafe.deploy();
|
|
await conditionMakerVaultUnsafe.deployed();
|
|
|
|
const ConnectGelatoDebtBridgeFromMaker = await ethers.getContractFactory(
|
|
"ConnectGelatoDebtBridgeFromMaker"
|
|
);
|
|
connectGelatoDebtBridgeFromMaker = await ConnectGelatoDebtBridgeFromMaker.deploy(
|
|
(await instaConnectors.connectorLength()).add(1)
|
|
);
|
|
await connectGelatoDebtBridgeFromMaker.deployed();
|
|
|
|
const ConnectGelatoProviderPayment = await ethers.getContractFactory(
|
|
"ConnectGelatoProviderPayment"
|
|
);
|
|
connectGelatoProviderPayment = await ConnectGelatoProviderPayment.deploy(
|
|
(await instaConnectors.connectorLength()).add(2)
|
|
);
|
|
await connectGelatoProviderPayment.deployed();
|
|
|
|
const ProviderModuleDSA = await ethers.getContractFactory(
|
|
"ProviderModuleDSA"
|
|
);
|
|
dsaProviderModule = await ProviderModuleDSA.deploy(
|
|
hre.network.config.GelatoCore,
|
|
connectGelatoProviderPayment.address
|
|
);
|
|
await dsaProviderModule.deployed();
|
|
|
|
return {
|
|
connectGelato: connectGelato,
|
|
connectMaker: connectMaker,
|
|
connectInstaPool: connectInstaPool,
|
|
connectCompound: connectCompound,
|
|
instaIndex: instaIndex,
|
|
instaList: instaList,
|
|
instaMapping: instaMapping,
|
|
dssCdpManager: dssCdpManager,
|
|
getCdps: getCdps,
|
|
daiToken: daiToken,
|
|
gelatoCore: gelatoCore,
|
|
cDaiToken: cDaiToken,
|
|
cEthToken: cEthToken,
|
|
instaMaster: instaMaster,
|
|
instaConnectors: instaConnectors,
|
|
compoundResolver: compoundResolver,
|
|
conditionMakerVaultUnsafe: conditionMakerVaultUnsafe,
|
|
connectGelatoDebtBridgeFromMaker: connectGelatoDebtBridgeFromMaker,
|
|
connectGelatoProviderPayment: connectGelatoProviderPayment,
|
|
priceOracleResolver: priceOracleResolver,
|
|
dsaProviderModule: dsaProviderModule,
|
|
dsa: ethers.constants.AddressZero,
|
|
};
|
|
}
|
|
|
|
async makerToCompoundTestSetup() {
|
|
let address = await this.address();
|
|
let contracts = await this.contracts();
|
|
let vaultId;
|
|
|
|
// Gelato Testing environment setup.
|
|
await this.enableGelatoConnectorsForFromMaker(address, contracts);
|
|
await this.executorDoStaking(address, contracts);
|
|
await this.providerDoFunding(address, contracts);
|
|
await this.providerChooseExecutor(address, contracts);
|
|
await this.providerAddCustomModuleForPayment(address, contracts);
|
|
await this.userCreateADSA(address, contracts);
|
|
vaultId = await this.userOpenDepositBorrowOnMakerVault(address, contracts);
|
|
let spells = await this.providerWhiteListTaskForMakerToCompound(
|
|
address,
|
|
contracts,
|
|
vaultId
|
|
);
|
|
|
|
return {
|
|
address: address,
|
|
contracts: contracts,
|
|
vaultId: vaultId,
|
|
spells: spells,
|
|
};
|
|
}
|
|
|
|
async makerETHAToMakerETHBSetup() {
|
|
let address = await this.address();
|
|
let contracts = await this.contracts();
|
|
let vaultAId;
|
|
|
|
// Gelato Testing environment setup.
|
|
await this.enableGelatoConnectorsForFromMaker(address, contracts);
|
|
await this.executorDoStaking(address, contracts);
|
|
await this.providerDoFunding(address, contracts);
|
|
await this.providerChooseExecutor(address, contracts);
|
|
await this.providerAddCustomModuleForPayment(address, contracts);
|
|
await this.userCreateADSA(address, contracts);
|
|
await this.masterAddETHBOnGemJoinMapping(address, contracts);
|
|
vaultAId = await this.userOpenDepositBorrowOnMakerVault(address, contracts);
|
|
let spells = await this.providerWhiteListTaskForMakerETHAToMakerETHB(
|
|
address,
|
|
contracts,
|
|
vaultAId
|
|
);
|
|
|
|
return {
|
|
address: address,
|
|
contracts: contracts,
|
|
vaultAId: vaultAId,
|
|
spells: spells,
|
|
};
|
|
}
|
|
|
|
async enableGelatoConnectorsForFromMaker(address, contracts) {
|
|
//#region Enable Debt Bridge Connector and Gelato Provider Payment Connector
|
|
|
|
// Debt Bridge Connector is used during refinancing of debt
|
|
// This Connect help the user to split a position in one protocol.
|
|
// to 2 protocol in a safe way. Both debt position will be safe.
|
|
|
|
// Gelato Provider Payment Connector is used for paying the provider
|
|
// for task execution. So when futur task will be executed, through a self financing
|
|
// transaction (user will pay during the execution of the task) task will
|
|
// be executed. Improvind user experience.
|
|
|
|
await address.userWallet.sendTransaction({
|
|
to: hre.network.config.InstaMaster,
|
|
value: ethers.utils.parseEther("0.1"),
|
|
});
|
|
|
|
await hre.network.provider.request({
|
|
method: "hardhat_impersonateAccount",
|
|
params: [await contracts.instaMaster.getAddress()],
|
|
});
|
|
|
|
await contracts.instaConnectors
|
|
.connect(contracts.instaMaster)
|
|
.enable(contracts.connectGelatoDebtBridgeFromMaker.address);
|
|
|
|
await contracts.instaConnectors
|
|
.connect(contracts.instaMaster)
|
|
.enable(contracts.connectGelatoProviderPayment.address);
|
|
|
|
await hre.network.provider.request({
|
|
method: "hardhat_stopImpersonatingAccount",
|
|
params: [await contracts.instaMaster.getAddress()],
|
|
});
|
|
|
|
expect(
|
|
await contracts.instaConnectors.isConnector([
|
|
contracts.connectGelatoDebtBridgeFromMaker.address,
|
|
])
|
|
).to.be.true;
|
|
expect(
|
|
await contracts.instaConnectors.isConnector([
|
|
contracts.connectGelatoProviderPayment.address,
|
|
])
|
|
).to.be.true;
|
|
|
|
//#endregion
|
|
}
|
|
|
|
async executorDoStaking(address, contracts) {
|
|
//#region Executor Staking on Gelato
|
|
|
|
// For task execution provider will ask a executor to watch the
|
|
// blockchain for possible execution autorization given by
|
|
// the condition that user choose when submitting the task.
|
|
// And if all condition are meet executor will execute the task.
|
|
// For safety measure Gelato ask the executor to stake a minimum
|
|
// amount.
|
|
|
|
await contracts.gelatoCore.connect(address.executorWallet).stakeExecutor({
|
|
value: await contracts.gelatoCore.minExecutorStake(),
|
|
});
|
|
|
|
expect(
|
|
await contracts.gelatoCore.isExecutorMinStaked(address.executorAddress)
|
|
).to.be.true;
|
|
|
|
//#endregion
|
|
}
|
|
|
|
async providerDoFunding(address, contracts) {
|
|
//#region Provider put some fund on gelato for paying future tasks executions
|
|
|
|
// Provider put some funds in gelato system for paying the
|
|
// Executor when this one will execute task on behalf of the
|
|
// Provider. At each provider's task execution, some funds (approximatively
|
|
// the gas cost value) will be transfered to the Executor stake.
|
|
|
|
const TASK_AUTOMATION_FUNDS = await contracts.gelatoCore.minExecProviderFunds(
|
|
GAS_LIMIT,
|
|
GAS_PRICE_CEIL
|
|
);
|
|
|
|
await expect(
|
|
contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.provideFunds(address.providerAddress, {
|
|
value: TASK_AUTOMATION_FUNDS,
|
|
})
|
|
).to.emit(contracts.gelatoCore, "LogFundsProvided");
|
|
|
|
expect(
|
|
await contracts.gelatoCore.providerFunds(address.providerAddress)
|
|
).to.be.equal(TASK_AUTOMATION_FUNDS);
|
|
|
|
//#endregion
|
|
}
|
|
|
|
async providerChooseExecutor(address, contracts) {
|
|
//#region Provider choose a executor
|
|
|
|
// Provider choose a executor who will execute futur task
|
|
// for the provider, it will be compensated by the provider.
|
|
|
|
await expect(
|
|
contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.providerAssignsExecutor(address.executorAddress)
|
|
).to.emit(contracts.gelatoCore, "LogProviderAssignedExecutor");
|
|
|
|
expect(
|
|
await contracts.gelatoCore.executorByProvider(address.providerAddress)
|
|
).to.be.equal(address.executorAddress);
|
|
|
|
//#endregion
|
|
}
|
|
|
|
async providerAddCustomModuleForPayment(address, contracts) {
|
|
//#region Provider will add a module
|
|
|
|
// By adding a module the provider will format future task's
|
|
// payload by adding some specificity like his address to the
|
|
// Payment connector for receiving payment of User.
|
|
|
|
await expect(
|
|
contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.addProviderModules([contracts.dsaProviderModule.address])
|
|
).to.emit(contracts.gelatoCore, "LogProviderModuleAdded");
|
|
|
|
expect(
|
|
await contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.isModuleProvided(
|
|
address.providerAddress,
|
|
contracts.dsaProviderModule.address
|
|
)
|
|
).to.be.true;
|
|
|
|
//#endregion
|
|
}
|
|
|
|
async userCreateADSA(address, contracts) {
|
|
//#region User create a DeFi Smart Account
|
|
|
|
// User create a Instadapp DeFi Smart Account
|
|
// who give him the possibility to interact
|
|
// with a large list of DeFi protocol through one
|
|
// Proxy account.
|
|
|
|
const dsaAccountCount = await contracts.instaList.accounts();
|
|
|
|
await expect(
|
|
contracts.instaIndex.build(address.userAddress, 1, address.userAddress)
|
|
).to.emit(contracts.instaIndex, "LogAccountCreated");
|
|
const dsaID = dsaAccountCount.add(1);
|
|
await expect(await contracts.instaList.accounts()).to.be.equal(dsaID);
|
|
|
|
// Instantiate the DSA
|
|
const dsa = await ethers.getContractAt(
|
|
InstaAccount.abi,
|
|
await contracts.instaList.accountAddr(dsaID)
|
|
);
|
|
|
|
contracts.dsa = dsa;
|
|
|
|
//#endregion
|
|
}
|
|
|
|
async userOpenDepositBorrowOnMakerVault(address, contracts) {
|
|
//#region Step 8 User open a Vault, put some ether on it and borrow some dai
|
|
|
|
// User open a maker vault
|
|
// He deposit 10 Eth on it
|
|
// He borrow a 1000 DAI
|
|
const dsa = contracts.dsa;
|
|
const openVault = await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "open",
|
|
inputs: ["ETH-A"],
|
|
});
|
|
|
|
await dsa.cast(
|
|
[hre.network.config.ConnectMaker],
|
|
[openVault],
|
|
address.userAddress
|
|
);
|
|
|
|
const cdps = await contracts.getCdps.getCdpsAsc(
|
|
contracts.dssCdpManager.address,
|
|
dsa.address
|
|
);
|
|
let vaultId = String(cdps.ids[0]);
|
|
expect(cdps.ids[0].isZero()).to.be.false;
|
|
|
|
await dsa.cast(
|
|
[hre.network.config.ConnectMaker],
|
|
[
|
|
await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "deposit",
|
|
inputs: [vaultId, MAKER_INITIAL_ETH, 0, 0],
|
|
}),
|
|
],
|
|
address.userAddress,
|
|
{
|
|
value: MAKER_INITIAL_ETH,
|
|
}
|
|
);
|
|
|
|
await dsa.cast(
|
|
[hre.network.config.ConnectMaker],
|
|
[
|
|
await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "borrow",
|
|
inputs: [vaultId, MAKER_INITIAL_DEBT, 0, 0],
|
|
}),
|
|
],
|
|
address.userAddress
|
|
);
|
|
|
|
expect(await contracts.daiToken.balanceOf(dsa.address)).to.be.equal(
|
|
MAKER_INITIAL_DEBT
|
|
);
|
|
|
|
//#endregion
|
|
|
|
return vaultId;
|
|
}
|
|
|
|
async masterAddETHBOnGemJoinMapping(address, contracts) {
|
|
await address.userWallet.sendTransaction({
|
|
to: hre.network.config.InstaMaster,
|
|
value: ethers.utils.parseEther("0.1"),
|
|
});
|
|
|
|
await hre.network.provider.request({
|
|
method: "hardhat_impersonateAccount",
|
|
params: [await contracts.instaMaster.getAddress()],
|
|
});
|
|
|
|
const ethBGemJoin = "0x08638eF1A205bE6762A8b935F5da9b700Cf7322c";
|
|
await expect(
|
|
contracts.instaMapping
|
|
.connect(contracts.instaMaster)
|
|
.addGemJoinMapping([ethBGemJoin])
|
|
).to.emit(contracts.instaMapping, "LogAddGemJoinMapping");
|
|
}
|
|
|
|
// Instadapp UI should do the same implementation for submitting debt bridge task
|
|
async providerWhiteListTaskForMakerToCompound(address, contracts, vaultId) {
|
|
//#region Step 9 Provider should whitelist task
|
|
|
|
// By WhiteList task, the provider can constrain the type
|
|
// of task the user can submitting.
|
|
|
|
//#region Actions
|
|
|
|
let spells = [];
|
|
|
|
const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({
|
|
addr: contracts.connectGelatoDebtBridgeFromMaker.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectGelatoDebtBridgeFromMakerABI,
|
|
functionname: "saveFullRefinanceDataToMemory",
|
|
inputs: [vaultId, 0, 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(debtBridgeCalculationForFullRefinance);
|
|
|
|
const flashBorrow = new GelatoCoreLib.Action({
|
|
addr: contracts.connectInstaPool.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectInstaPool.abi,
|
|
functionname: "flashBorrow",
|
|
inputs: [hre.network.config.DAI, 0, "600", 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(flashBorrow);
|
|
|
|
const paybackMaker = new GelatoCoreLib.Action({
|
|
addr: contracts.connectMaker.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "payback",
|
|
inputs: [vaultId, ethers.constants.MaxUint256, 0, 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(paybackMaker);
|
|
|
|
const withdrawMaker = new GelatoCoreLib.Action({
|
|
addr: contracts.connectMaker.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "withdraw",
|
|
inputs: [vaultId, ethers.constants.MaxUint256, 0, 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(withdrawMaker);
|
|
|
|
const depositCompound = new GelatoCoreLib.Action({
|
|
addr: contracts.connectCompound.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectCompound.abi,
|
|
functionname: "deposit",
|
|
inputs: [ETH, 0, "603", 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(depositCompound);
|
|
|
|
const borrowCompound = new GelatoCoreLib.Action({
|
|
addr: contracts.connectCompound.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectCompound.abi,
|
|
functionname: "borrow",
|
|
inputs: [hre.network.config.DAI, 0, "604", 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(borrowCompound);
|
|
|
|
const flashPayBack = new GelatoCoreLib.Action({
|
|
addr: contracts.connectInstaPool.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectInstaPool.abi,
|
|
functionname: "flashPayback",
|
|
inputs: [hre.network.config.DAI, 0, 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(flashPayBack);
|
|
|
|
const payProvider = new GelatoCoreLib.Action({
|
|
addr: contracts.connectGelatoProviderPayment.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectGelatoProviderPaymentABI,
|
|
functionname: "payProvider",
|
|
inputs: [address.providerAddress, ETH, 0, "605", 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(payProvider);
|
|
|
|
const gasPriceCeil = ethers.constants.MaxUint256;
|
|
|
|
const connectGelatoDebtBridgeFromMakerTaskSpec = new GelatoCoreLib.TaskSpec(
|
|
{
|
|
conditions: [contracts.conditionMakerVaultUnsafe.address],
|
|
actions: spells,
|
|
gasPriceCeil,
|
|
}
|
|
);
|
|
|
|
await expect(
|
|
contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.provideTaskSpecs([connectGelatoDebtBridgeFromMakerTaskSpec])
|
|
).to.emit(contracts.gelatoCore, "LogTaskSpecProvided");
|
|
|
|
expect(
|
|
await contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.isTaskSpecProvided(
|
|
address.providerAddress,
|
|
connectGelatoDebtBridgeFromMakerTaskSpec
|
|
)
|
|
).to.be.equal("OK");
|
|
|
|
expect(
|
|
await contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.taskSpecGasPriceCeil(
|
|
address.providerAddress,
|
|
await contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.hashTaskSpec(connectGelatoDebtBridgeFromMakerTaskSpec)
|
|
)
|
|
).to.be.equal(gasPriceCeil);
|
|
|
|
//#endregion
|
|
|
|
return spells;
|
|
}
|
|
|
|
// Instadapp UI should do the same implementation for submitting debt bridge task
|
|
async providerWhiteListTaskForMakerETHAToMakerETHB(
|
|
address,
|
|
contracts,
|
|
vaultId
|
|
) {
|
|
//#region Step 9 Provider should whitelist task
|
|
|
|
// By WhiteList task, the provider can constrain the type
|
|
// of task the user can submitting.
|
|
|
|
//#region Actions
|
|
|
|
let spells = [];
|
|
|
|
const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({
|
|
addr: contracts.connectGelatoDebtBridgeFromMaker.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectGelatoDebtBridgeFromMakerABI,
|
|
functionname: "saveFullRefinanceDataToMemory",
|
|
inputs: [vaultId, 0, 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(debtBridgeCalculationForFullRefinance);
|
|
|
|
const flashBorrow = new GelatoCoreLib.Action({
|
|
addr: contracts.connectInstaPool.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectInstaPool.abi,
|
|
functionname: "flashBorrow",
|
|
inputs: [hre.network.config.DAI, 0, "600", 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(flashBorrow);
|
|
|
|
const paybackMaker = new GelatoCoreLib.Action({
|
|
addr: contracts.connectMaker.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "payback",
|
|
inputs: [vaultId, ethers.constants.MaxUint256, 0, 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(paybackMaker);
|
|
|
|
const withdrawMaker = new GelatoCoreLib.Action({
|
|
addr: contracts.connectMaker.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "withdraw",
|
|
inputs: [vaultId, ethers.constants.MaxUint256, 0, 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(withdrawMaker);
|
|
|
|
const openVaultB = new GelatoCoreLib.Action({
|
|
addr: contracts.connectMaker.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "open",
|
|
inputs: ["ETH-B"],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(openVaultB);
|
|
|
|
const depositMakerOnVaultB = new GelatoCoreLib.Action({
|
|
addr: contracts.connectMaker.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "deposit",
|
|
inputs: [0, 0, "603", 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(depositMakerOnVaultB);
|
|
|
|
const borrowOnVaultB = new GelatoCoreLib.Action({
|
|
addr: contracts.connectMaker.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectMaker.abi,
|
|
functionname: "borrow",
|
|
inputs: [0, 0, "604", 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(borrowOnVaultB);
|
|
|
|
const flashPayBack = new GelatoCoreLib.Action({
|
|
addr: contracts.connectInstaPool.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectInstaPool.abi,
|
|
functionname: "flashPayback",
|
|
inputs: [hre.network.config.DAI, 0, 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(flashPayBack);
|
|
|
|
const payProvider = new GelatoCoreLib.Action({
|
|
addr: contracts.connectGelatoProviderPayment.address,
|
|
data: await hre.run("abi-encode-withselector", {
|
|
abi: ConnectGelatoProviderPaymentABI,
|
|
functionname: "payProvider",
|
|
inputs: [address.providerAddress, ETH, 0, "605", 0],
|
|
}),
|
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
|
});
|
|
|
|
spells.push(payProvider);
|
|
|
|
const gasPriceCeil = ethers.constants.MaxUint256;
|
|
|
|
const connectGelatoDebtBridgeFromMakerTaskSpec = new GelatoCoreLib.TaskSpec(
|
|
{
|
|
conditions: [contracts.conditionMakerVaultUnsafe.address],
|
|
actions: spells,
|
|
gasPriceCeil,
|
|
}
|
|
);
|
|
|
|
await expect(
|
|
contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.provideTaskSpecs([connectGelatoDebtBridgeFromMakerTaskSpec])
|
|
).to.emit(contracts.gelatoCore, "LogTaskSpecProvided");
|
|
|
|
expect(
|
|
await contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.isTaskSpecProvided(
|
|
address.providerAddress,
|
|
connectGelatoDebtBridgeFromMakerTaskSpec
|
|
)
|
|
).to.be.equal("OK");
|
|
|
|
expect(
|
|
await contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.taskSpecGasPriceCeil(
|
|
address.providerAddress,
|
|
await contracts.gelatoCore
|
|
.connect(address.providerWallet)
|
|
.hashTaskSpec(connectGelatoDebtBridgeFromMakerTaskSpec)
|
|
)
|
|
).to.be.equal(gasPriceCeil);
|
|
|
|
//#endregion
|
|
|
|
return spells;
|
|
}
|
|
|
|
async getABI() {
|
|
return {
|
|
PriceOracleResolverABI: PriceOracleResolverABI,
|
|
ConnectGelatoABI: ConnectGelato.abi,
|
|
ConnectAuthABI: ConnectAuth.abi,
|
|
};
|
|
}
|
|
|
|
async getConstants() {
|
|
return {
|
|
MIN_COL_RATIO_MAKER: MIN_COL_RATIO_MAKER,
|
|
GAS_PRICE_CEIL: GAS_PRICE_CEIL,
|
|
GAS_LIMIT: GAS_LIMIT,
|
|
MAKER_INITIAL_DEBT: MAKER_INITIAL_DEBT,
|
|
};
|
|
}
|
|
|
|
getConnectAuth() {
|
|
return ConnectAuth;
|
|
}
|
|
}
|
|
|
|
module.exports = Helper;
|