mirror of
https://github.com/Instadapp/Gelato-automations.git
synced 2024-07-29 22:28:07 +00:00
Do Vault creation if Vault B is not owned anymore by dsa
This commit is contained in:
parent
5b055edca7
commit
d4b78c25ce
|
@ -11,17 +11,16 @@ import {
|
||||||
import {
|
import {
|
||||||
IConnectInstaPoolV2
|
IConnectInstaPoolV2
|
||||||
} from "../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol";
|
} from "../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol";
|
||||||
import {IMcdManager} from "../../interfaces/dapps/Maker/IMcdManager.sol";
|
|
||||||
import {
|
import {
|
||||||
DAI,
|
DAI,
|
||||||
CONNECT_MAKER,
|
CONNECT_MAKER,
|
||||||
CONNECT_COMPOUND,
|
CONNECT_COMPOUND,
|
||||||
INSTA_POOL_V2
|
INSTA_POOL_V2
|
||||||
} from "../../constants/CInstaDapp.sol";
|
} from "../../constants/CInstaDapp.sol";
|
||||||
import {MCD_MANAGER} from "../../constants/CMaker.sol";
|
|
||||||
import {
|
import {
|
||||||
_getMakerVaultDebt,
|
_getMakerVaultDebt,
|
||||||
_getMakerVaultCollateralBalance
|
_getMakerVaultCollateralBalance,
|
||||||
|
_isVaultOwnedBy
|
||||||
} from "../../functions/dapps/FMaker.sol";
|
} from "../../functions/dapps/FMaker.sol";
|
||||||
import {
|
import {
|
||||||
_encodeFlashPayback
|
_encodeFlashPayback
|
||||||
|
@ -93,12 +92,11 @@ contract ConnectGelatoDataFullMakerToCompound is
|
||||||
uint256 // cycleId
|
uint256 // cycleId
|
||||||
) public view virtual override returns (string memory) {
|
) public view virtual override returns (string memory) {
|
||||||
(uint256 vaultId, ) = abi.decode(_actionData[4:], (uint256, address));
|
(uint256 vaultId, ) = abi.decode(_actionData[4:], (uint256, address));
|
||||||
IMcdManager managerContract = IMcdManager(MCD_MANAGER);
|
|
||||||
|
|
||||||
if (vaultId == 0)
|
if (vaultId == 0)
|
||||||
return "ConnectGelatoDataFullETHAToETHB : Vault Id is not valid";
|
return "ConnectGelatoDataFullETHAToETHB : Vault Id is not valid";
|
||||||
if (managerContract.owns(vaultId) != _dsa)
|
if (_isVaultOwnedBy(vaultId, _dsa))
|
||||||
return "ConnectGelatoDataFullETHAToETHB : Vault not owns by dsa";
|
return "ConnectGelatoDataFullETHAToETHB : Vault not owned by dsa";
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,17 +11,16 @@ import {
|
||||||
import {
|
import {
|
||||||
IConnectInstaPoolV2
|
IConnectInstaPoolV2
|
||||||
} from "../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol";
|
} from "../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol";
|
||||||
import {IMcdManager} from "../../interfaces/dapps/Maker/IMcdManager.sol";
|
|
||||||
import {
|
import {
|
||||||
DAI,
|
DAI,
|
||||||
CONNECT_MAKER,
|
CONNECT_MAKER,
|
||||||
CONNECT_COMPOUND,
|
CONNECT_COMPOUND,
|
||||||
INSTA_POOL_V2
|
INSTA_POOL_V2
|
||||||
} from "../../constants/CInstaDapp.sol";
|
} from "../../constants/CInstaDapp.sol";
|
||||||
import {MCD_MANAGER} from "../../constants/CMaker.sol";
|
|
||||||
import {
|
import {
|
||||||
_getMakerVaultDebt,
|
_getMakerVaultDebt,
|
||||||
_getMakerVaultCollateralBalance
|
_getMakerVaultCollateralBalance,
|
||||||
|
_isVaultOwnedBy
|
||||||
} from "../../functions/dapps/FMaker.sol";
|
} from "../../functions/dapps/FMaker.sol";
|
||||||
import {
|
import {
|
||||||
_encodeFlashPayback
|
_encodeFlashPayback
|
||||||
|
@ -92,17 +91,13 @@ contract ConnectGelatoDataFullMakerToMaker is
|
||||||
uint256, // value
|
uint256, // value
|
||||||
uint256 // cycleId
|
uint256 // cycleId
|
||||||
) public view virtual override returns (string memory) {
|
) public view virtual override returns (string memory) {
|
||||||
(uint256 vaultAId, uint256 vaultBId, , ) =
|
(uint256 vaultAId, , , ) =
|
||||||
abi.decode(_actionData[4:], (uint256, uint256, address, string));
|
abi.decode(_actionData[4:], (uint256, uint256, address, string));
|
||||||
|
|
||||||
IMcdManager managerContract = IMcdManager(MCD_MANAGER);
|
|
||||||
|
|
||||||
if (vaultAId == 0)
|
if (vaultAId == 0)
|
||||||
return "ConnectGelatoDataFullETHAToETHB : Vault A Id is not valid";
|
return "ConnectGelatoDataFullETHAToETHB : Vault A Id is not valid";
|
||||||
if (managerContract.owns(vaultAId) != _dsa)
|
if (_isVaultOwnedBy(vaultAId, _dsa))
|
||||||
return "ConnectGelatoDataFullETHAToETHB : Vault A not owns by dsa";
|
return "ConnectGelatoDataFullETHAToETHB : Vault A not owned by dsa";
|
||||||
if (vaultBId != 0 && managerContract.owns(vaultBId) != _dsa)
|
|
||||||
return "ConnectGelatoDataFullETHAToETHB : Vault B not owns by dsa";
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +149,8 @@ contract ConnectGelatoDataFullMakerToMaker is
|
||||||
targets = new address[](1);
|
targets = new address[](1);
|
||||||
targets[0] = INSTA_POOL_V2;
|
targets[0] = INSTA_POOL_V2;
|
||||||
|
|
||||||
|
_vaultBId = _isVaultOwnedBy(_vaultBId, address(this)) ? 0 : _vaultBId;
|
||||||
|
|
||||||
uint256 wDaiToBorrow = _getRealisedDebt(_getMakerVaultDebt(_vaultAId));
|
uint256 wDaiToBorrow = _getRealisedDebt(_getMakerVaultDebt(_vaultAId));
|
||||||
uint256 wColToWithdrawFromMaker =
|
uint256 wColToWithdrawFromMaker =
|
||||||
_getMakerVaultCollateralBalance(_vaultAId);
|
_getMakerVaultCollateralBalance(_vaultAId);
|
||||||
|
|
|
@ -123,3 +123,8 @@ function _getBorrowAmt(
|
||||||
dart = sub(mul(_amt, RAY), _dai) / _rate;
|
dart = sub(mul(_amt, RAY), _dai) / _rate;
|
||||||
dart = mul(dart, _rate) < mul(_amt, RAY) ? dart + 1 : dart;
|
dart = mul(dart, _rate) < mul(_amt, RAY) ? dart + 1 : dart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _isVaultOwnedBy(uint256 _vaultId, address _owner) view returns (bool) {
|
||||||
|
IMcdManager managerContract = IMcdManager(MCD_MANAGER);
|
||||||
|
return _vaultId != 0 && managerContract.owns(_vaultId) != _owner;
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ module.exports = async function (mockRoute) {
|
||||||
const wallets = await getWallets();
|
const wallets = await getWallets();
|
||||||
const contracts = await getContracts();
|
const contracts = await getContracts();
|
||||||
const constants = await getDebtBridgeFromMakerConstants();
|
const constants = await getDebtBridgeFromMakerConstants();
|
||||||
|
const ABI = getABI();
|
||||||
|
|
||||||
// Gelato Testing environment setup.
|
// Gelato Testing environment setup.
|
||||||
await provideFunds(
|
await provideFunds(
|
||||||
|
@ -44,7 +45,8 @@ module.exports = async function (mockRoute) {
|
||||||
contracts.getCdps,
|
contracts.getCdps,
|
||||||
contracts.dssCdpManager,
|
contracts.dssCdpManager,
|
||||||
constants.MAKER_INITIAL_ETH,
|
constants.MAKER_INITIAL_ETH,
|
||||||
constants.MAKER_INITIAL_DEBT
|
constants.MAKER_INITIAL_DEBT,
|
||||||
|
ABI.ConnectMakerABI
|
||||||
);
|
);
|
||||||
const vaultBId = await createVaultForETHB(
|
const vaultBId = await createVaultForETHB(
|
||||||
wallets.userAddress,
|
wallets.userAddress,
|
||||||
|
@ -62,8 +64,6 @@ module.exports = async function (mockRoute) {
|
||||||
vaultBId
|
vaultBId
|
||||||
);
|
);
|
||||||
|
|
||||||
const ABI = getABI();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
wallets,
|
wallets,
|
||||||
contracts,
|
contracts,
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
const ConnectGelatoABI = require("../../../pre-compiles/ConnectGelato.json")
|
const ConnectGelatoABI = require("../../../pre-compiles/ConnectGelato.json")
|
||||||
.abi;
|
.abi;
|
||||||
const ConnectAuthABI = require("../../../pre-compiles/ConnectAuth.json").abi;
|
const ConnectAuthABI = require("../../../pre-compiles/ConnectAuth.json").abi;
|
||||||
|
const ConnectMakerABI = require("../../../pre-compiles/ConnectMaker.json").abi;
|
||||||
|
|
||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
return {
|
return {
|
||||||
ConnectGelatoABI: ConnectGelatoABI,
|
ConnectGelatoABI: ConnectGelatoABI,
|
||||||
ConnectAuthABI: ConnectAuthABI,
|
ConnectAuthABI: ConnectAuthABI,
|
||||||
|
ConnectMakerABI: ConnectMakerABI,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
const { expect } = require("chai");
|
const { expect } = require("chai");
|
||||||
const hre = require("hardhat");
|
const hre = require("hardhat");
|
||||||
|
|
||||||
const ConnectMaker = require("../../../../pre-compiles/ConnectMaker.json");
|
|
||||||
|
|
||||||
module.exports = async function (
|
module.exports = async function (
|
||||||
userAddress,
|
userAddress,
|
||||||
DAI,
|
DAI,
|
||||||
|
@ -10,7 +8,8 @@ module.exports = async function (
|
||||||
getCdps,
|
getCdps,
|
||||||
dssCdpManager,
|
dssCdpManager,
|
||||||
makerInitialEth,
|
makerInitialEth,
|
||||||
makerInitialDebt
|
makerInitialDebt,
|
||||||
|
connectMakerABI
|
||||||
) {
|
) {
|
||||||
//#region Step 8 User open a Vault, put some ether on it and borrow some dai
|
//#region Step 8 User open a Vault, put some ether on it and borrow some dai
|
||||||
|
|
||||||
|
@ -18,7 +17,7 @@ module.exports = async function (
|
||||||
// He deposit 10 Eth on it
|
// He deposit 10 Eth on it
|
||||||
// He borrow a 1000 DAI
|
// He borrow a 1000 DAI
|
||||||
const openVault = await hre.run("abi-encode-withselector", {
|
const openVault = await hre.run("abi-encode-withselector", {
|
||||||
abi: ConnectMaker.abi,
|
abi: connectMakerABI,
|
||||||
functionname: "open",
|
functionname: "open",
|
||||||
inputs: ["ETH-A"],
|
inputs: ["ETH-A"],
|
||||||
});
|
});
|
||||||
|
@ -33,7 +32,7 @@ module.exports = async function (
|
||||||
[hre.network.config.ConnectMaker],
|
[hre.network.config.ConnectMaker],
|
||||||
[
|
[
|
||||||
await hre.run("abi-encode-withselector", {
|
await hre.run("abi-encode-withselector", {
|
||||||
abi: ConnectMaker.abi,
|
abi: connectMakerABI,
|
||||||
functionname: "deposit",
|
functionname: "deposit",
|
||||||
inputs: [vaultId, makerInitialEth, 0, 0],
|
inputs: [vaultId, makerInitialEth, 0, 0],
|
||||||
}),
|
}),
|
||||||
|
@ -48,7 +47,7 @@ module.exports = async function (
|
||||||
[hre.network.config.ConnectMaker],
|
[hre.network.config.ConnectMaker],
|
||||||
[
|
[
|
||||||
await hre.run("abi-encode-withselector", {
|
await hre.run("abi-encode-withselector", {
|
||||||
abi: ConnectMaker.abi,
|
abi: connectMakerABI,
|
||||||
functionname: "borrow",
|
functionname: "borrow",
|
||||||
inputs: [vaultId, makerInitialDebt, 0, 0],
|
inputs: [vaultId, makerInitialDebt, 0, 0],
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -0,0 +1,349 @@
|
||||||
|
const { expect } = require("chai");
|
||||||
|
const hre = require("hardhat");
|
||||||
|
const { deployments, ethers } = hre;
|
||||||
|
const GelatoCoreLib = require("@gelatonetwork/core");
|
||||||
|
|
||||||
|
const setupFullRefinanceMakerToMaker = require("./helpers/setupFullRefinanceMakerToMaker");
|
||||||
|
const getInstaPoolV2Route = require("../../../../helpers/services/InstaDapp/getInstaPoolV2Route");
|
||||||
|
const getGasCostForFullRefinance = require("./helpers/services/getGasCostForFullRefinance");
|
||||||
|
|
||||||
|
// This test showcases how to submit a task refinancing a Users debt position from
|
||||||
|
// Maker to Compound using Gelato
|
||||||
|
describe("Full Debt Bridge refinancing loan from ETH-A to ETH-B with Vault B creation due to the closing of the previous one", function () {
|
||||||
|
this.timeout(0);
|
||||||
|
if (hre.network.name !== "hardhat") {
|
||||||
|
console.error("Test Suite is meant to be run on hardhat only");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let contracts;
|
||||||
|
let wallets;
|
||||||
|
let constants;
|
||||||
|
let ABI;
|
||||||
|
|
||||||
|
// Payload Params for ConnectGelatoFullDebtBridgeFromMaker and ConditionMakerVaultUnsafe
|
||||||
|
let vaultAId;
|
||||||
|
let vaultBId;
|
||||||
|
|
||||||
|
// For TaskSpec and for Task
|
||||||
|
let gelatoDebtBridgeSpells = [];
|
||||||
|
|
||||||
|
// Cross test var
|
||||||
|
let taskReceipt;
|
||||||
|
|
||||||
|
before(async function () {
|
||||||
|
// Reset back to a fresh forked state during runtime
|
||||||
|
await deployments.fixture();
|
||||||
|
|
||||||
|
const result = await setupFullRefinanceMakerToMaker();
|
||||||
|
|
||||||
|
wallets = result.wallets;
|
||||||
|
contracts = result.contracts;
|
||||||
|
vaultAId = result.vaultAId;
|
||||||
|
vaultBId = result.vaultBId;
|
||||||
|
gelatoDebtBridgeSpells = result.spells;
|
||||||
|
|
||||||
|
ABI = result.ABI;
|
||||||
|
constants = result.constants;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#1: DSA authorizes Gelato to cast spells.", async function () {
|
||||||
|
//#region User give authorization to gelato to use his DSA on his behalf.
|
||||||
|
|
||||||
|
// Instadapp DSA contract give the possibility to the user to delegate
|
||||||
|
// action by giving authorization.
|
||||||
|
// In this case user give authorization to gelato to execute
|
||||||
|
// task for him if needed.
|
||||||
|
|
||||||
|
await contracts.dsa.cast(
|
||||||
|
[hre.network.config.ConnectAuth],
|
||||||
|
[
|
||||||
|
await hre.run("abi-encode-withselector", {
|
||||||
|
abi: ABI.ConnectAuthABI,
|
||||||
|
functionname: "add",
|
||||||
|
inputs: [contracts.gelatoCore.address],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
wallets.userAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(await contracts.dsa.isAuth(contracts.gelatoCore.address)).to.be.true;
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#2: User submits automated Debt Bridge task to Gelato via DSA", async function () {
|
||||||
|
//#region User submit a Debt Refinancing task if market move against him
|
||||||
|
|
||||||
|
// User submit the refinancing task if market move against him.
|
||||||
|
// So in this case if the maker vault go to the unsafe area
|
||||||
|
// the refinancing task will be executed and the position
|
||||||
|
// will be split on two position on maker and compound.
|
||||||
|
// It will be done through a algorithm that will optimize the
|
||||||
|
// total borrow rate.
|
||||||
|
|
||||||
|
const conditionMakerVaultUnsafeObj = new GelatoCoreLib.Condition({
|
||||||
|
inst: contracts.conditionMakerVaultUnsafe.address,
|
||||||
|
data: await contracts.conditionMakerVaultUnsafe.getConditionData(
|
||||||
|
vaultAId,
|
||||||
|
contracts.priceOracleResolver.address,
|
||||||
|
await hre.run("abi-encode-withselector", {
|
||||||
|
abi: (await deployments.getArtifact("PriceOracleResolver")).abi,
|
||||||
|
functionname: "getMockPrice",
|
||||||
|
inputs: [wallets.userAddress],
|
||||||
|
}),
|
||||||
|
constants.MIN_COL_RATIO_MAKER
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const conditionDebtBridgeIsAffordableObj = new GelatoCoreLib.Condition({
|
||||||
|
inst: contracts.conditionDebtBridgeIsAffordable.address,
|
||||||
|
data: await contracts.conditionDebtBridgeIsAffordable.getConditionData(
|
||||||
|
vaultAId,
|
||||||
|
constants.MAX_FEES_IN_PERCENT
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const conditionDestVaultWillBeSafe = new GelatoCoreLib.Condition({
|
||||||
|
inst: contracts.conditionDestVaultWillBeSafe.address,
|
||||||
|
data: await contracts.conditionDestVaultWillBeSafe.getConditionData(
|
||||||
|
vaultAId,
|
||||||
|
vaultBId,
|
||||||
|
"ETH-B"
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
// ======= GELATO TASK SETUP ======
|
||||||
|
const refinanceFromEthAToBIfVaultUnsafe = new GelatoCoreLib.Task({
|
||||||
|
conditions: [
|
||||||
|
conditionMakerVaultUnsafeObj,
|
||||||
|
conditionDebtBridgeIsAffordableObj,
|
||||||
|
conditionDestVaultWillBeSafe,
|
||||||
|
],
|
||||||
|
actions: gelatoDebtBridgeSpells,
|
||||||
|
});
|
||||||
|
|
||||||
|
const gelatoExternalProvider = new GelatoCoreLib.GelatoProvider({
|
||||||
|
addr: wallets.gelatoProviderAddress, // Gelato Provider Address
|
||||||
|
module: contracts.dsaProviderModule.address, // Gelato DSA module
|
||||||
|
});
|
||||||
|
|
||||||
|
const expiryDate = 0;
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
contracts.dsa.cast(
|
||||||
|
[contracts.connectGelato.address], // targets
|
||||||
|
[
|
||||||
|
await hre.run("abi-encode-withselector", {
|
||||||
|
abi: ABI.ConnectGelatoABI,
|
||||||
|
functionname: "submitTask",
|
||||||
|
inputs: [
|
||||||
|
gelatoExternalProvider,
|
||||||
|
refinanceFromEthAToBIfVaultUnsafe,
|
||||||
|
expiryDate,
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
], // datas
|
||||||
|
wallets.userAddress, // origin
|
||||||
|
{
|
||||||
|
gasLimit: 5000000,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).to.emit(contracts.gelatoCore, "LogTaskSubmitted");
|
||||||
|
|
||||||
|
taskReceipt = new GelatoCoreLib.TaskReceipt({
|
||||||
|
id: await contracts.gelatoCore.currentTaskReceiptId(),
|
||||||
|
userProxy: contracts.dsa.address,
|
||||||
|
provider: gelatoExternalProvider,
|
||||||
|
tasks: [refinanceFromEthAToBIfVaultUnsafe],
|
||||||
|
expiryDate,
|
||||||
|
});
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Closing of the vault B
|
||||||
|
|
||||||
|
await contracts.dsa.cast(
|
||||||
|
[hre.network.config.ConnectMaker],
|
||||||
|
[
|
||||||
|
await hre.run("abi-encode-withselector", {
|
||||||
|
abi: ABI.ConnectMakerABI,
|
||||||
|
functionname: "close",
|
||||||
|
inputs: [vaultBId],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
wallets.userAddress, // origin
|
||||||
|
{
|
||||||
|
gasLimit: 5000000,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
//#endregion Closing of the vault B
|
||||||
|
});
|
||||||
|
|
||||||
|
// This test showcases the part which is automatically done by the Gelato Executor Network on mainnet
|
||||||
|
// Bots constatly check whether the submitted task is executable (by calling canExec)
|
||||||
|
// If the task becomes executable (returns "OK"), the "exec" function will be called
|
||||||
|
// which will execute the debt refinancing on behalf of the user
|
||||||
|
it("#3: Auto-refinance from ETH-A to ETH-B, if the Maker vault became unsafe.", async function () {
|
||||||
|
// Steps
|
||||||
|
// Step 1: Market Move against the user (Mock)
|
||||||
|
// Step 2: Executor execute the user's task
|
||||||
|
|
||||||
|
//#region Step 1 Market Move against the user (Mock)
|
||||||
|
|
||||||
|
// Ether market price went from the current price to 250$
|
||||||
|
|
||||||
|
const gelatoGasPrice = await hre.run("fetchGelatoGasPrice");
|
||||||
|
expect(gelatoGasPrice).to.be.lte(constants.GAS_PRICE_CEIL);
|
||||||
|
|
||||||
|
// TO DO: base mock price off of real price data
|
||||||
|
await contracts.priceOracleResolver.setMockPrice(
|
||||||
|
ethers.utils.parseUnits("400", 18)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await contracts.gelatoCore
|
||||||
|
.connect(wallets.gelatoExecutorWallet)
|
||||||
|
.canExec(taskReceipt, constants.GAS_LIMIT, gelatoGasPrice)
|
||||||
|
).to.be.equal("ConditionNotOk:MakerVaultNotUnsafe");
|
||||||
|
|
||||||
|
// TO DO: base mock price off of real price data
|
||||||
|
await contracts.priceOracleResolver.setMockPrice(
|
||||||
|
ethers.utils.parseUnits("250", 18)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await contracts.gelatoCore
|
||||||
|
.connect(wallets.gelatoExecutorWallet)
|
||||||
|
.canExec(taskReceipt, constants.GAS_LIMIT, gelatoGasPrice)
|
||||||
|
).to.be.equal("OK");
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 2 Executor execute the user's task
|
||||||
|
|
||||||
|
// The market move make the vault unsafe, so the executor
|
||||||
|
// will execute the user's task to make the user position safe
|
||||||
|
// by a debt refinancing in compound.
|
||||||
|
|
||||||
|
//#region EXPECTED OUTCOME
|
||||||
|
let debtOnMakerBefore = await contracts.makerResolver.getMakerVaultRawDebt(
|
||||||
|
vaultAId
|
||||||
|
);
|
||||||
|
|
||||||
|
const route = await getInstaPoolV2Route(
|
||||||
|
contracts.DAI.address,
|
||||||
|
debtOnMakerBefore,
|
||||||
|
contracts.instaPoolResolver
|
||||||
|
);
|
||||||
|
|
||||||
|
if (route !== 1) {
|
||||||
|
debtOnMakerBefore = await contracts.makerResolver.getMakerVaultDebt(
|
||||||
|
vaultAId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gasCost = await getGasCostForFullRefinance(route);
|
||||||
|
|
||||||
|
const gasFeesPaidFromCol = ethers.BigNumber.from(gasCost).mul(
|
||||||
|
gelatoGasPrice
|
||||||
|
);
|
||||||
|
|
||||||
|
const pricedCollateral = (
|
||||||
|
await contracts.makerResolver.getMakerVaultCollateralBalance(vaultAId)
|
||||||
|
).sub(gasFeesPaidFromCol);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
const providerBalanceBeforeExecution = await contracts.gelatoCore.providerFunds(
|
||||||
|
wallets.gelatoProviderAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
contracts.gelatoCore
|
||||||
|
.connect(wallets.gelatoExecutorWallet)
|
||||||
|
.exec(taskReceipt, {
|
||||||
|
gasPrice: gelatoGasPrice, // Exectutor must use gelatoGasPrice (Chainlink fast gwei)
|
||||||
|
gasLimit: constants.GAS_LIMIT,
|
||||||
|
})
|
||||||
|
).to.emit(contracts.gelatoCore, "LogExecSuccess");
|
||||||
|
|
||||||
|
// 🚧 For Debugging:
|
||||||
|
// const txResponse2 = await contracts.gelatoCore
|
||||||
|
// .connect(wallets.gelatoExecutorWallet)
|
||||||
|
// .exec(taskReceipt, {
|
||||||
|
// gasPrice: gelatoGasPrice,
|
||||||
|
// gasLimit: constants.GAS_LIMIT,
|
||||||
|
// });
|
||||||
|
// const {blockHash} = await txResponse2.wait();
|
||||||
|
// const logs = await ethers.provider.getLogs({blockHash});
|
||||||
|
// const iFace = new ethers.utils.Interface(GelatoCoreLib.GelatoCore.abi);
|
||||||
|
// for (const log of logs) {
|
||||||
|
// console.log(iFace.parseLog(log).args.reason);
|
||||||
|
// }
|
||||||
|
// await GelatoCoreLib.sleep(10000);
|
||||||
|
|
||||||
|
const cdps = await contracts.getCdps.getCdpsAsc(
|
||||||
|
contracts.dssCdpManager.address,
|
||||||
|
contracts.dsa.address
|
||||||
|
);
|
||||||
|
const oldVaultBId = vaultBId;
|
||||||
|
vaultBId = String(cdps.ids[1]);
|
||||||
|
expect(cdps.ids[1].isZero()).to.be.false;
|
||||||
|
|
||||||
|
expect(oldVaultBId).to.be.not.equal(vaultBId);
|
||||||
|
|
||||||
|
let debtOnMakerVaultB;
|
||||||
|
if (route === 1) {
|
||||||
|
debtOnMakerVaultB = await contracts.makerResolver.getMakerVaultRawDebt(
|
||||||
|
vaultBId
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
debtOnMakerVaultB = await contracts.makerResolver.getMakerVaultDebt(
|
||||||
|
vaultBId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pricedCollateralOnVaultB = await contracts.makerResolver.getMakerVaultCollateralBalance(
|
||||||
|
vaultBId
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await contracts.gelatoCore.providerFunds(wallets.gelatoProviderAddress)
|
||||||
|
).to.be.gt(
|
||||||
|
providerBalanceBeforeExecution.sub(
|
||||||
|
gasFeesPaidFromCol
|
||||||
|
.mul(await contracts.gelatoCore.totalSuccessShare())
|
||||||
|
.div(100)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Estimated amount to borrowed token should be equal to the actual one read on compound contracts
|
||||||
|
if (route === 1) {
|
||||||
|
expect(debtOnMakerBefore).to.be.lte(debtOnMakerVaultB);
|
||||||
|
} else {
|
||||||
|
expect(debtOnMakerBefore).to.be.equal(debtOnMakerVaultB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Estimated amount of collateral should be equal to the actual one read on compound contracts
|
||||||
|
expect(pricedCollateral).to.be.equal(pricedCollateralOnVaultB);
|
||||||
|
|
||||||
|
const collateralOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultCollateralBalance(
|
||||||
|
vaultAId
|
||||||
|
); // in Ether.
|
||||||
|
const debtOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultRawDebt(
|
||||||
|
vaultAId
|
||||||
|
);
|
||||||
|
|
||||||
|
// We should not have deposited ether or borrowed DAI on maker.
|
||||||
|
expect(collateralOnMakerOnVaultAAfter).to.be.equal(ethers.constants.Zero);
|
||||||
|
expect(debtOnMakerOnVaultAAfter).to.be.equal(ethers.constants.Zero);
|
||||||
|
|
||||||
|
// DSA has maximum 2 wei DAI in it due to maths inaccuracies
|
||||||
|
expect(await contracts.DAI.balanceOf(contracts.dsa.address)).to.be.equal(
|
||||||
|
constants.MAKER_INITIAL_DEBT
|
||||||
|
);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
});
|
||||||
|
});
|
|
@ -14,6 +14,7 @@ module.exports = async function () {
|
||||||
const wallets = await getWallets();
|
const wallets = await getWallets();
|
||||||
const contracts = await getContracts();
|
const contracts = await getContracts();
|
||||||
const constants = await getDebtBridgeFromMakerConstants();
|
const constants = await getDebtBridgeFromMakerConstants();
|
||||||
|
const ABI = getABI();
|
||||||
|
|
||||||
// Gelato Testing environment setup.
|
// Gelato Testing environment setup.
|
||||||
await stakeExecutor(wallets.gelatoExecutorWallet, contracts.gelatoCore);
|
await stakeExecutor(wallets.gelatoExecutorWallet, contracts.gelatoCore);
|
||||||
|
@ -45,7 +46,8 @@ module.exports = async function () {
|
||||||
contracts.getCdps,
|
contracts.getCdps,
|
||||||
contracts.dssCdpManager,
|
contracts.dssCdpManager,
|
||||||
constants.MAKER_INITIAL_ETH,
|
constants.MAKER_INITIAL_ETH,
|
||||||
constants.MAKER_INITIAL_DEBT
|
constants.MAKER_INITIAL_DEBT,
|
||||||
|
ABI.ConnectMakerABI
|
||||||
);
|
);
|
||||||
|
|
||||||
const spells = await getSpellsToCompound(
|
const spells = await getSpellsToCompound(
|
||||||
|
@ -55,8 +57,6 @@ module.exports = async function () {
|
||||||
vaultId
|
vaultId
|
||||||
);
|
);
|
||||||
|
|
||||||
const ABI = getABI();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
wallets,
|
wallets,
|
||||||
contracts,
|
contracts,
|
||||||
|
|
|
@ -15,6 +15,7 @@ module.exports = async function () {
|
||||||
const wallets = await getWallets();
|
const wallets = await getWallets();
|
||||||
const contracts = await getContracts();
|
const contracts = await getContracts();
|
||||||
const constants = await getDebtBridgeFromMakerConstants();
|
const constants = await getDebtBridgeFromMakerConstants();
|
||||||
|
const ABI = getABI();
|
||||||
|
|
||||||
// Gelato Testing environment setup.
|
// Gelato Testing environment setup.
|
||||||
await stakeExecutor(wallets.gelatoExecutorWallet, contracts.gelatoCore);
|
await stakeExecutor(wallets.gelatoExecutorWallet, contracts.gelatoCore);
|
||||||
|
@ -46,7 +47,8 @@ module.exports = async function () {
|
||||||
contracts.getCdps,
|
contracts.getCdps,
|
||||||
contracts.dssCdpManager,
|
contracts.dssCdpManager,
|
||||||
constants.MAKER_INITIAL_ETH,
|
constants.MAKER_INITIAL_ETH,
|
||||||
constants.MAKER_INITIAL_DEBT
|
constants.MAKER_INITIAL_DEBT,
|
||||||
|
ABI.ConnectMakerABI
|
||||||
);
|
);
|
||||||
const vaultBId = await createVaultForETHB(
|
const vaultBId = await createVaultForETHB(
|
||||||
wallets.userAddress,
|
wallets.userAddress,
|
||||||
|
@ -63,8 +65,6 @@ module.exports = async function () {
|
||||||
vaultBId
|
vaultBId
|
||||||
);
|
);
|
||||||
|
|
||||||
const ABI = getABI();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
wallets,
|
wallets,
|
||||||
contracts,
|
contracts,
|
||||||
|
|
|
@ -14,6 +14,7 @@ module.exports = async function () {
|
||||||
const wallets = await getWallets();
|
const wallets = await getWallets();
|
||||||
const contracts = await getContracts();
|
const contracts = await getContracts();
|
||||||
const constants = await getDebtBridgeFromMakerConstants();
|
const constants = await getDebtBridgeFromMakerConstants();
|
||||||
|
const ABI = getABI();
|
||||||
|
|
||||||
// Gelato Testing environment setup.
|
// Gelato Testing environment setup.
|
||||||
await stakeExecutor(wallets.gelatoExecutorWallet, contracts.gelatoCore);
|
await stakeExecutor(wallets.gelatoExecutorWallet, contracts.gelatoCore);
|
||||||
|
@ -45,7 +46,8 @@ module.exports = async function () {
|
||||||
contracts.getCdps,
|
contracts.getCdps,
|
||||||
contracts.dssCdpManager,
|
contracts.dssCdpManager,
|
||||||
constants.MAKER_INITIAL_ETH,
|
constants.MAKER_INITIAL_ETH,
|
||||||
constants.MAKER_INITIAL_DEBT
|
constants.MAKER_INITIAL_DEBT,
|
||||||
|
ABI.ConnectMakerABI
|
||||||
);
|
);
|
||||||
|
|
||||||
const spells = await getSpellsEthAEthBWithVaultCreation(
|
const spells = await getSpellsEthAEthBWithVaultCreation(
|
||||||
|
@ -55,8 +57,6 @@ module.exports = async function () {
|
||||||
vaultAId
|
vaultAId
|
||||||
);
|
);
|
||||||
|
|
||||||
const ABI = getABI();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
wallets,
|
wallets,
|
||||||
contracts,
|
contracts,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user