Fix condition and gas oracle bugs

This commit is contained in:
Shivva 2020-11-26 15:31:14 +01:00 committed by Luis Schliesske
parent 673dada3bb
commit fade13c960
3 changed files with 334 additions and 62 deletions

View File

@ -11,11 +11,15 @@ import {
_vaultWillBeSafe,
_newVaultWillBeSafe
} from "../../../functions/dapps/FMaker.sol";
import {DAI} from "../../../constants/CInstaDapp.sol";
import {
_getFlashLoanRoute,
_getGasCostMakerToMaker,
_getRealisedDebt
} from "../../../functions/gelato/FGelatoDebtBridge.sol";
import {_getGelatoProviderFees} from "../../../functions/gelato/FGelato.sol";
import {GelatoBytes} from "../../../lib/GelatoBytes.sol";
import {sub} from "../../../vendor/DSMath.sol";
contract ConditionDestVaultWillBeSafe is GelatoConditionsStandard {
using GelatoBytes for bytes;
@ -55,7 +59,14 @@ contract ConditionDestVaultWillBeSafe is GelatoConditionsStandard {
) public view returns (string memory) {
uint256 wDaiToBorrow =
_getRealisedDebt(_getMakerVaultDebt(_fromVaultId));
uint256 wColToDeposit = _getMakerVaultCollateralBalance(_fromVaultId);
uint256 route = _getFlashLoanRoute(DAI, wDaiToBorrow);
uint256 gasCost = _getGasCostMakerToMaker(_destVaultId == 0, route);
uint256 gasFeesPaidFromCol = _getGelatoProviderFees(gasCost);
uint256 wColToDeposit =
sub(
_getMakerVaultCollateralBalance(_fromVaultId),
gasFeesPaidFromCol
);
return
destVaultWillBeSafeExplicit(

View File

@ -5,7 +5,9 @@ import {GELATO_GAS_PRICE_ORACLE} from "../../constants/CGelato.sol";
import {mul} from "../../vendor/DSMath.sol";
function _getGelatoGasPrice() view returns (uint256) {
return uint256(GELATO_GAS_PRICE_ORACLE.latestAnswer());
int256 oracleGasPrice = GELATO_GAS_PRICE_ORACLE.latestAnswer();
if (oracleGasPrice <= 0) revert("_getGelatoGasPrice:0orBelow");
return uint256(oracleGasPrice);
}
function _getGelatoProviderFees(uint256 _gas) view returns (uint256) {

View File

@ -35,8 +35,11 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
let conditionDestVaultWillBeSafe;
let dsa;
let cdpId;
let ilk;
let cdpAId;
let cdpBId;
let ilkA;
let ilkB;
let ethAIlk;
let ethBIlk;
let amountToBorrow;
@ -94,8 +97,8 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
await instaList.accountAddr(dsaID)
);
// Create/Deposit/Borrow a Vault
const openVault = await hre.run("abi-encode-withselector", {
// Create/Deposit/Borrow a Vault for ETH-A
let openVault = await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "open",
inputs: ["ETH-A"],
@ -104,48 +107,82 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
await dsa.cast([hre.network.config.ConnectMaker], [openVault], userAddress);
let cdps = await getCdps.getCdpsAsc(dssCdpManager.address, dsa.address);
cdpId = String(cdps.ids[0]);
cdpAId = String(cdps.ids[0]);
expect(cdps.ids[0].isZero()).to.be.false;
// Create/Deposit/Borrow a Vault for ETH-B
openVault = await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "open",
inputs: ["ETH-B"],
});
await dsa.cast([hre.network.config.ConnectMaker], [openVault], userAddress);
cdps = await getCdps.getCdpsAsc(dssCdpManager.address, dsa.address);
cdpBId = String(cdps.ids[1]);
expect(cdps.ids[1].isZero()).to.be.false;
ethAIlk = ethers.utils.formatBytes32String("ETH-A");
ilkA = await vat.ilks(ethAIlk);
ethBIlk = ethers.utils.formatBytes32String("ETH-B");
ilkB = await vat.ilks(ethBIlk);
amountToBorrow = ethers.utils.parseUnits("100", 18);
});
it("#1: ok should return Ok when the gas fees didn't exceed a user define amount with vault creation", async function () {
// Steps :
// 1 - Deposit
// 2 - Borrow
// 3 - Test if vault ETH-B will be safe after debt bridge action
const amountToDeposit = amountToBorrow
.mul(ethers.utils.parseUnits("1", 27))
.div(ilkA[2]) // ilk[2] represent the liquidation ratio of ilk
.add(ethers.utils.parseUnits("4", 17)); // to be just above the liquidation ratio.
//#region Deposit
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "deposit",
inputs: [cdpId, ethers.utils.parseEther("10"), 0, 0],
inputs: [cdpAId, amountToDeposit, 0, 0],
}),
],
userAddress,
{
value: ethers.utils.parseEther("10"),
value: amountToDeposit,
}
);
//#endregion Deposit
//#region Borrow
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "borrow",
inputs: [cdpId, ethers.utils.parseUnits("1000", 18), 0, 0],
inputs: [cdpAId, amountToBorrow, 0, 0],
}),
],
userAddress
);
expect(await DAI.balanceOf(dsa.address)).to.be.equal(
ethers.utils.parseEther("1000")
);
expect(await DAI.balanceOf(dsa.address)).to.be.equal(amountToBorrow);
ethBIlk = ethers.utils.formatBytes32String("ETH-B");
ilk = await vat.ilks(ethBIlk);
amountToBorrow = ethers.utils.parseUnits("100", 18);
});
//#endregion Borrow
it("#1: ok should return Ok when the gas fees didn't exceed a user define amount", async function () {
const conditionData = await conditionDestVaultWillBeSafe.getConditionData(
cdpId,
cdpAId,
0,
"ETH-B"
);
@ -154,14 +191,260 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
).to.be.equal("OK");
});
it("#2: New Vault Case : destVaultWillBeSafeExplicit should return false when col is lower than borrow amount / spot", async function () {
it("#2: ok should return DestVaultWillNotBeSafe when the gas fees exceeded a user define amount with vault creation", async function () {
// Steps :
// 1 - Deposit
// 2 - Borrow
// 3 - Test if vault ETH-B will be safe after debt bridge action
const amountToDeposit = amountToBorrow
.mul(ethers.utils.parseUnits("1", 27))
.div(ilkA[2]) // ilk[2] represent the liquidation ratio of ilk
.add(ethers.utils.parseUnits("1", 16)); // to be just below the liquidation ratio.
//#region Deposit
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "deposit",
inputs: [cdpAId, amountToDeposit, 0, 0],
}),
],
userAddress,
{
value: amountToDeposit,
}
);
//#endregion Deposit
//#region Borrow
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "borrow",
inputs: [cdpAId, amountToBorrow, 0, 0],
}),
],
userAddress
);
expect(await DAI.balanceOf(dsa.address)).to.be.equal(amountToBorrow);
//#endregion Borrow
const conditionData = await conditionDestVaultWillBeSafe.getConditionData(
cdpAId,
0,
"ETH-B"
);
expect(
await conditionDestVaultWillBeSafe.ok(0, conditionData, 0)
).to.be.equal("DestVaultWillNotBeSafe");
});
it("#3: ok should return DestVaultWillNotBeSafe when the gas fees exceeded a user define amount", async function () {
// Steps :
// 1 - Deposit
// 2 - Borrow
// 3 - Test if vault ETH-B will be safe after debt bridge action
const amountToDeposit = amountToBorrow
.mul(ethers.utils.parseUnits("1", 27))
.div(ilkA[2]) // ilk[2] represent the liquidation ratio of ilk
.add(ethers.utils.parseUnits("1", 16)); // to be just below the liquidation ratio.
//#region Deposit
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "deposit",
inputs: [cdpAId, amountToDeposit, 0, 0],
}),
],
userAddress,
{
value: amountToDeposit,
}
);
//#endregion Deposit
//#region Borrow
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "borrow",
inputs: [cdpAId, amountToBorrow, 0, 0],
}),
],
userAddress
);
expect(await DAI.balanceOf(dsa.address)).to.be.equal(amountToBorrow);
//#endregion Borrow
const conditionData = await conditionDestVaultWillBeSafe.getConditionData(
cdpAId,
cdpBId,
"ETH-B"
);
expect(
await conditionDestVaultWillBeSafe.ok(0, conditionData, 0)
).to.be.equal("DestVaultWillNotBeSafe");
});
it("#4: ok should return Ok when the gas fees didn't exceed a user define amount", async function () {
// Steps :
// 1 - Deposit
// 2 - Borrow
// 3 - Test if vault ETH-B will be safe after debt bridge action
const amountToDeposit = amountToBorrow
.mul(ethers.utils.parseUnits("1", 27))
.div(ilkA[2]) // ilk[2] represent the liquidation ratio of ilk
.add(ethers.utils.parseUnits("4", 17)); // to be just above the liquidation ratio.
//#region Deposit
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "deposit",
inputs: [cdpAId, amountToDeposit, 0, 0],
}),
],
userAddress,
{
value: amountToDeposit,
}
);
//#endregion Deposit
//#region Borrow
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "borrow",
inputs: [cdpAId, amountToBorrow, 0, 0],
}),
],
userAddress
);
expect(await DAI.balanceOf(dsa.address)).to.be.equal(amountToBorrow);
//#endregion Borrow
const conditionData = await conditionDestVaultWillBeSafe.getConditionData(
cdpAId,
cdpBId,
"ETH-B"
);
expect(
await conditionDestVaultWillBeSafe.ok(0, conditionData, 0)
).to.be.equal("OK");
});
it("#5: ok should return Ok when the gas fees didn't exceed a user define amount with deposit on vaultB", async function () {
// Steps :
// 1 - Deposit in Vault ETH-A
// 2 - Deposit in Vault ETH-B just the minimum needed to make the all position of the user safe after debt bridge
// 3 - Borrow
// 4 - Test if vault ETH-B will be safe after debt bridge action
const amountToDeposit = amountToBorrow
.mul(ethers.utils.parseUnits("1", 27))
.div(ilkA[2]) // ilk[2] represent the liquidation ratio of ilk
.add(ethers.utils.parseUnits("1", 17)); // to be just above the liquidation ratio.
//#region Deposit on Vault ETH-A
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "deposit",
inputs: [cdpAId, amountToDeposit, 0, 0],
}),
],
userAddress,
{
value: amountToDeposit,
}
);
//#endregion Deposit
//#region Deposit on Vault ETH-B
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "deposit",
inputs: [cdpBId, ethers.utils.parseUnits("3", 17), 0, 0],
}),
],
userAddress,
{
value: amountToDeposit,
}
);
//#endregion Deposit on Vault ETH-B
//#region Borrow
await dsa.cast(
[hre.network.config.ConnectMaker],
[
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "borrow",
inputs: [cdpAId, amountToBorrow, 0, 0],
}),
],
userAddress
);
expect(await DAI.balanceOf(dsa.address)).to.be.equal(amountToBorrow);
//#endregion Borrow
const conditionData = await conditionDestVaultWillBeSafe.getConditionData(
cdpAId,
cdpBId,
"ETH-B"
);
expect(
await conditionDestVaultWillBeSafe.ok(0, conditionData, 0)
).to.be.equal("OK");
});
it("#6: New Vault Case : destVaultWillBeSafeExplicit should return false when col is lower than borrow amount / spot", async function () {
let amountOfColToDepo = amountToBorrow
.mul(ilk[1])
.mul(ilkB[1]) // ilk[1] represent accumulated rates
.div(ethers.utils.parseUnits("1", 27));
amountOfColToDepo = amountOfColToDepo
.sub(amountOfColToDepo.div(ethers.utils.parseUnits("10", 0)))
.mul(ethers.utils.parseUnits("1", 27))
.div(ilk[2]);
.div(ilkB[2]); // ilk[2] represent the liquidation ratio of ilk
expect(
await conditionDestVaultWillBeSafe.destVaultWillBeSafeExplicit(
@ -173,14 +456,14 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
).to.be.false;
});
it("#3: New Vault Case : destVaultWillBeSafeExplicit should return true when col is greater than borrow amount / spot", async function () {
it("#7: New Vault Case : destVaultWillBeSafeExplicit should return true when col is greater than borrow amount / spot", async function () {
let amountOfColToDepo = amountToBorrow
.mul(ilk[1])
.mul(ilkB[1]) // ilk[1] represent accumulated rates
.div(ethers.utils.parseUnits("1", 27));
amountOfColToDepo = amountOfColToDepo
.add(amountOfColToDepo.div(ethers.utils.parseUnits("10", 0)))
.mul(ethers.utils.parseUnits("1", 27))
.div(ilk[2]);
.div(ilkB[2]); // ilk[2] represent the liquidation ratio of ilk
expect(
await conditionDestVaultWillBeSafe.destVaultWillBeSafeExplicit(
@ -192,7 +475,7 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
).to.be.true;
});
it("#4: Old Vault Case : destVaultWillBeSafeExplicit should return false when col is lower than borrow amount / spot", async function () {
it("#8: Old Vault Case : destVaultWillBeSafeExplicit should return false when col is lower than borrow amount / spot", async function () {
const openVault = await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "open",
@ -206,12 +489,12 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
);
let amountOfColToDepo = amountToBorrow
.mul(ilk[1])
.mul(ilkB[1]) // ilk[1] represent accumulated rates
.div(ethers.utils.parseUnits("1", 27));
amountOfColToDepo = amountOfColToDepo
.sub(amountOfColToDepo.div(ethers.utils.parseUnits("10", 0)))
.mul(ethers.utils.parseUnits("1", 27))
.div(ilk[2]);
.div(ilkB[2]); // ilk[2] represent the liquidation ratio of ilk
expect(
await conditionDestVaultWillBeSafe.destVaultWillBeSafeExplicit(
@ -223,30 +506,18 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
).to.be.false;
});
it("#5: Old Vault Case : destVaultWillBeSafeExplicit should return true when col is lower than borrow amount / spot", async function () {
const openVault = await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "open",
inputs: ["ETH-B"],
});
await dsa.cast([hre.network.config.ConnectMaker], [openVault], userAddress);
const cdpIdB = String(
(await getCdps.getCdpsAsc(dssCdpManager.address, dsa.address)).ids[1]
);
it("#9: Old Vault Case : destVaultWillBeSafeExplicit should return true when col is lower than borrow amount / spot", async function () {
let amountOfColToDepo = amountToBorrow
.mul(ilk[1])
.mul(ilkB[1]) // ilk[1] represent accumulated rates
.div(ethers.utils.parseUnits("1", 27));
amountOfColToDepo = amountOfColToDepo
.add(amountOfColToDepo.div(ethers.utils.parseUnits("10", 0)))
.mul(ethers.utils.parseUnits("1", 27))
.div(ilk[2]);
.div(ilkB[2]); // ilk[2] represent the liquidation ratio of ilk
expect(
await conditionDestVaultWillBeSafe.destVaultWillBeSafeExplicit(
cdpIdB,
cdpBId,
amountToBorrow,
amountOfColToDepo,
"ETH-B"
@ -254,21 +525,9 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
).to.be.true;
});
it("#6: Old Vault Case with existing deposit : destVaultWillBeSafeExplicit should return true when col is lower than borrow amount / spot due to initial deposit on Vault B", async function () {
const openVault = await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "open",
inputs: ["ETH-B"],
});
await dsa.cast([hre.network.config.ConnectMaker], [openVault], userAddress);
const cdpIdB = String(
(await getCdps.getCdpsAsc(dssCdpManager.address, dsa.address)).ids[1]
);
it("#10: Old Vault Case with existing deposit : destVaultWillBeSafeExplicit should return true when col is lower than borrow amount / spot due to initial deposit on Vault B", async function () {
let amountOfColToDepo = amountToBorrow
.mul(ilk[1])
.mul(ilkB[1]) // ilk[1] represent accumulated rates
.div(ethers.utils.parseUnits("1", 27));
const tenPercentOfAmountOfColToDepo = amountOfColToDepo.div(
ethers.utils.parseUnits("10", 0)
@ -276,7 +535,7 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
amountOfColToDepo = amountOfColToDepo
.sub(tenPercentOfAmountOfColToDepo)
.mul(ethers.utils.parseUnits("1", 27))
.div(ilk[2]);
.div(ilkB[2]); // ilk[2] represent the liquidation ratio of ilk
// Deposit For ETH-B Vault
await dsa.cast(
@ -285,7 +544,7 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
await hre.run("abi-encode-withselector", {
abi: ConnectMaker.abi,
functionname: "deposit",
inputs: [cdpIdB, tenPercentOfAmountOfColToDepo, 0, 0],
inputs: [cdpBId, tenPercentOfAmountOfColToDepo, 0, 0],
}),
],
userAddress,
@ -296,7 +555,7 @@ describe("ConditionDestVaultWillBeSafe Unit Test", function () {
expect(
await conditionDestVaultWillBeSafe.destVaultWillBeSafeExplicit(
cdpIdB,
cdpBId,
amountToBorrow,
amountOfColToDepo,
"ETH-B"