Skip to content

Commit

Permalink
Add enforcer unit testing (#37)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Redden <[email protected]>
  • Loading branch information
0xgregthedev and androolloyd authored Nov 1, 2023
1 parent 0771896 commit a2d9d81
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 36 deletions.
71 changes: 40 additions & 31 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
DiffFuzzTestStarPortLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880501, ~: 882340)
DiffFuzzTestStarPortLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232899, ~: 237832)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1041770)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 693528)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 773097)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1041013)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 693016)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 772585)
TestBorrowerEnforcer:testBERevertAdditionalTransfers() (gas: 73101)
TestBorrowerEnforcer:testBERevertInvalidLoanTerms() (gas: 78338)
TestBorrowerEnforcer:testBEValidLoanTerms() (gas: 69429)
TestBorrowerEnforcer:testBEValidLoanTermsAnyIssuer() (gas: 69581)
TestCustodian:testCannotLazyMintTwice() (gas: 76686)
TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 66883)
TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 72511)
Expand All @@ -11,9 +15,9 @@ TestCustodian:testDefaultCustodySelectorRevert() (gas: 70105)
TestCustodian:testGenerateOrderInvalidHandlerExecution() (gas: 132855)
TestCustodian:testGenerateOrderRepay() (gas: 164353)
TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 190000)
TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 848490)
TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 790122)
TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 520526)
TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 847956)
TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 789588)
TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 520259)
TestCustodian:testGenerateOrderRepayInvalidHookAddress() (gas: 90249)
TestCustodian:testGenerateOrderRepayInvalidHookReturnType() (gas: 84653)
TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 96449)
Expand Down Expand Up @@ -41,48 +45,53 @@ TestCustodian:testSupportsInterface() (gas: 9428)
TestCustodian:testSymbol() (gas: 7149)
TestCustodian:testTokenURI() (gas: 64839)
TestCustodian:testTokenURIInvalidLoan() (gas: 13218)
TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 533373)
TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 502230)
TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 552096)
TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 541954)
TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 546614)
TestLoanManager:testAdditionalTransfers() (gas: 293327)
TestLoanManager:testCannotIssueSameLoanTwice() (gas: 331775)
TestLenderEnforcer:testLERevertAdditionalTransfersFromLender() (gas: 73760)
TestLenderEnforcer:testLERevertInvalidLoanTerms() (gas: 78385)
TestLenderEnforcer:testLEValidLoanTerms() (gas: 69429)
TestLenderEnforcer:testLEValidLoanTermsAnyBorrower() (gas: 69516)
TestLenderEnforcer:testLEValidLoanTermsWithAdditionalTransfers() (gas: 70757)
TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 532861)
TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 501718)
TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 551584)
TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 541442)
TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 546102)
TestLoanManager:testAdditionalTransfers() (gas: 293082)
TestLoanManager:testCannotIssueSameLoanTwice() (gas: 331285)
TestLoanManager:testCannotOriginateWhilePaused() (gas: 87923)
TestLoanManager:testCannotSettleInvalidLoan() (gas: 72594)
TestLoanManager:testCannotSettleUnlessValidCustodian() (gas: 68750)
TestLoanManager:testCaveatEnforcerRevert() (gas: 119155)
TestLoanManager:testDefaultFeeRake() (gas: 352730)
TestLoanManager:testExoticDebtWithNoCaveatsNotAsBorrower() (gas: 342979)
TestLoanManager:testDefaultFeeRake() (gas: 352463)
TestLoanManager:testExoticDebtWithNoCaveatsNotAsBorrower() (gas: 342734)
TestLoanManager:testInitializedFlagSetProperly() (gas: 65262)
TestLoanManager:testInvalidAmountCollateral() (gas: 153078)
TestLoanManager:testInvalidAmountCollateral721() (gas: 153221)
TestLoanManager:testInvalidAmountDebt() (gas: 177389)
TestLoanManager:testInvalidIdentifierDebt() (gas: 197383)
TestLoanManager:testInvalidItemType() (gas: 139126)
TestLoanManager:testInvalidTransferLengthCollateral() (gas: 161295)
TestLoanManager:testInvalidTransferLengthDebt() (gas: 165838)
TestLoanManager:testInvalidAmountCollateral() (gas: 152833)
TestLoanManager:testInvalidAmountCollateral721() (gas: 152976)
TestLoanManager:testInvalidAmountDebt() (gas: 177144)
TestLoanManager:testInvalidIdentifierDebt() (gas: 197138)
TestLoanManager:testInvalidItemType() (gas: 138881)
TestLoanManager:testInvalidTransferLengthCollateral() (gas: 161050)
TestLoanManager:testInvalidTransferLengthDebt() (gas: 165593)
TestLoanManager:testIssued() (gas: 67144)
TestLoanManager:testName() (gas: 7184)
TestLoanManager:testNonDefaultCustodianCustodyCallFails() (gas: 190465)
TestLoanManager:testNonDefaultCustodianCustodyCallSuccess() (gas: 258714)
TestLoanManager:testNonDefaultCustodianCustodyCallFails() (gas: 190220)
TestLoanManager:testNonDefaultCustodianCustodyCallSuccess() (gas: 258469)
TestLoanManager:testNonPayableFunctions() (gas: 175555)
TestLoanManager:testOverrideFeeRake() (gas: 346469)
TestLoanManager:testOverrideFeeRake() (gas: 346202)
TestLoanManager:testPause() (gas: 34222)
TestLoanManager:testSupportsInterface() (gas: 9181)
TestLoanManager:testSymbol() (gas: 7235)
TestLoanManager:testTokenNoCodeCollateral() (gas: 137898)
TestLoanManager:testTokenNoCodeDebt() (gas: 170934)
TestLoanManager:testTokenNoCodeCollateral() (gas: 137653)
TestLoanManager:testTokenNoCodeDebt() (gas: 170689)
TestLoanManager:testTokenURI() (gas: 64892)
TestLoanManager:testTokenURIInvalidLoan() (gas: 13244)
TestLoanManager:testTransferFromFail() (gas: 80176)
TestLoanManager:testUnPause() (gas: 14291)
TestNewLoan:testBuyNowPayLater() (gas: 2831964)
TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 392402)
TestNewLoan:testBuyNowPayLater() (gas: 2831719)
TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 391890)
TestNewLoan:testNewLoanERC721CollateralLessDebtThanOffered() (gas: 2259)
TestNewLoan:testNewLoanRefinanceNew() (gas: 207)
TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 299336)
TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 354219)
TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 353952)
TestNewLoan:testSettleLoan() (gas: 163)
TestRefStarPortLib:testSpentToReceived() (gas: 13315)
TestRefStarPortLib:testValidateSalt(address,bytes32) (runs: 256, μ: 33865, ~: 33865)
Expand All @@ -100,6 +109,6 @@ TestStrategistOriginator:testInvalidDebtAmountAskingMoreThanOffered() (gas: 2065
TestStrategistOriginator:testInvalidDebtAmountOfferingZero() (gas: 186903)
TestStrategistOriginator:testInvalidDebtAmountRequestingZero() (gas: 206801)
TestStrategistOriginator:testInvalidDebtLength() (gas: 205428)
TestStrategistOriginator:testInvalidOffer() (gas: 396592)
TestStrategistOriginator:testInvalidOffer() (gas: 396325)
TestStrategistOriginator:testInvalidSigner() (gas: 208639)
TestStrategistOriginator:testSetStrategist() (gas: 17818)
12 changes: 8 additions & 4 deletions src/enforcers/BorrowerEnforcer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,23 @@ contract BorrowerEnforcer is CaveatEnforcer {
LoanManager.Loan loan;
}

/// @notice Enforces that the loan terms are identical except for the issuer
/// @notice The issuer is allowed to be any address
/// @notice No additional transfers are permitted
/// @param additionalTransfers The additional transfers to be made
/// @param loan The loan terms
/// @param caveatData The borrowers encoded details
function validate(
ConduitTransfer[] calldata additionalTransfers,
LoanManager.Loan calldata loan,
bytes calldata caveatData
) public view virtual override {
bytes32 loanHash = keccak256(abi.encode(loan));

Details memory details = abi.decode(caveatData, (Details));
if (details.loan.borrower != loan.borrower) revert BorrowerOnlyEnforcer();
details.loan.issuer = loan.issuer;

if (loanHash != keccak256(abi.encode(details.loan))) revert InvalidLoanTerms();
if (keccak256(abi.encode(loan)) != keccak256(abi.encode(details.loan))) revert InvalidLoanTerms();

//Should additional transfers from the accounts other than the borrower be allowed?
if (additionalTransfers.length > 0) revert InvalidAdditionalTransfer();
}
}
7 changes: 6 additions & 1 deletion src/enforcers/LenderEnforcer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@ contract LenderEnforcer is CaveatEnforcer {
LoanManager.Loan loan;
}

