Testing cleaning refactoring

This commit is contained in:
Shivva 2020-11-11 12:55:36 +01:00 committed by Luis Schliesske
parent 2944a4e56e
commit 5f7cc1c79a
10 changed files with 261 additions and 33 deletions

View File

@ -15,4 +15,4 @@ address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
// Insta Pool
address constant INSTA_POOL_RESOLVER = 0xa004a5afBa04b74037E9E52bA1f7eb02b5E61509;
uint256 constant ROUTE_1_3_TOLERANCE = 1005e15;
uint256 constant ROUTE_1_TOLERANCE = 1005e15;

View File

@ -3,7 +3,7 @@ pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
import {GelatoBytes} from "../../lib/GelatoBytes.sol";
import {sub, wmul} from "../../vendor/DSMath.sol";
import {sub} from "../../vendor/DSMath.sol";
import {
AccountInterface,
ConnectorInterface

View File

@ -3,7 +3,11 @@ pragma solidity 0.7.4;
import {
_wCalcCollateralToWithdraw,
_wCalcDebtToRepay
_wCalcDebtToRepay,
_getFlashLoanRoute,
_getGasCostMakerToMaker,
_getGasCostMakerToCompound,
_getRealisedDebt
} from "../../functions/gelato/FGelatoDebtBridge.sol";
contract FGelatoDebtBridgeMock {
@ -38,4 +42,36 @@ contract FGelatoDebtBridgeMock {
_wDaiDebtOnMaker
);
}
function getFlashLoanRoute(address _tokenA, uint256 _wTokenADebtToMove)
public
view
returns (uint256)
{
return _getFlashLoanRoute(_tokenA, _wTokenADebtToMove);
}
function getGasCostMakerToMaker(bool _newVault, uint256 _route)
public
pure
returns (uint256)
{
return _getGasCostMakerToMaker(_newVault, _route);
}
function getGasCostMakerToCompound(uint256 _route)
public
pure
returns (uint256)
{
return _getGasCostMakerToCompound(_route);
}
function getRealisedDebt(uint256 _debtToMove)
public
pure
returns (uint256)
{
return _getRealisedDebt(_debtToMove);
}
}

View File

