Migrating Notional v2 connector tests (#2)

* Migrating tests

* Adding more tests

* Adding more tests and helper functions

* Adding more tests

* Cleaning up
This commit is contained in:
weitianjie2000 2022-01-31 13:04:27 -08:00 committed by GitHub
parent 0a2b38bee8
commit f39fa90327
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 699 additions and 0 deletions

View File

@ -8,6 +8,7 @@ module.exports = {
basic: require("./abi/connectors/basic.json"),
auth: require("./abi/connectors/auth.json"),
"INSTAPOOL-A": require("./abi/connectors/instapool.json"),
"BASIC-A": require("./abi/connectors/basic.json")
},
basic: {
erc20: require("./abi/basics/erc20.json"),

View File

@ -0,0 +1,109 @@
const NOTIONAL_CONTRACT_ADDRESS = '0x1344A36A1B56144C3Bc62E7757377D288fDE0369';
const NOTIONAL_CONTRACT_ABI = [
{
"inputs": [
{
"internalType": "uint16",
"name": "currencyId",
"type": "uint16"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "getAccountBalance",
"outputs": [
{
"internalType": "int256",
"name": "cashBalance",
"type": "int256"
},
{
"internalType": "int256",
"name": "nTokenBalance",
"type": "int256"
},
{
"internalType": "uint256",
"name": "lastClaimTime",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "getAccountPortfolio",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "currencyId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maturity",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "assetType",
"type": "uint256"
},
{
"internalType": "int256",
"name": "notional",
"type": "int256"
},
{
"internalType": "uint256",
"name": "storageSlot",
"type": "uint256"
},
{
"internalType": "enum AssetStorageState",
"name": "storageState",
"type": "uint8"
}
],
"internalType": "struct PortfolioAsset[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
}
];
const WETH_TOKEN_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
const DAI_TOKEN_ADDRESS = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
const CDAI_TOKEN_ADDRESS = "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643";
const CETH_TOKEN_ADDRESS = "0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5";
const ERC20_TOKEN_ABI = [
"function transfer(address _to, uint256 _value) public returns (bool success)",
"function balanceOf(address account) external view returns (uint256)",
"function approve(address spender, uint256 amount) external returns (bool)",
];
module.exports = {
NOTIONAL_CONTRACT_ADDRESS,
NOTIONAL_CONTRACT_ABI,
WETH_TOKEN_ADDRESS,
DAI_TOKEN_ADDRESS,
CDAI_TOKEN_ADDRESS,
CETH_TOKEN_ADDRESS,
ERC20_TOKEN_ABI
};

View File

@ -0,0 +1,167 @@
const encodeSpells = require("../../scripts/encodeSpells.js")
const depositCollteral = async (dsa, authority, referrer, currencyId, amount, underlying) => {
const spells = [
{
connector: "NOTIONAL-TEST-A",
method: "depositCollateral",
args: [currencyId, underlying, amount, 0, 0]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
};
const depositAndMintNToken = async (dsa, authority, referrer, currencyId, amount, underlying) => {
const spells = [
{
connector: "NOTIONAL-TEST-A",
method: "depositAndMintNToken",
args: [currencyId, amount, underlying, 0, 0]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
}
const depositAndLend = async (dsa, authority, referrer, currencyId, underlying, amount, market, fcash, minRate) => {
const spells = [
{
connector: "NOTIONAL-TEST-A",
method: "depositAndLend",
args: [currencyId, amount, underlying, market, fcash, minRate, 0]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
};
const withdrawCollateral = async (dsa, authority, referrer, currencyId, amount, underlying) => {
const spells = [
{
connector: "NOTIONAL-TEST-A",
method: "withdrawCollateral",
args: [currencyId, underlying, amount, 0, 0]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
};
const redeemNTokenRaw = async (dsa, authority, referrer, currencyId, sellTokenAssets, tokensToRedeem) => {
const spells = [
{
connector: "NOTIONAL-TEST-A",
method: "redeemNTokenRaw",
args: [currencyId, sellTokenAssets, tokensToRedeem, 0, 0]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
};
const redeemNTokenAndWithdraw = async (dsa, authority, referrer, currencyId, tokensToRedeem, amountToWithdraw, redeemToUnderlying) => {
const spells = [
{
connector: "NOTIONAL-TEST-A",
method: "redeemNTokenAndWithdraw",
args: [currencyId, tokensToRedeem, amountToWithdraw, redeemToUnderlying, 0, 0]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
};
const redeemNTokenAndDeleverage = async (dsa, authority, referrer, currencyId, tokensToRedeem, marketIndex, fCashAmount, minLendRate) => {
const spells = [
{
connector: "NOTIONAL-TEST-A",
method: "redeemNTokenAndDeleverage",
args: [currencyId, tokensToRedeem, marketIndex, fCashAmount, minLendRate, 0]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
};
const depositCollateralBorrowAndWithdraw = async (
dsa,
authority,
referrer,
depositCurrencyId,
depositUnderlying,
depositAmount,
borrowCurrencyId,
marketIndex,
fCashAmount,
maxBorrowRate,
redeedmUnderlying
) => {
const spells = [
{
connector: "NOTIONAL-TEST-A",
method: "depositCollateralBorrowAndWithdraw",
args: [
depositCurrencyId,
depositUnderlying,
depositAmount,
borrowCurrencyId,
marketIndex,
fCashAmount,
maxBorrowRate,
redeedmUnderlying,
0,
0
]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
};
const withdrawLend = async (dsa, authority, referrer, currencyId, marketIndex, fCashAmount, maxBorrowRate) => {
const spells = [
{
connector: "NOTIONAL-TEST-A",
method: "withdrawLend",
args: [currencyId, marketIndex, fCashAmount, maxBorrowRate, 0]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
};
const depositERC20 = async (dsa, authority, referrer, token, amount) => {
const spells = [
{
connector: "BASIC-A",
method: "deposit",
args: [token, amount, 0, 0]
}
];
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
await tx.wait()
};
module.exports = {
depositCollteral,
depositAndMintNToken,
depositAndLend,
withdrawCollateral,
withdrawLend,
redeemNTokenRaw,
redeemNTokenAndWithdraw,
redeemNTokenAndDeleverage,
depositCollateralBorrowAndWithdraw,
depositERC20
};

View File

@ -0,0 +1,422 @@
const { expect } = require("chai");
const hre = require("hardhat");
const { web3, deployments, waffle, ethers } = hre;
const { provider, deployContract } = waffle
const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js")
const buildDSAv2 = require("../../scripts/buildDSAv2")
const encodeSpells = require("../../scripts/encodeSpells.js")
const getMasterSigner = require("../../scripts/getMasterSigner")
const addresses = require("../../scripts/constant/addresses");
const abis = require("../../scripts/constant/abis");
const constants = require("../../scripts/constant/constant");
const tokens = require("../../scripts/constant/tokens");
const contracts = require("./notional.contracts");
const helpers = require("./notional.helpers");
const connectV2NotionalArtifacts = require("../../artifacts/contracts/mainnet/connectors/notional/main.sol/ConnectV2Notional.json");
const { BigNumber } = require("ethers");
const DAI_WHALE = "0x6dfaf865a93d3b0b5cfd1b4db192d1505676645b";
const CDAI_WHALE = "0x33b890d6574172e93e58528cd99123a88c0756e9";
const ETH_WHALE = "0x7D24796f7dDB17d73e8B1d0A3bbD103FBA2cb2FE";
const CETH_WHALE = "0x1a1cd9c606727a7400bb2da6e4d5c70db5b4cade";
const MaxUint96 = BigNumber.from("0xffffffffffffffffffffffff");
const DEPOSIT_ASSET = 1;
const DEPOSIT_UNDERLYING = 2;
const DEPOSIT_ASSET_MINT_NTOKEN = 3;
const DEPOSIT_UNDERLYING_MINT_NTOKEN = 4;
const ETH_ID = 1;
const DAI_ID = 2;
const MARKET_3M = 1;
describe("Notional", function () {
const connectorName = "NOTIONAL-TEST-A"
let dsaWallet0
let masterSigner;
let instaConnectorsV2;
let connector;
let notional;
let daiToken;
let cdaiToken;
let cethToken;
let daiWhale;
let cdaiWhale;
let cethWhale;
const wallets = provider.getWallets()
const [wallet0, wallet1, wallet2, wallet3] = wallets
beforeEach(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 13798624,
},
},
],
});
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [DAI_WHALE]
})
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [CDAI_WHALE]
})
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [ETH_WHALE]
})
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [CETH_WHALE]
})
masterSigner = await getMasterSigner(wallet3)
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: connectV2NotionalArtifacts,
signer: masterSigner,
connectors: instaConnectorsV2
})
notional = new ethers.Contract(
contracts.NOTIONAL_CONTRACT_ADDRESS,
contracts.NOTIONAL_CONTRACT_ABI,
ethers.provider
);
daiToken = new ethers.Contract(
contracts.DAI_TOKEN_ADDRESS,
contracts.ERC20_TOKEN_ABI,
ethers.provider
);
daiWhale = await ethers.getSigner(DAI_WHALE);
cdaiToken = new ethers.Contract(
contracts.CDAI_TOKEN_ADDRESS,
contracts.ERC20_TOKEN_ABI,
ethers.provider
);
cdaiWhale = await ethers.getSigner(CDAI_WHALE);
cethToken = new ethers.Contract(
contracts.CETH_TOKEN_ADDRESS,
contracts.ERC20_TOKEN_ABI,
ethers.provider
);
cethWhale = await ethers.getSigner(CETH_WHALE);
weth = new ethers.Contract(
contracts.WETH_TOKEN_ADDRESS,
contracts.ERC20_TOKEN_ABI,
ethers.provider
);
dsaWallet0 = await buildDSAv2(wallet0.address)
});
describe("Deposit Tests", function () {
it("test_deposit_ETH_underlying", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
const depositAmount = ethers.utils.parseEther("1");
await helpers.depositCollteral(dsaWallet0, wallet0, wallet1, ETH_ID, depositAmount, true);
const bal = await notional.callStatic.getAccountBalance(ETH_ID, dsaWallet0.address);
// balance in internal asset precision
expect(bal[0], "expect at least 49 cETH").to.be.gte(ethers.utils.parseUnits("4900000000", 0));
expect(bal[1], "expect 0 nETH").to.be.equal(ethers.utils.parseUnits("0", 0));
});
it("test_deposit_ETH_asset", async function () {
const depositAmount = ethers.utils.parseUnits("1", 8);
await cethToken.connect(cethWhale).transfer(wallet0.address, depositAmount);
await cethToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, cethToken.address, depositAmount);
await helpers.depositCollteral(dsaWallet0, wallet0, wallet1, ETH_ID, depositAmount, false);
const bal = await notional.callStatic.getAccountBalance(ETH_ID, dsaWallet0.address);
// balance in internal asset precision
expect(bal[0], "expect at least 1 cETH").to.be.gte(ethers.utils.parseUnits("100000000", 0));
expect(bal[1], "expect 0 nETH").to.be.equal(ethers.utils.parseUnits("0", 0));
});
it("test_deposit_DAI_underlying", async function () {
const depositAmount = ethers.utils.parseUnits("1000", 18);
await daiToken.connect(daiWhale).transfer(wallet0.address, depositAmount);
await daiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, daiToken.address, depositAmount);
await helpers.depositCollteral(dsaWallet0, wallet0, wallet1, DAI_ID, depositAmount, true);
const bal = await notional.callStatic.getAccountBalance(DAI_ID, dsaWallet0.address);
// balance in internal asset precision
expect(bal[0], "expect at least 45000 cDAI").to.be.gte(ethers.utils.parseUnits("4500000000000", 0));
expect(bal[1], "expect 0 nDAI").to.be.equal(ethers.utils.parseUnits("0", 0));
});
it("test_deposit_DAI_asset", async function () {
const depositAmount = ethers.utils.parseUnits("1000", 8);
await cdaiToken.connect(cdaiWhale).transfer(wallet0.address, depositAmount);
await cdaiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, cdaiToken.address, depositAmount);
await helpers.depositCollteral(dsaWallet0, wallet0, wallet1, DAI_ID, depositAmount, false);
const bal = await notional.callStatic.getAccountBalance(DAI_ID, dsaWallet0.address);
// balance in internal asset precision
expect(bal[0], "expect at least 1000 cDAI").to.be.gte(ethers.utils.parseUnits("100000000000", 0));
expect(bal[1], "expect 0 nDAI").to.be.equal(ethers.utils.parseUnits("0", 0));
});
it("test_deposit_ETH_underlying_and_mint_ntoken", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
const depositAmount = ethers.utils.parseEther("1");
await helpers.depositAndMintNToken(dsaWallet0, wallet0, wallet1, ETH_ID, depositAmount, true);
const bal = await notional.callStatic.getAccountBalance(ETH_ID, dsaWallet0.address);
expect(bal[0], "expect 0 balance").to.be.equal(ethers.utils.parseUnits("0", 0));
expect(bal[1], "expect at least 49 nETH").to.be.gte(ethers.utils.parseUnits("4900000000", 0));
});
});
describe("Lend Tests", function () {
it("test_deposit_ETH_underlying_and_lend", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
const depositAmount = ethers.utils.parseEther("10");
await helpers.depositAndLend(dsaWallet0, wallet0, wallet1, ETH_ID, true, depositAmount, MARKET_3M, 9e8, 0);
const portfolio = await notional.getAccountPortfolio(dsaWallet0.address);
expect(portfolio.length, "expect 1 lending position").to.be.equal(1);
expect(portfolio[0][3], "expect 9 fETH").to.be.gte(ethers.utils.parseUnits("900000000", 0));
});
it("test_deposit_ETH_asset_and_lend", async function () {
const depositAmount = ethers.utils.parseUnits("1", 8);
await cethToken.connect(cethWhale).transfer(wallet0.address, depositAmount);
await cethToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, cethToken.address, depositAmount);
await helpers.depositAndLend(dsaWallet0, wallet0, wallet1, ETH_ID, false, depositAmount, MARKET_3M, 0.01e8, 0);
const portfolio = await notional.getAccountPortfolio(dsaWallet0.address);
expect(portfolio.length, "expect 1 lending position").to.be.equal(1);
expect(portfolio[0][3], "expect 0.01 fETH").to.be.gte(ethers.utils.parseUnits("1000000", 0));
});
it("test_deposit_DAI_underlying_and_lend", async function () {
const depositAmount = ethers.utils.parseUnits("1000", 18);
await daiToken.connect(daiWhale).transfer(wallet0.address, depositAmount);
await daiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, daiToken.address, depositAmount);
await helpers.depositAndLend(dsaWallet0, wallet0, wallet1, DAI_ID, true, depositAmount, MARKET_3M, 100e8, 0);
const portfolio = await notional.getAccountPortfolio(dsaWallet0.address);
expect(portfolio.length, "expect 1 lending position").to.be.equal(1);
expect(portfolio[0][3], "expect 100 fDAI").to.be.gte(ethers.utils.parseUnits("10000000000", 0));
});
it("test_deposit_DAI_asset_and_lend", async function () {
const depositAmount = ethers.utils.parseUnits("1000", 8);
await cdaiToken.connect(cdaiWhale).transfer(wallet0.address, depositAmount);
await cdaiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, cdaiToken.address, depositAmount);
await helpers.depositAndLend(dsaWallet0, wallet0, wallet1, DAI_ID, false, depositAmount, MARKET_3M, 10e8, 0);
const portfolio = await notional.getAccountPortfolio(dsaWallet0.address);
expect(portfolio.length, "expect 1 lending position").to.be.equal(1);
expect(portfolio[0][3], "expect 10 fDAI").to.be.gte(ethers.utils.parseUnits("1000000000", 0));
});
it("test_withdraw_lend_ETH", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
const depositAmount = ethers.utils.parseEther("10");
await helpers.depositAndLend(dsaWallet0, wallet0, wallet1, ETH_ID, true, depositAmount, MARKET_3M, 9e8, 0);
const before = await notional.getAccountPortfolio(dsaWallet0.address);
expect(before.length, "expect 1 lending position").to.be.equal(1);
expect(before[0][3], "expect 9 fETH").to.be.gte(ethers.utils.parseUnits("900000000", 0));
await helpers.withdrawLend(dsaWallet0, wallet0, wallet1, ETH_ID, MARKET_3M, 9e8, 0);
const after = await notional.getAccountPortfolio(dsaWallet0.address);
expect(after.length, "expect lending position to be closed out").to.be.equal(0);
});
});
describe("Borrow Tests", function () {
it("test_deposit_ETH_and_borrow_DAI_underlying", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
const depositAmount = ethers.utils.parseEther("10");
await helpers.depositCollateralBorrowAndWithdraw(
dsaWallet0, wallet0, wallet1, ETH_ID, DEPOSIT_UNDERLYING, depositAmount, DAI_ID, MARKET_3M, 1000e8, 0, true
);
expect(
await daiToken.balanceOf(dsaWallet0.address),
"expect DSA wallet to contain borrowed balance minus fees"
).to.be.gte(ethers.utils.parseEther("990"));
});
it("test_deposit_ETH_and_borrow_DAI_asset", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
const depositAmount = ethers.utils.parseEther("10");
await helpers.depositCollateralBorrowAndWithdraw(
dsaWallet0, wallet0, wallet1, ETH_ID, DEPOSIT_UNDERLYING, depositAmount, DAI_ID, MARKET_3M, 1000e8, 0, false
);
expect(
await cdaiToken.balanceOf(dsaWallet0.address),
"expect DSA wallet to contain borrowed balance minus fees"
).to.be.gte(ethers.utils.parseUnits("4500000000000", 0));
});
it("test_deposit_DAI_underlying_and_borrow_ETH", async function () {
const depositAmount = ethers.utils.parseUnits("20000", 18);
await daiToken.connect(daiWhale).transfer(wallet0.address, depositAmount);
await daiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, daiToken.address, depositAmount);
await helpers.depositCollateralBorrowAndWithdraw(
dsaWallet0, wallet0, wallet1, DAI_ID, DEPOSIT_UNDERLYING, depositAmount, ETH_ID, MARKET_3M, 1e8, 0, true
);
expect(
await ethers.provider.getBalance(dsaWallet0.address),
"expect DSA wallet to contain borrowed balance minus fees"
).to.be.gte(ethers.utils.parseEther("0.99"));
});
it("test_deposit_DAI_asset_and_borrow_ETH", async function () {
const depositAmount = ethers.utils.parseUnits("1000000", 8);
await cdaiToken.connect(cdaiWhale).transfer(wallet0.address, depositAmount);
await cdaiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, cdaiToken.address, depositAmount);
await helpers.depositCollateralBorrowAndWithdraw(
dsaWallet0, wallet0, wallet1, DAI_ID, DEPOSIT_ASSET, depositAmount, ETH_ID, MARKET_3M, 1e8, 0, true
);
expect(
await ethers.provider.getBalance(dsaWallet0.address),
"expect DSA wallet to contain borrowed balance minus fees"
).to.be.gte(ethers.utils.parseEther("0.99"));
});
it("test_mint_nDAI_underlying_and_borrow_ETH", async function () {
const depositAmount = ethers.utils.parseUnits("20000", 18);
await daiToken.connect(daiWhale).transfer(wallet0.address, depositAmount);
await daiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, daiToken.address, depositAmount);
await helpers.depositCollateralBorrowAndWithdraw(
dsaWallet0, wallet0, wallet1, DAI_ID, DEPOSIT_UNDERLYING_MINT_NTOKEN, depositAmount, ETH_ID, MARKET_3M, 1e8, 0, true
);
expect(
await ethers.provider.getBalance(dsaWallet0.address),
"expect DSA wallet to contain borrowed balance minus fees"
).to.be.gte(ethers.utils.parseEther("0.99"));
});
it("test_mint_nDAI_asset_and_borrow_ETH", async function () {
const depositAmount = ethers.utils.parseUnits("1000000", 8);
await cdaiToken.connect(cdaiWhale).transfer(wallet0.address, depositAmount);
await cdaiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, cdaiToken.address, depositAmount);
await helpers.depositCollateralBorrowAndWithdraw(
dsaWallet0, wallet0, wallet1, DAI_ID, DEPOSIT_ASSET_MINT_NTOKEN, depositAmount, ETH_ID, MARKET_3M, 1e8, 0, true
);
expect(
await ethers.provider.getBalance(dsaWallet0.address),
"expect DSA wallet to contain borrowed balance minus fees"
).to.be.gte(ethers.utils.parseEther("0.99"));
});
});
describe("Withdraw Tests", function () {
it("test_withdraw_ETH_underlying", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
const depositAmount = ethers.utils.parseEther("1");
await helpers.depositCollteral(dsaWallet0, wallet0, wallet1, 1, depositAmount, true);
await helpers.withdrawCollateral(dsaWallet0, wallet0, wallet1, 1, ethers.constants.MaxUint256, true);
expect(
await ethers.provider.getBalance(dsaWallet0.address),
"expect DSA wallet to contain underlying funds"
).to.be.gte(ethers.utils.parseEther("10"));
});
it("test_withdraw_ETH_asset", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
const depositAmount = ethers.utils.parseEther("1");
await helpers.depositCollteral(dsaWallet0, wallet0, wallet1, ETH_ID, depositAmount, true);
await helpers.withdrawCollateral(dsaWallet0, wallet0, wallet1, ETH_ID, ethers.constants.MaxUint256, false);
expect(
await cethToken.balanceOf(dsaWallet0.address),
"expect DSA wallet to contain cToken funds"
).to.be.gte(ethers.utils.parseUnits("4900000000", 0));
});
it("test_redeem_DAI_raw", async function () {
const depositAmount = ethers.utils.parseUnits("1000", 8);
await cdaiToken.connect(cdaiWhale).transfer(wallet0.address, depositAmount);
await cdaiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, cdaiToken.address, depositAmount);
await helpers.depositAndMintNToken(dsaWallet0, wallet0, wallet1, DAI_ID, depositAmount, false);
await helpers.redeemNTokenRaw(dsaWallet0, wallet0, wallet1, DAI_ID, true, MaxUint96)
const bal = await notional.callStatic.getAccountBalance(DAI_ID, dsaWallet0.address);
expect(bal[0], "expect cDAI balance after redemption").to.be.gte(ethers.utils.parseUnits("99000000000", 0));
expect(bal[1], "expect 0 nDAI").to.be.equal(ethers.utils.parseEther("0"));
});
it("test_redeem_DAI_and_withdraw_redeem", async function () {
const depositAmount = ethers.utils.parseUnits("1000", 8);
await cdaiToken.connect(cdaiWhale).transfer(wallet0.address, depositAmount);
await cdaiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, cdaiToken.address, depositAmount);
await helpers.depositAndMintNToken(dsaWallet0, wallet0, wallet1, DAI_ID, depositAmount, false);
await helpers.redeemNTokenAndWithdraw(dsaWallet0, wallet0, wallet1, DAI_ID, MaxUint96, ethers.constants.MaxUint256, true);
const bal = await notional.callStatic.getAccountBalance(DAI_ID, dsaWallet0.address);
expect(bal[0], "expect 0 cDAI balance").to.be.equal(ethers.utils.parseEther("0"));
expect(bal[1], "expect 0 nDAI balance").to.be.equal(ethers.utils.parseEther("0"));
});
it("test_redeem_DAI_and_withdraw_no_redeem", async function () {
const depositAmount = ethers.utils.parseUnits("1000", 8);
await cdaiToken.connect(cdaiWhale).transfer(wallet0.address, depositAmount);
await cdaiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, cdaiToken.address, depositAmount);
await helpers.depositAndMintNToken(dsaWallet0, wallet0, wallet1, DAI_ID, depositAmount, false);
expect(await cdaiToken.balanceOf(dsaWallet0.address)).to.be.equal(ethers.utils.parseEther("0"));
await helpers.redeemNTokenAndWithdraw(dsaWallet0, wallet0, wallet1, DAI_ID, MaxUint96, ethers.constants.MaxUint256, false);
const bal = await notional.callStatic.getAccountBalance(DAI_ID, dsaWallet0.address);
expect(bal[0], "expect 0 cDAI balance").to.be.equal(ethers.utils.parseEther("0"));
expect(bal[1], "expect 0 nDAI balance").to.be.equal(ethers.utils.parseEther("0"));
expect(
await cdaiToken.balanceOf(dsaWallet0.address),
"expect DSA wallet to contain cToken funds"
).to.be.gte(ethers.utils.parseUnits("99000000000", 0));
});
it("test_redeem_DAI_and_deleverage", async function () {
const depositAmount = ethers.utils.parseUnits("20000", 18);
await daiToken.connect(daiWhale).transfer(wallet0.address, depositAmount);
await daiToken.connect(wallet0).approve(dsaWallet0.address, ethers.constants.MaxUint256);
await helpers.depositERC20(dsaWallet0, wallet0, wallet1, daiToken.address, depositAmount);
await helpers.depositCollateralBorrowAndWithdraw(
dsaWallet0, wallet0, wallet1, DAI_ID, DEPOSIT_UNDERLYING, depositAmount, ETH_ID, MARKET_3M, 1e8, 0, true
);
const bal = await ethers.provider.getBalance(dsaWallet0.address);
await helpers.depositAndMintNToken(dsaWallet0, wallet0, wallet1, ETH_ID, bal, true);
const before = await notional.getAccountPortfolio(dsaWallet0.address);
expect(before.length, "expect 1 fDAI debt position").to.be.equal(1);
expect(before[0][3], "expect fDAI debt position to equal borrow amount").to.be.lte(ethers.utils.parseUnits("-100000000", 0));
await helpers.redeemNTokenAndDeleverage(dsaWallet0, wallet0, wallet1, ETH_ID, MaxUint96, MARKET_3M, 0.98e8, 0);
const after = await notional.getAccountPortfolio(dsaWallet0.address);
expect(after.length, "expect 1 fDAI debt position after deleverage").to.be.equal(1);
expect(after[0][3], "expect fDAI debt balance to go down after deleverage").to.be.lte(ethers.utils.parseUnits("-2000000", 0));
});
});
});