/// @notice Enforces that the loan terms are identical except for the borrower
/// @notice The borrower is allowed to be any address
/// @notice No additional transfers from the issuer are permitted
/// @param additionalTransfers The additional transfers to be made
/// @param loan The loan terms
/// @param caveatData The borrowers encoded details
function validate(
ConduitTransfer[] calldata additionalTransfers,
LoanManager.Loan calldata loan,
bytes calldata caveatData
) public view virtual override {
Details memory details = abi.decode(caveatData, (Details));
if (details.loan.issuer != loan.issuer) revert LenderOnlyEnforcer();
details.loan.borrower = loan.borrower;

if (keccak256(abi.encode(loan)) != keccak256(abi.encode(details.loan))) {
Expand Down
46 changes: 46 additions & 0 deletions test/unit-testing/TestBorrowerEnforcer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import "starport-test/StarPortTest.sol";
import {BorrowerEnforcer} from "starport-core/enforcers/BorrowerEnforcer.sol";
import {ConduitTransfer, ConduitItemType} from "seaport-types/src/conduit/lib/ConduitStructs.sol";

import "forge-std/console.sol";

contract TestBorrowerEnforcer is StarPortTest {
function testBERevertAdditionalTransfers() external {
ConduitTransfer[] memory additionalTransfers = new ConduitTransfer[](1);
additionalTransfers[0] = ConduitTransfer({
token: address(0),
amount: 0,
to: address(0),
from: address(0),
identifier: 0,
itemType: ConduitItemType.ERC20
});

LoanManager.Loan memory loan = generateDefaultLoanTerms();
BorrowerEnforcer.Details memory details = BorrowerEnforcer.Details({loan: loan});
vm.expectRevert(BorrowerEnforcer.InvalidAdditionalTransfer.selector);
borrowerEnforcer.validate(additionalTransfers, loan, abi.encode(details));
}

function testBERevertInvalidLoanTerms() external {
LoanManager.Loan memory loan = generateDefaultLoanTerms();

BorrowerEnforcer.Details memory details = BorrowerEnforcer.Details({loan: loan});
details.loan.borrower = lender.addr;
vm.expectRevert(BorrowerEnforcer.InvalidLoanTerms.selector);
borrowerEnforcer.validate(new ConduitTransfer[](0), generateDefaultLoanTerms(), abi.encode(details));
}

function testBEValidLoanTerms() external view {
LoanManager.Loan memory loan = generateDefaultLoanTerms();
borrowerEnforcer.validate(new ConduitTransfer[](0), loan, abi.encode(BorrowerEnforcer.Details({loan: loan})));
}

function testBEValidLoanTermsAnyIssuer() external view {
LoanManager.Loan memory loan = generateDefaultLoanTerms();
BorrowerEnforcer.Details memory details = BorrowerEnforcer.Details({loan: loan});
details.loan.issuer = address(0);

borrowerEnforcer.validate(new ConduitTransfer[](0), loan, abi.encode(BorrowerEnforcer.Details({loan: loan})));
}
}
61 changes: 61 additions & 0 deletions test/unit-testing/TestLenderEnforcer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import "starport-test/StarPortTest.sol";
import {LenderEnforcer} from "starport-core/enforcers/LenderEnforcer.sol";
import {ConduitTransfer, ConduitItemType} from "seaport-types/src/conduit/lib/ConduitStructs.sol";

import "forge-std/console.sol";

contract TestLenderEnforcer is StarPortTest {
function testLERevertAdditionalTransfersFromLender() external {
ConduitTransfer[] memory additionalTransfers = new ConduitTransfer[](1);
additionalTransfers[0] = ConduitTransfer({
token: address(0),
amount: 0,
to: address(0),
from: lender.addr,
identifier: 0,
itemType: ConduitItemType.ERC20
});

LoanManager.Loan memory loan = generateDefaultLoanTerms();

vm.expectRevert(LenderEnforcer.InvalidAdditionalTransfer.selector);
lenderEnforcer.validate(additionalTransfers, loan, abi.encode(LenderEnforcer.Details({loan: loan})));
}

function testLERevertInvalidLoanTerms() external {
LoanManager.Loan memory loan = generateDefaultLoanTerms();

LenderEnforcer.Details memory details = LenderEnforcer.Details({loan: loan});
details.loan.custodian = borrower.addr;
vm.expectRevert(LenderEnforcer.InvalidLoanTerms.selector);

lenderEnforcer.validate(new ConduitTransfer[](0), generateDefaultLoanTerms(), abi.encode(details));
}

function testLEValidLoanTermsWithAdditionalTransfers() external view {
ConduitTransfer[] memory additionalTransfers = new ConduitTransfer[](1);
additionalTransfers[0] = ConduitTransfer({
token: address(0),
amount: 0,
to: address(0),
from: address(0),
identifier: 0,
itemType: ConduitItemType.ERC20
});
LoanManager.Loan memory loan = generateDefaultLoanTerms();
lenderEnforcer.validate(additionalTransfers, loan, abi.encode(LenderEnforcer.Details({loan: loan})));
}

function testLEValidLoanTerms() external view {
LoanManager.Loan memory loan = generateDefaultLoanTerms();
lenderEnforcer.validate(new ConduitTransfer[](0), loan, abi.encode(LenderEnforcer.Details({loan: loan})));
}

function testLEValidLoanTermsAnyBorrower() external view {
LoanManager.Loan memory loan = generateDefaultLoanTerms();
LenderEnforcer.Details memory details = LenderEnforcer.Details({loan: loan});
details.loan.borrower = address(0);

lenderEnforcer.validate(new ConduitTransfer[](0), loan, abi.encode(LenderEnforcer.Details({loan: loan})));
}
}

0 comments on commit a2d9d81

Please sign in to comment.