Skip to content

Commit

Permalink
100% coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
mshrieve committed Jun 14, 2024
1 parent 866dffc commit 4ad3e9c
Show file tree
Hide file tree
Showing 10 changed files with 737 additions and 38 deletions.
489 changes: 489 additions & 0 deletions lcov.info

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/PolyLend.sol
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ contract PolyLend is PolyLendEE, ERC1155TokenReceiver {
// transfer usdc from the lender to the borrower
usdc.transferFrom(lender, msg.sender, loanAmount);

emit LoanAccepted(requestId, block.timestamp);
emit LoanAccepted(loanId, block.timestamp);

return loanId;
}
Expand Down
57 changes: 48 additions & 9 deletions src/test/Accept.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@ pragma solidity ^0.8.15;

import {PolyLendTestHelper, Loan} from "./PolyLendTestHelper.sol";

contract PolyLendRequestTest is PolyLendTestHelper {
contract PolyLendAcceptTest is PolyLendTestHelper {
uint256 rate;
uint256 offerId;

function test_PolyLend_accept(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint32 _minimumDuration
) public {
function _setUp(uint128 _collateralAmount, uint128 _loanAmount, uint256 _rate, uint32 _minimumDuration) internal {
vm.assume(_collateralAmount > 0);
vm.assume(_minimumDuration <= 60 days);

Expand All @@ -27,12 +23,21 @@ contract PolyLendRequestTest is PolyLendTestHelper {

vm.startPrank(lender);
usdc.approve(address(polyLend), _loanAmount);
uint256 offerId = polyLend.offer(requestId, _loanAmount, rate);
offerId = polyLend.offer(requestId, _loanAmount, rate);
vm.stopPrank();
}

function test_PolyLendAcceptTest_accept(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint32 _minimumDuration
) public {
_setUp(_collateralAmount, _loanAmount, _rate, _minimumDuration);

vm.startPrank(borrower);
vm.expectEmit();
emit LoanAccepted(requestId, block.timestamp);
emit LoanAccepted(0, block.timestamp);
polyLend.accept(offerId);
vm.stopPrank();

Expand All @@ -51,4 +56,38 @@ contract PolyLendRequestTest is PolyLendTestHelper {
assertEq(usdc.balanceOf(borrower), _loanAmount);
assertEq(conditionalTokens.balanceOf(address(polyLend), positionId0), _collateralAmount);
}

function test_revert_PolyLendAcceptTest_accept_OnlyBorrower(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint32 _minimumDuration,
address _caller
) public {
vm.assume(_caller != borrower);

_setUp(_collateralAmount, _loanAmount, _rate, _minimumDuration);

vm.startPrank(_caller);
vm.expectRevert(OnlyBorrower.selector);
polyLend.accept(offerId);
vm.stopPrank();
}

function test_revert_PolyLendAcceptTest_accept_InvalidOffer(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint32 _minimumDuration,
uint256 _offerId
) public {
vm.assume(_offerId > 0);

_setUp(_collateralAmount, _loanAmount, _rate, _minimumDuration);

vm.startPrank(borrower);
vm.expectRevert(InvalidOffer.selector);
polyLend.accept(_offerId);
vm.stopPrank();
}
}
8 changes: 4 additions & 4 deletions src/test/Call.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ contract PolyLendCallTest is PolyLendTestHelper {
vm.stopPrank();
}

function test_PolyLend_call(
function test_PolyLendCallTest_call(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
Expand Down Expand Up @@ -63,7 +63,7 @@ contract PolyLendCallTest is PolyLendTestHelper {
assertEq(loan.callTime, block.timestamp);
}

function test_revert_PolyLend_call_OnlyLender(
function test_revert_PolyLendCallTest_call_OnlyLender(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
Expand All @@ -79,7 +79,7 @@ contract PolyLendCallTest is PolyLendTestHelper {
vm.stopPrank();
}

function test_revert_PolyLend_call_MinimumDurationHasNotPassed(
function test_revert_PolyLendCallTest_call_MinimumDurationHasNotPassed(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
Expand All @@ -99,7 +99,7 @@ contract PolyLendCallTest is PolyLendTestHelper {
vm.stopPrank();
}

function test_revert_PolyLend_call_LoanIsCalled(
function test_revert_PolyLendCallTest_call_LoanIsCalled(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
Expand Down
14 changes: 14 additions & 0 deletions src/test/Constructor.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {Test, console2 as console, stdStorage, StdStorage, stdError} from "../../lib/forge-std/src/Test.sol";
import {PolyLend} from "../PolyLend.sol";

contract PolyLendConstructorTest is Test {
function test_PolyLendConstructorTest_constructor(address _conditionalTokens, address _usdc) public {
PolyLend polyLend = new PolyLend(_conditionalTokens, _usdc);

vm.assertEq(address(polyLend.usdc()), _usdc);
vm.assertEq(address(polyLend.conditionalTokens()), _conditionalTokens);
}
}
2 changes: 1 addition & 1 deletion src/test/InterestLib.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {InterestLib} from "../InterestLib.sol";
contract InterestLibTest is Test {
using InterestLib for uint256;

function testPow() public pure {
function test_InterestLibTest_pow() public pure {
uint256 base = 2 * InterestLib.ONE;
uint256 exponent = 3;
uint256 result = base.pow(exponent);
Expand Down
98 changes: 92 additions & 6 deletions src/test/Offer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,33 @@ import {PolyLendTestHelper, Offer} from "./PolyLendTestHelper.sol";

contract PolyLendOfferTest is PolyLendTestHelper {
uint256 rate;
uint256 requestId;

function test_PolyLend_offer(uint128 _amount, uint128 _loanAmount, uint256 _rate, uint32 _minimumDuration) public {
vm.assume(_amount > 0);
function _setUp(uint128 _collateralAmount, uint128 _loanAmount, uint256 _rate, uint32 _minimumDuration) internal {
vm.assume(_collateralAmount > 0);
vm.assume(_loanAmount > 0);
vm.assume(_minimumDuration <= 60 days);

rate = bound(_rate, 10 ** 18 + 1, polyLend.MAX_INTEREST());

_mintConditionalTokens(borrower, _amount, positionId0);
usdc.mint(lender, _loanAmount);
_mintConditionalTokens(borrower, _collateralAmount, positionId0);

vm.startPrank(borrower);
conditionalTokens.setApprovalForAll(address(polyLend), true);

uint256 requestId = polyLend.request(positionId0, _amount, _minimumDuration);
requestId = polyLend.request(positionId0, _collateralAmount, _minimumDuration);
vm.stopPrank();
}

function test_PolyLendOfferTest_offer(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint32 _minimumDuration
) public {
_setUp(_collateralAmount, _loanAmount, _rate, _minimumDuration);

vm.startPrank(lender);
usdc.mint(lender, _loanAmount);
usdc.approve(address(polyLend), _loanAmount);
vm.expectEmit();
emit LoanOffered(requestId, lender, _loanAmount, rate);
Expand All @@ -35,4 +45,80 @@ contract PolyLendOfferTest is PolyLendTestHelper {
assertEq(offer.loanAmount, _loanAmount);
assertEq(offer.rate, rate);
}

function test_revert_PolyLendOfferTest_offer_InvalidRequestId(uint128 _loanAmount) public {
vm.startPrank(lender);
vm.expectRevert(InvalidRequest.selector);
polyLend.offer(0, _loanAmount, rate);
vm.stopPrank();
}

function test_revert_PolyLendOfferTest_offer_InsufficientFunds(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint32 _minimumDuration,
uint128 _balance
) public {
_setUp(_collateralAmount, _loanAmount, _rate, _minimumDuration);

uint256 balance = bound(_balance, 0, _loanAmount - 1);
vm.startPrank(lender);
usdc.mint(lender, balance);
vm.expectRevert(InsufficientFunds.selector);
polyLend.offer(requestId, _loanAmount, rate);
vm.stopPrank();
}

function test_revert_PolyLendOfferTest_offer_InsufficientAllowance(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint32 _minimumDuration,
uint128 _allowance
) public {
_setUp(_collateralAmount, _loanAmount, _rate, _minimumDuration);

uint256 allowance = bound(_allowance, 0, _loanAmount - 1);
vm.startPrank(lender);
usdc.mint(lender, _loanAmount);
usdc.approve(address(polyLend), allowance);
vm.expectRevert(InsufficientAllowance.selector);
polyLend.offer(requestId, _loanAmount, rate);
vm.stopPrank();
}

function test_revert_PolyLendOfferTest_offer_InvalidRate_tooLow(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint32 _minimumDuration
) public {
_setUp(_collateralAmount, _loanAmount, _rate, _minimumDuration);

rate = bound(_rate, 0, 10 ** 18);
vm.startPrank(lender);
usdc.mint(lender, _loanAmount);
usdc.approve(address(polyLend), _loanAmount);
vm.expectRevert(InvalidRate.selector);
polyLend.offer(requestId, _loanAmount, rate);
vm.stopPrank();
}

function test_revert_PolyLendOfferTest_offer_InvalidRate_tooHigh(
uint128 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint32 _minimumDuration
) public {
_setUp(_collateralAmount, _loanAmount, _rate, _minimumDuration);

rate = bound(_rate, polyLend.MAX_INTEREST() + 1, type(uint64).max);
vm.startPrank(lender);
usdc.mint(lender, _loanAmount);
usdc.approve(address(polyLend), _loanAmount);
vm.expectRevert(InvalidRate.selector);
polyLend.offer(requestId, _loanAmount, rate);
vm.stopPrank();
}
}
50 changes: 45 additions & 5 deletions src/test/Repay.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,46 @@ contract PolyLendRepayTest is PolyLendTestHelper {
assertEq(conditionalTokens.balanceOf(address(borrower), positionId0), _collateralAmount);
}

function test_PolyLendRepayTest_repay_calledLoan(
uint64 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
uint256 _minimumDuration,
uint256 _duration,
uint256 _auctionDuration
) public {
_setUp(_collateralAmount, _loanAmount, _rate, _minimumDuration);

uint256 duration = bound(_duration, _minimumDuration, 90 days);
uint256 auctionDuration = bound(_auctionDuration, 0, polyLend.AUCTION_DURATION());

uint256 callTime = block.timestamp + duration;
vm.warp(callTime);

vm.startPrank(lender);
polyLend.call(loanId);
vm.stopPrank();

vm.warp(block.timestamp + auctionDuration);
uint256 amountOwed = polyLend.getAmountOwed(loanId, callTime);

vm.startPrank(borrower);
usdc.mint(borrower, amountOwed - usdc.balanceOf(borrower));
usdc.approve(address(polyLend), amountOwed);
vm.expectEmit();
emit LoanRepaid(loanId);
polyLend.repay(loanId, callTime);
vm.stopPrank();

Loan memory loan = _getLoan(loanId);

assertEq(loan.borrower, address(0));
assertEq(usdc.balanceOf(borrower), 0);
assertEq(usdc.balanceOf(lender), amountOwed);
assertEq(conditionalTokens.balanceOf(address(polyLend), positionId0), 0);
assertEq(conditionalTokens.balanceOf(address(borrower), positionId0), _collateralAmount);
}

function test_PolyLendRepayTest_repay_paybackBuffer(
uint64 _collateralAmount,
uint128 _loanAmount,
Expand Down Expand Up @@ -98,7 +138,7 @@ contract PolyLendRepayTest is PolyLendTestHelper {
assertEq(conditionalTokens.balanceOf(address(borrower), positionId0), _collateralAmount);
}

function test_revert_PolyLendRepayTest_alreadyRepaid_OnlyBorrower(
function test_revert_PolyLendRepayTest_repay_alreadyRepaid_OnlyBorrower(
uint64 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
Expand All @@ -125,7 +165,7 @@ contract PolyLendRepayTest is PolyLendTestHelper {
vm.stopPrank();
}

function test_revert_PolyLendRepayTest_OnlyBorrower(
function test_revert_PolyLendRepayTest_repay_OnlyBorrower(
uint64 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
Expand All @@ -143,7 +183,7 @@ contract PolyLendRepayTest is PolyLendTestHelper {
}

/// @dev Reverts if _repayTimestamp is too early for an uncalled loan
function test_revert_PolyLendRepayTest_timestampTooEarly_InvalidRepayTimestamp(
function test_revert_PolyLendRepayTest_repay_timestampTooEarly_InvalidRepayTimestamp(
uint64 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
Expand All @@ -166,7 +206,7 @@ contract PolyLendRepayTest is PolyLendTestHelper {
}

/// @dev Reverts if _repayTimestamp does not equal call time for a called loan
function test_revert_PolyLendRepayTest_doesNotEqualCallTime_InvalidRepayTimestamp(
function test_revert_PolyLendRepayTest_repay_doesNotEqualCallTime_InvalidRepayTimestamp(
uint64 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
Expand Down Expand Up @@ -195,7 +235,7 @@ contract PolyLendRepayTest is PolyLendTestHelper {
vm.stopPrank();
}

function test_revert_PolyLendRepayTest_InsufficientAllowance(
function test_revert_PolyLendRepayTest_repay_InsufficientAllowance(
uint64 _collateralAmount,
uint128 _loanAmount,
uint256 _rate,
Expand Down
8 changes: 4 additions & 4 deletions src/test/Request.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.15;
import {PolyLendTestHelper, Request} from "./PolyLendTestHelper.sol";

contract PolyLendRequestTest is PolyLendTestHelper {
function test_PolyLend_request(uint128 _amount, uint32 _minimumDuration) public {
function test_PolyLendRequestTest_request(uint128 _amount, uint32 _minimumDuration) public {
vm.assume(_amount > 0);
vm.assume(_minimumDuration <= 60 days);

Expand All @@ -26,19 +26,19 @@ contract PolyLendRequestTest is PolyLendTestHelper {
assertEq(request.minimumDuration, _minimumDuration);
}

function test_revert_PolyLend_request_CollateralAmountIsZero() public {
function test_revert_PolyLendRequestTest_request_CollateralAmountIsZero() public {
vm.prank(borrower);
vm.expectRevert(CollateralAmountIsZero.selector);
polyLend.request(positionId0, 0, 0);
}

function test_revert_PolyLend_request_InsufficientCollateralBalance() public {
function test_revert_PolyLendRequestTest_request_InsufficientCollateralBalance() public {
vm.prank(borrower);
vm.expectRevert(InsufficientCollateralBalance.selector);
polyLend.request(positionId0, 100_000_000, 0);
}

function test_revert_PolyLend_request_CollateralIsNotApproved() public {
function test_revert_PolyLendRequestTest_request_CollateralIsNotApproved() public {
_mintConditionalTokens(borrower, 100_000_000, positionId0);

vm.prank(borrower);
Expand Down
Loading

0 comments on commit 4ad3e9c

Please sign in to comment.