|
| 1 | +import { formatEther, formatUnits, parseEther, parseUnits } from "@ethersproject/units"; |
| 2 | +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; |
| 3 | +import { waffle } from "hardhat"; |
| 4 | +import { ERC20, ILendingPool } from "../../typechain"; |
| 5 | +import { useChai } from "../utils"; |
| 6 | +import { aaveV2Fixture } from "./utils/fixtures"; |
| 7 | + |
| 8 | +const expect = useChai(); |
| 9 | + |
| 10 | +describe("Borrow and Repay", function () { |
| 11 | + let wallet: SignerWithAddress; |
| 12 | + let DAI: ERC20; |
| 13 | + let USDC: ERC20; |
| 14 | + let pool: ILendingPool; |
| 15 | + |
| 16 | + before(async function () { |
| 17 | + ({ wallet, DAI, USDC, lendingPool: pool } = await waffle.loadFixture(aaveV2Fixture)); |
| 18 | + |
| 19 | + // let's add some collateral to our account |
| 20 | + // otherwise we won't be able to take a loan |
| 21 | + const daiBal = parseEther("1000"); |
| 22 | + await DAI.approve(pool.address, daiBal); |
| 23 | + await pool.deposit(DAI.address, daiBal, wallet.address, 0); |
| 24 | + }); |
| 25 | + |
| 26 | + it("setting a particular asset as collateral", async () => { |
| 27 | + // let's say you have multiple assets deposited into the aave v2 protocol |
| 28 | + // but you only want to use one of them, to get the loan |
| 29 | + // ie -> in case of liquidations (loan fail), you don't want to lose your other tokens |
| 30 | + // in such a case we set an asset reserve to be used as collateral for our account |
| 31 | + |
| 32 | + // we pass in the asset address, and whether it should be used as collateral |
| 33 | + // in our case since we deposited DAI, i will use it as collateral |
| 34 | + await pool.setUserUseReserveAsCollateral(DAI.address, true); |
| 35 | + }); |
| 36 | + |
| 37 | + it("borrow stable loan", async () => { |
| 38 | + // let's check our USDC balance before we borrow |
| 39 | + const balBefore = await USDC.balanceOf(wallet.address); |
| 40 | + console.log("balance of USDC before we borrow: ", formatUnits(balBefore, 6)); |
| 41 | + expect(balBefore).to.eq(0); |
| 42 | + |
| 43 | + // so aave has two kinds of loans |
| 44 | + // 1. stable loans - stable apr in the short term, long term adjusts to market change |
| 45 | + // 2. variable loans - variable apr, changes based on the supply / demand |
| 46 | + // more on this here: https://docs.aave.com/faq/borrowing#what-is-the-difference-between-stable-and-variable-rate |
| 47 | + |
| 48 | + const amt = parseUnits("700", 6); // we can only borrow a fraction of our collateral |
| 49 | + await pool.borrow( |
| 50 | + USDC.address, // address of asset we want to borrow |
| 51 | + amt, // amt we want to borrow |
| 52 | + 1, // interest rate mode -> 1 = stable, 2 = variable |
| 53 | + 0, // referral code |
| 54 | + wallet.address, // on behalf of which account |
| 55 | + ); |
| 56 | + |
| 57 | + // let's check our USDC balance after we borrow |
| 58 | + const balAfter = await USDC.balanceOf(wallet.address); |
| 59 | + console.log("balance of USDC before we borrow: ", formatUnits(balAfter, 6)); |
| 60 | + expect(balAfter).to.eq(amt); |
| 61 | + }); |
| 62 | + |
| 63 | + it("change borrow rate mode from stable to variable", async () => { |
| 64 | + // let's assume we have a loan in stable borrowing rate, like we do in previous test |
| 65 | + // how do we convert it from stable to variable borrowing rate? |
| 66 | + // Well, super simple -> we provide the asset address & current rate mode |
| 67 | + // since our current rate mode is 1 (stable), we pass in that and aave will replace |
| 68 | + // it with variable |
| 69 | + await pool.swapBorrowRateMode(USDC.address, 1); |
| 70 | + }); |
| 71 | + |
| 72 | + it("repay the borrowed sum (ie: replay the loan)", async () => { |
| 73 | + const balBefore = await USDC.balanceOf(wallet.address); |
| 74 | + console.log("USDC balance before repaying debt = ", formatUnits(balBefore, 6)); |
| 75 | + expect(balBefore).to.not.eq(0); |
| 76 | + |
| 77 | + // let's allow the pool to withdraw the amount from our USDC account |
| 78 | + await USDC.approve(pool.address, balBefore); |
| 79 | + // call pool.repay with similar arguments in borrow |
| 80 | + // asset, balance we want to repay, borrow rate (variable), and on behalf of address |
| 81 | + await pool.repay(USDC.address, balBefore, 2, wallet.address); |
| 82 | + const balAfter = await USDC.balanceOf(wallet.address); |
| 83 | + |
| 84 | + console.log("USDC balance after repaying debt = ", formatUnits(balAfter, 6)); |
| 85 | + expect(balAfter).to.eq(0); |
| 86 | + |
| 87 | + // let's check our total debt now |
| 88 | + const data = await pool.getUserAccountData(wallet.address); |
| 89 | + console.log("total debt on our account (value in ETH) = ", formatEther(data.totalDebtETH)); |
| 90 | + expect(data.totalDebtETH).to.lte(parseEther("0.0000001")); |
| 91 | + }); |
| 92 | +}); |
0 commit comments