From 2d103a4607ffa22e3170fecb3f1cdcfaf81a2a77 Mon Sep 17 00:00:00 2001 From: Brice Stacey Date: Thu, 6 Oct 2022 14:14:57 -0400 Subject: [PATCH] Emit LoanFunded and LoanDrawnDown events --- contracts/FundingVault.sol | 10 +++++----- contracts/Pool.sol | 6 +++++- contracts/interfaces/ILoan.sol | 10 ++++++++++ contracts/libraries/LoanLib.sol | 12 ++++++++++++ test/Loan.test.ts | 29 ++++++++++++++++++++++++++--- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/contracts/FundingVault.sol b/contracts/FundingVault.sol index 290abbfa..12949247 100644 --- a/contracts/FundingVault.sol +++ b/contracts/FundingVault.sol @@ -13,7 +13,7 @@ contract FundingVault { using SafeERC20 for IERC20; address private immutable _loan; - IERC20 private immutable _asset; + IERC20 public immutable asset; /** * @dev Modifier restricting access to pool @@ -26,11 +26,11 @@ contract FundingVault { /** * @dev Constructor for the vault * @param loan address of loan - * @param asset asset held by vault + * @param asset_ asset held by vault */ - constructor(address loan, address asset) { + constructor(address loan, address asset_) { _loan = loan; - _asset = IERC20(asset); + asset = IERC20(asset_); } /** @@ -38,6 +38,6 @@ contract FundingVault { */ function withdraw(uint256 amount, address receiver) external onlyLoan { require(receiver != address(0), "FundingVault: 0 address"); - _asset.safeTransfer(receiver, amount); + asset.safeTransfer(receiver, amount); } } diff --git a/contracts/Pool.sol b/contracts/Pool.sol index c999d688..a3c5d237 100644 --- a/contracts/Pool.sol +++ b/contracts/Pool.sol @@ -216,7 +216,11 @@ contract Pool is IPool, ERC20 { /** * @dev Called by the pool manager, this transfers liquidity from the pool to a given loan. */ - function fundLoan(address addr) external onlyManager { + function fundLoan(address addr) + external + onlyManager + atState(IPoolLifeCycleState.Active) + { ILoan loan = ILoan(addr); _liquidityAsset.safeApprove(address(loan), loan.principal()); diff --git a/contracts/interfaces/ILoan.sol b/contracts/interfaces/ILoan.sol index c0eb8577..955fecdf 100644 --- a/contracts/interfaces/ILoan.sol +++ b/contracts/interfaces/ILoan.sol @@ -26,6 +26,16 @@ struct ILoanNonFungibleCollateral { } interface ILoan { + /** + * @dev Emitted when loan is funded. + */ + event LoanFunded(address asset, uint256 amount); + + /** + * @dev Emitted when the loan is drawn down. + */ + event LoanDrawnDown(address asset, uint256 amount); + /** * @dev Emitted when collateral is posted to the loan. */ diff --git a/contracts/libraries/LoanLib.sol b/contracts/libraries/LoanLib.sol index 4b829a2b..71400e7a 100644 --- a/contracts/libraries/LoanLib.sol +++ b/contracts/libraries/LoanLib.sol @@ -15,6 +15,16 @@ library LoanLib { using SafeERC20 for IERC20; using SafeMath for uint256; + /** + * @dev Emitted when loan is funded. + */ + event LoanFunded(address asset, uint256 amount); + + /** + * @dev Emitted when the loan is drawn down. + */ + event LoanDrawnDown(address asset, uint256 amount); + /** * @dev Emitted when collateral is posted to the loan. */ @@ -168,6 +178,7 @@ library LoanLib { address(fundingVault), amount ); + emit LoanFunded(liquidityAsset, amount); return ILoanLifeCycleState.Funded; } @@ -180,5 +191,6 @@ library LoanLib { address receiver ) public { fundingVault.withdraw(amount, receiver); + emit LoanDrawnDown(address(fundingVault.asset()), amount); } } diff --git a/test/Loan.test.ts b/test/Loan.test.ts index 73eb5703..62f979ea 100644 --- a/test/Loan.test.ts +++ b/test/Loan.test.ts @@ -360,7 +360,8 @@ describe("Loan", () => { it("transitions Loan to Funded state", async () => { const fixture = await loadFixture(deployFixture); let { loan } = fixture; - const { borrower, collateralAsset, pool, poolManager } = fixture; + const { borrower, collateralAsset, liquidityAsset, pool, poolManager } = + fixture; // Connect as borrower loan = loan.connect(borrower); @@ -370,8 +371,22 @@ describe("Loan", () => { await expect(loan.postFungibleCollateral(collateralAsset.address, 100)) .not.to.be.reverted; expect(await loan.state()).to.equal(1); - await expect(pool.connect(poolManager).fundLoan(loan.address)).not.to.be - .reverted; + const fundTx = pool.connect(poolManager).fundLoan(loan.address); + await expect(fundTx).not.to.be.reverted; + await expect(fundTx) + .to.emit(loan, "LoanFunded") + .withArgs(loan.liquidityAsset, 500_000); + await expect(fundTx).to.changeTokenBalance( + liquidityAsset, + await loan.fundingVault(), + 500_000 + ); + await expect(fundTx).to.changeTokenBalance( + liquidityAsset, + pool, + -500_000 + ); + expect(await loan.state()).to.equal(4); }); @@ -436,6 +451,14 @@ describe("Loan", () => { borrower.address, 500_000 ); + await expect(drawDownTx).to.changeTokenBalance( + liquidityAsset, + await loan.fundingVault(), + -500_000 + ); + await expect(drawDownTx) + .to.emit(loan, "LoanDrawnDown") + .withArgs(loan.liquidityAsset, 500_000); // Try again const drawDownTx2 = loan.connect(borrower).drawdown();