import { APPROVAL_AMOUNT_LENDING_POOL, MOCK_ETH_ADDRESS, AAVE_REFERRAL, MAX_UINT_AMOUNT, ZERO_ADDRESS, } from "../helpers/constants"; import {convertToCurrencyDecimals} from "../helpers/contracts-helpers"; import {expect} from "chai"; import {ethers} from "ethers"; import {RateMode, ProtocolErrors} from "../helpers/types"; import {makeSuite, TestEnv} from "./helpers/make-suite"; makeSuite("AToken: Transfer", (testEnv: TestEnv) => { const { INVALID_FROM_BALANCE_AFTER_TRANSFER, INVALID_TO_BALANCE_AFTER_TRANSFER, INVALID_REDIRECTED_BALANCE_BEFORE_TRANSFER, INVALID_REDIRECTED_BALANCE_AFTER_TRANSFER, INVALID_REDIRECTION_ADDRESS, ZERO_COLLATERAL, TRANSFERRED_AMOUNT_GT_ZERO, } = ProtocolErrors; it("User 0 deposits 1000 DAI, transfers to user 1", async () => { const {users, pool, dai, aDai} = testEnv; await dai .connect(users[0].signer) .mint(await convertToCurrencyDecimals(dai.address, "1000")); await dai .connect(users[0].signer) .approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); //user 1 deposits 1000 DAI const amountDAItoDeposit = await convertToCurrencyDecimals( dai.address, "1000" ); await pool .connect(users[0].signer) .deposit(dai.address, amountDAItoDeposit, "0"); await aDai .connect(users[0].signer) .transfer(users[1].address, amountDAItoDeposit); const fromBalance = await aDai.balanceOf(users[0].address); const toBalance = await aDai.balanceOf(users[1].address); expect(fromBalance.toString()).to.be.equal( "0", INVALID_FROM_BALANCE_AFTER_TRANSFER ); expect(toBalance.toString()).to.be.equal( amountDAItoDeposit.toString(), INVALID_TO_BALANCE_AFTER_TRANSFER ); }); it("User 1 redirects interest to user 2, transfers 500 DAI back to user 0", async () => { const {users, aDai, dai} = testEnv; await aDai .connect(users[1].signer) .redirectInterestStream(users[2].address); const aDAIRedirected = await convertToCurrencyDecimals(dai.address, "1000"); const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, "500"); const user2RedirectedBalanceBefore = await aDai.getRedirectedBalance( users[2].address ); expect(user2RedirectedBalanceBefore.toString()).to.be.equal( aDAIRedirected, INVALID_REDIRECTED_BALANCE_BEFORE_TRANSFER ); await aDai .connect(users[1].signer) .transfer(users[0].address, aDAItoTransfer); const user2RedirectedBalanceAfter = await aDai.getRedirectedBalance( users[2].address ); const user1RedirectionAddress = await aDai.getInterestRedirectionAddress( users[1].address ); expect(user2RedirectedBalanceAfter.toString()).to.be.equal( aDAItoTransfer, INVALID_REDIRECTED_BALANCE_BEFORE_TRANSFER ); expect(user1RedirectionAddress.toString()).to.be.equal( users[2].address, INVALID_REDIRECTION_ADDRESS ); }); it("User 0 transfers back to user 1", async () => { const {users, aDai, dai} = testEnv; const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, "500"); await aDai .connect(users[0].signer) .transfer(users[1].address, aDAItoTransfer); const user2RedirectedBalanceAfter = await aDai.getRedirectedBalance( users[2].address ); const user1BalanceAfter = await aDai.balanceOf(users[1].address); expect(user2RedirectedBalanceAfter.toString()).to.be.equal( user1BalanceAfter.toString(), INVALID_REDIRECTED_BALANCE_AFTER_TRANSFER ); }); it("User 0 deposits 1 ETH and user tries to borrow, but the aTokens received as a transfer are not available as collateral (revert expected)", async () => { const {users, pool} = testEnv; await pool .connect(users[0].signer) .deposit(MOCK_ETH_ADDRESS, ethers.utils.parseEther("1.0"), "0", { value: ethers.utils.parseEther("1.0"), }); await expect( pool .connect(users[1].signer) .borrow( MOCK_ETH_ADDRESS, ethers.utils.parseEther("0.1"), RateMode.Stable, AAVE_REFERRAL ), ZERO_COLLATERAL ).to.be.revertedWith(ZERO_COLLATERAL); }); it("User 1 sets the DAI as collateral and borrows, tries to transfer everything back to user 0 (revert expected)", async () => { const {users, pool, aDai, dai} = testEnv; await pool .connect(users[1].signer) .setUserUseReserveAsCollateral(dai.address, true); const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, "1000"); await pool .connect(users[1].signer) .borrow( MOCK_ETH_ADDRESS, ethers.utils.parseEther("0.1"), RateMode.Stable, AAVE_REFERRAL ); await expect( aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer), "Transfer cannot be allowed." ).to.be.revertedWith("Transfer cannot be allowed."); }); it("User 0 tries to transfer 0 balance (revert expected)", async () => { const {users, pool, aDai, dai} = testEnv; await expect( aDai.connect(users[0].signer).transfer(users[1].address, "0"), TRANSFERRED_AMOUNT_GT_ZERO ).to.be.revertedWith(TRANSFERRED_AMOUNT_GT_ZERO); }); it("User 1 repays the borrow, transfers aDAI back to user 0", async () => { const {users, pool, aDai, dai} = testEnv; await pool .connect(users[1].signer) .repay(MOCK_ETH_ADDRESS, MAX_UINT_AMOUNT, RateMode.Stable, users[1].address, { value: ethers.utils.parseEther("1"), }); const aDAItoTransfer = await convertToCurrencyDecimals( aDai.address, "1000" ); await aDai .connect(users[1].signer) .transfer(users[0].address, aDAItoTransfer); const user2RedirectedBalanceAfter = await aDai.getRedirectedBalance( users[2].address ); const user1RedirectionAddress = await aDai.getInterestRedirectionAddress( users[1].address ); expect(user2RedirectedBalanceAfter.toString()).to.be.equal( "0", INVALID_REDIRECTED_BALANCE_AFTER_TRANSFER ); expect(user1RedirectionAddress.toString()).to.be.equal( ZERO_ADDRESS, INVALID_REDIRECTION_ADDRESS ); }); it("User 0 redirects interest to user 2, transfers 500 aDAI to user 1. User 1 redirects to user 3. User 0 transfers another 100 aDAI", async () => { const {users, pool, aDai, dai} = testEnv; let aDAItoTransfer = await convertToCurrencyDecimals(aDai.address, "500"); await aDai .connect(users[0].signer) .redirectInterestStream(users[2].address); await aDai .connect(users[0].signer) .transfer(users[1].address, aDAItoTransfer); await aDai .connect(users[1].signer) .redirectInterestStream(users[3].address); aDAItoTransfer = await convertToCurrencyDecimals(aDai.address, "100"); await aDai .connect(users[0].signer) .transfer(users[1].address, aDAItoTransfer); const user2RedirectedBalanceAfter = await aDai.getRedirectedBalance( users[2].address ); const user3RedirectedBalanceAfter = await aDai.getRedirectedBalance( users[3].address ); const expectedUser2Redirected = await convertToCurrencyDecimals( aDai.address, "400" ); const expectedUser3Redirected = await convertToCurrencyDecimals( aDai.address, "600" ); expect(user2RedirectedBalanceAfter.toString()).to.be.equal( expectedUser2Redirected, INVALID_REDIRECTED_BALANCE_AFTER_TRANSFER ); expect(user3RedirectedBalanceAfter.toString()).to.be.equal( expectedUser3Redirected, INVALID_REDIRECTED_BALANCE_AFTER_TRANSFER ); }); });