@ -2,14 +2,14 @@
pragma solidity 0.7.4;
import {
_getMakerVaultDebt,
_getMakerRawVaultDebt,
_getMakerVaultCollateralBalance
} from "../../functions/dapps/FMaker.sol";
contract MakerResolver {
/// @dev Return Debt in wad of the vault associated to the vaultId.
function getMakerVaultDebt(uint256 _vaultId) public view returns (uint256) {
return _getMakerVaultDebt(_vaultId);
return _getMakerRawVaultDebt(_vaultId);
}
/// @dev Return Collateral in wad of the vault associated to the vaultId.

View File

@ -21,6 +21,20 @@ function _getMakerVaultDebt(uint256 _vaultId) view returns (uint256 wad) {
wad = mul(wad, RAY) < rad ? wad + 1 : wad;
}
function _getMakerRawVaultDebt(uint256 _vaultId) view returns (uint256 tab) {
IMcdManager manager = IMcdManager(MCD_MANAGER);
(bytes32 ilk, address urn) = _getVaultData(manager, _vaultId);
IVat vat = IVat(manager.vat());
(, uint256 rate, , , ) = vat.ilks(ilk);
(, uint256 art) = vat.urns(ilk, urn);
uint256 rad = mul(art, rate);
tab = rad / RAY;
tab = mul(tab, RAY) < rad ? tab + 1 : tab;
}
function _getMakerVaultCollateralBalance(uint256 _vaultId)
view
returns (uint256)

View File

@ -5,7 +5,7 @@ pragma experimental ABIEncoderV2;
import {add, sub, wmul, wdiv} from "../../vendor/DSMath.sol";
import {
INSTA_POOL_RESOLVER,
ROUTE_1_3_TOLERANCE
ROUTE_1_TOLERANCE
} from "../../constants/CInstaDapp.sol";
import {GAS_COSTS_FOR_FULL_REFINANCE} from "../../constants/CDebtBridge.sol";
import {
@ -77,6 +77,7 @@ function _getGasCostMakerToMaker(bool _newVault, uint256 _route)
pure
returns (uint256)
{
_checkRouteIndex(_route);
return
_newVault
? add(GAS_COSTS_FOR_FULL_REFINANCE()[_route], 0)
@ -84,9 +85,17 @@ function _getGasCostMakerToMaker(bool _newVault, uint256 _route)
}
function _getGasCostMakerToCompound(uint256 _route) pure returns (uint256) {
_checkRouteIndex(_route);
return GAS_COSTS_FOR_FULL_REFINANCE()[_route];
}
function _getRealisedDebt(uint256 _debtToMove) pure returns (uint256) {
return wmul(_debtToMove, ROUTE_1_3_TOLERANCE);
return wmul(_debtToMove, ROUTE_1_TOLERANCE);
}
function _checkRouteIndex(uint256 _route) pure {
require(
_route <= 4,
"FGelatoDebtBridge._getGasCostMakerToMaker: invalid route index"
);
}

View File

@ -274,15 +274,9 @@ describe("Full Debt Bridge refinancing loan from Maker to Compound", function ()
compoundPosition[0].borrowBalanceStoredUser
);
} else {
expect(debtOnMakerBefore).to.be.equal(
compoundPosition[0].borrowBalanceStoredUser
);
// We should not have borrowed DAI on maker
const debtOnMakerAfter = await contracts.makerResolver.getMakerVaultDebt(
vaultId
);
expect(debtOnMakerAfter).to.be.equal(ethers.constants.Zero);
expect(
debtOnMakerBefore.sub(compoundPosition[0].borrowBalanceStoredUser)
).to.be.lt(ethers.utils.parseUnits("2", 0));
}
// Estimated amount of collateral should be equal to the actual one read on compound contracts
@ -292,12 +286,16 @@ describe("Full Debt Bridge refinancing loan from Maker to Compound", function ()
)
).to.be.lt(ethers.utils.parseUnits("1", 12));
const collateralOnMakerAfter = await contracts.makerResolver.getMakerVaultCollateralBalance(
const collateralOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultCollateralBalance(
vaultId
); // in Ether.
const debtOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultDebt(
vaultId
);
// We should not have deposited ether on it.
expect(collateralOnMakerAfter).to.be.equal(ethers.constants.Zero);
// 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 contain 1000 DAI
expect(await contracts.DAI.balanceOf(contracts.dsa.address)).to.be.equal(

View File

@ -275,12 +275,6 @@ describe("Full Debt Bridge refinancing loan from ETH-A to ETH-B with vault creat
expect(debtOnMakerBefore).to.be.lte(debtOnMakerVaultB);
} else {
expect(debtOnMakerBefore).to.be.equal(debtOnMakerVaultB);
// We should not have borrowed DAI on maker
const debtOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultDebt(
vaultAId
);
expect(debtOnMakerOnVaultAAfter).to.be.equal(ethers.constants.Zero);
}
// Estimated amount of collateral should be equal to the actual one read on compound contracts
@ -289,9 +283,13 @@ describe("Full Debt Bridge refinancing loan from ETH-A to ETH-B with vault creat
const collateralOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultCollateralBalance(
vaultAId
); // in Ether.
const debtOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultDebt(
vaultAId
);
// We should not have deposited ether on it.
// 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(

View File

@ -275,12 +275,6 @@ describe("Full Debt Bridge refinancing loan from ETH-A to ETH-B", function () {
expect(debtOnMakerBefore).to.be.lte(debtOnMakerVaultB);
} else {
expect(debtOnMakerBefore).to.be.equal(debtOnMakerVaultB);
// We should not have borrowed DAI on maker
const debtOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultDebt(
vaultAId
);
expect(debtOnMakerOnVaultAAfter).to.be.equal(ethers.constants.Zero);
}
// Estimated amount of collateral should be equal to the actual one read on compound contracts
@ -289,9 +283,13 @@ describe("Full Debt Bridge refinancing loan from ETH-A to ETH-B", function () {
const collateralOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultCollateralBalance(
vaultAId
); // in Ether.
const debtOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultDebt(
vaultAId
);
// We should not have deposited ether on it.
// 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(

View File

@ -0,0 +1,175 @@
const {expect} = require("chai");
const hre = require("hardhat");
const {deployments, ethers} = hre;
const InstaPoolResolver = require("../../artifacts/contracts/interfaces/InstaDapp/resolvers/IInstaPoolResolver.sol/IInstaPoolResolver.json");
const DAI = hre.network.config.DAI;
describe("Debt Partial Refinance Math Unit Test", 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 fGelatoDebtBridgeMock;
let instaPoolResolver;
beforeEach(async function () {
await deployments.fixture();
instaPoolResolver = await ethers.getContractAt(
InstaPoolResolver.abi,
hre.network.config.InstaPoolResolver
);
fGelatoDebtBridgeMock = await ethers.getContract("FGelatoDebtBridgeMock");
});
it("getFlashLoanRoute should return 0 when dydx has enough liquidity", async function () {
// const rData = instaPoolResolver.getTokenLimit(DAI);
const daiAmtToBorrow = ethers.utils.parseUnits("1000", 18);
expect(
await fGelatoDebtBridgeMock.getFlashLoanRoute(DAI, daiAmtToBorrow)
).to.be.equal(0);
});
it("getFlashLoanRoute should return 1 when maker has enough liquidity and cheaper protocol didn't have enough liquidity", async function () {
const rData = await instaPoolResolver.getTokenLimit(DAI);
const daiAmtToBorrow = ethers.utils.parseUnits("1000", 18).add(rData.dydx);
expect(
await fGelatoDebtBridgeMock.getFlashLoanRoute(DAI, daiAmtToBorrow)
).to.be.equal(1);
});
it("getFlashLoanRoute should return 2 when compound has enough liquidity and cheaper protocol didn't have enough liquidity", async function () {
const rData = await instaPoolResolver.getTokenLimit(DAI);
const daiAmtToBorrow = ethers.utils.parseUnits("1000", 18).add(rData.maker);
expect(
await fGelatoDebtBridgeMock.getFlashLoanRoute(DAI, daiAmtToBorrow)
).to.be.equal(2);
});
// Seems aave has less liquidity than compound, is it always the case? If yes, why we should use this protocol.
// it("getFlashLoanRoute should return 3 when aave has enough liquidity and cheaper protocol didn't have enough liquidity", async function () {
// const rData = await instaPoolResolver.getTokenLimit(DAI);
// console.log(String(rData.dydx));
// console.log(String(rData.maker));
// console.log(String(rData.compound));
// console.log(String(rData.aave));
// const daiAmtToBorrow = ethers.utils.parseUnits("1000", 18).add(rData.compound);
// expect(await fGelatoDebtBridgeMock.getFlashLoanRoute(DAI, daiAmtToBorrow)).to.be.equal(3);
// })
it("getFlashLoanRoute should revert with FGelatoDebtBridge._getFlashLoanRoute: illiquid", async function () {
const rData = await instaPoolResolver.getTokenLimit(DAI);
const daiAmtToBorrow = ethers.utils
.parseUnits("1000", 18)
.add(rData.compound);
await expect(
fGelatoDebtBridgeMock.getFlashLoanRoute(DAI, daiAmtToBorrow)
).to.be.revertedWith("FGelatoDebtBridge._getFlashLoanRoute: illiquid");
});
it("getGasCostMakerToMaker should return 2519000 gas limit for route 0 (Dydx) and new vault", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToMaker(true, 0)
).to.be.equal(2519000);
});
it("getGasCostMakerToMaker should return 2519000 gas limit for route 0 (Dydx)", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToMaker(false, 0)
).to.be.equal(2519000);
});
it("getGasCostMakerToMaker should return 3140500 gas limit for route 1 (maker) and new vault", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToMaker(true, 1)
).to.be.equal(3140500);
});
it("getGasCostMakerToMaker should return 3140500 gas limit for route 1 (maker)", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToMaker(false, 1)
).to.be.equal(3140500);
});
it("getGasCostMakerToMaker should return 3971000 gas limit for route 2 (compound) and new vault", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToMaker(true, 2)
).to.be.equal(3971000);
});
it("getGasCostMakerToMaker should return 3971000 gas limit for route 2 (compound)", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToMaker(false, 2)
).to.be.equal(3971000);
});
it("getGasCostMakerToMaker should return 4345000 gas limit for route 3 (aave) and new vault", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToMaker(true, 3)
).to.be.equal(4345000);
});
it("getGasCostMakerToMaker should return 4345000 gas limit for route 3 (aave)", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToMaker(false, 3)
).to.be.equal(4345000);
});
it("getGasCostMakerToMaker should revert with invalid route index when the inputed route exceed 4", async function () {
await expect(
fGelatoDebtBridgeMock.getGasCostMakerToMaker(true, 5)
).to.be.revertedWith(
"FGelatoDebtBridge._getGasCostMakerToMaker: invalid route index"
);
});
it("getGasCostMakerToCompound should return 2519000 gas limit for route 0 (Dydx)", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToCompound(0)
).to.be.equal(2519000);
});
it("getGasCostMakerToCompound should return 3140500 gas limit for route 1 (Maker)", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToCompound(1)
).to.be.equal(3140500);
});
it("getGasCostMakerToCompound should return 3971000 gas limit for route 2 (Compound)", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToCompound(2)
).to.be.equal(3971000);
});
it("getGasCostMakerToCompound should return 4345000 gas limit for route 3 (Aave)", async function () {
expect(
await fGelatoDebtBridgeMock.getGasCostMakerToCompound(3)
).to.be.equal(4345000);
});
it("getGasCostMakerToCompound should revert with invalid route index when the inputed route exceed 4", async function () {
await expect(
fGelatoDebtBridgeMock.getGasCostMakerToCompound(5)
).to.be.revertedWith(
"FGelatoDebtBridge._getGasCostMakerToMaker: invalid route index"
);
});
it("getRealisedDebt should increase the inputed uint by 0,5%", async function () {
const debtToMove = ethers.utils.parseUnits("1000", 18);
const expectedRealisedDebt = ethers.utils.parseUnits("1005", 18);
expect(await fGelatoDebtBridgeMock.getRealisedDebt(debtToMove)).to.be.equal(
expectedRealisedDebt
);
});
});