From 2c8cfae9dd247b1949250f51fc9cdd52328f6c4d Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 07:52:35 -0300 Subject: [PATCH 01/11] AstariaV1Pricing tests, coverage, and cleanup, new snapshot --- .gas-snapshot | 69 +++--- src/pricing/AstariaV1Pricing.sol | 28 +-- src/pricing/Pricing.sol | 2 +- test/AstariaV1Test.sol | 2 +- test/StarportTest.sol | 2 +- test/unit-testing/TestV1Pricing.sol | 342 ++++++++++++++++++++++++++++ test/utils/DeepEq.sol | 13 ++ 7 files changed, 410 insertions(+), 48 deletions(-) create mode 100644 test/unit-testing/TestV1Pricing.sol diff --git a/.gas-snapshot b/.gas-snapshot index 9fb49d2b..aed653dd 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,5 +1,5 @@ -DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880420, ~: 883377) -DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232899, ~: 237832) +DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880390, ~: 883335) +DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232905, ~: 237832) IntegrationTestCaveats:testOriginateUnapprovedFulfiller() (gas: 341293) IntegrationTestCaveats:testOriginateWBorrowerApproval() (gas: 298091) IntegrationTestCaveats:testOriginateWCaveats() (gas: 272268) @@ -15,9 +15,16 @@ IntegrationTestCaveats:testRefinanceWCaveatsInvalidSalt() (gas: 381151) IntegrationTestCaveats:testRefinanceWLenderApproval() (gas: 405713) PausableNonReentrantImpl:test() (gas: 2442) PausableNonReentrantImpl:testReentrancy() (gas: 2735) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1024388) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1023396) TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 708447) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 747164) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 747230) +TestAstariaV1Pricing:testGetRefiannceConsiderationValidEqualRate() (gas: 146499) +TestAstariaV1Pricing:testGetRefiannceConsiderationValidHigherRate() (gas: 158898) +TestAstariaV1Pricing:testGetRefiannceConsiderationValidLowerRate() (gas: 153927) +TestAstariaV1Pricing:testGetRefinanceConsiderationAsBorrowerZeroRate() (gas: 81159) +TestAstariaV1Pricing:testGetRefinanceConsiderationInsufficientRefinance() (gas: 108392) +TestAstariaV1Pricing:testGetRefinanceConsiderationInvalidRefinance() (gas: 88455) +TestAstariaV1Pricing:testGetRefinanceConsiderationZeroRate() (gas: 139117) TestAstariaV1Settlement:testGetAuctionStart() (gas: 433653) TestAstariaV1Settlement:testGetAuctionStartNotStarted() (gas: 433226) TestAstariaV1Settlement:testGetCurrentAuctionPrice() (gas: 448508) @@ -28,16 +35,16 @@ TestAstariaV1Settlement:testGetSettlementLoanNotRecalled() (gas: 439333) TestAstariaV1Settlement:testV1SettlementHandlerExecute() (gas: 419840) TestAstariaV1Settlement:testV1SettlementHandlerValidate() (gas: 419952) TestAstariaV1Settlement:testV1SettlementHandlerValidateInvalidHandler() (gas: 420076) -TestAstariaV1Status:testCannotRecallTwice() (gas: 580716) +TestAstariaV1Status:testCannotRecallTwice() (gas: 580760) TestAstariaV1Status:testCannotWithdrawLoanHasNotBeenRefinanced() (gas: 425689) TestAstariaV1Status:testCannotWithdrawWithdrawDoesNotExist() (gas: 432118) -TestAstariaV1Status:testGenerateRecallConsideration() (gas: 481554) -TestAstariaV1Status:testInvalidRecallInvalidStakeType() (gas: 507879) -TestAstariaV1Status:testInvalidRecallLoanDoesNotExist() (gas: 523886) +TestAstariaV1Status:testGenerateRecallConsideration() (gas: 481620) +TestAstariaV1Status:testInvalidRecallInvalidStakeType() (gas: 507923) +TestAstariaV1Status:testInvalidRecallLoanDoesNotExist() (gas: 523908) TestAstariaV1Status:testIsActive() (gas: 432838) -TestAstariaV1Status:testIsRecalledInsideWindow() (gas: 571509) -TestAstariaV1Status:testIsRecalledOutsideWindow() (gas: 569410) -TestAstariaV1Status:testRecallRateActiveRecall() (gas: 557048) +TestAstariaV1Status:testIsRecalledInsideWindow() (gas: 571531) +TestAstariaV1Status:testIsRecalledOutsideWindow() (gas: 569432) +TestAstariaV1Status:testRecallRateActiveRecall() (gas: 557070) TestAstariaV1Status:testRecallRateEmptyRecall() (gas: 430492) TestBorrowerEnforcer:testBERevertAdditionalTransfers() (gas: 73195) TestBorrowerEnforcer:testBERevertInvalidLoanTerms() (gas: 78316) @@ -53,11 +60,11 @@ TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 72489) TestCustodian:testCustodySelector() (gas: 2728398) TestCustodian:testDefaultCustodySelectorRevert() (gas: 70083) TestCustodian:testGenerateOrderInvalidHandlerExecution() (gas: 133050) -TestCustodian:testGenerateOrderRepay() (gas: 171915) -TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 197518) -TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 833690) +TestCustodian:testGenerateOrderRepay() (gas: 171937) +TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 197540) +TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 833734) TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 757868) -TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 516666) +TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 516688) TestCustodian:testGenerateOrderRepayInvalidHookAddress() (gas: 90335) TestCustodian:testGenerateOrderRepayInvalidHookReturnType() (gas: 84652) TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 96426) @@ -75,11 +82,11 @@ TestCustodian:testNonPayableFunctions() (gas: 225792) TestCustodian:testOnlySeaport() (gas: 17895) TestCustodian:testPayableFunctions() (gas: 41667) TestCustodian:testPreviewOrderNoActiveLoan() (gas: 98786) -TestCustodian:testPreviewOrderRepay() (gas: 227648) +TestCustodian:testPreviewOrderRepay() (gas: 227692) TestCustodian:testPreviewOrderSettlement() (gas: 178524) TestCustodian:testPreviewOrderSettlementInvalidFufliller() (gas: 100823) TestCustodian:testPreviewOrderSettlementInvalidRepayer() (gas: 106856) -TestCustodian:testRatifyOrder() (gas: 178410) +TestCustodian:testRatifyOrder() (gas: 178432) TestCustodian:testSeaportMetadata() (gas: 8567) TestCustodian:testSetRepayApproval() (gas: 37861) TestCustodian:testSupportsInterface() (gas: 9450) @@ -91,33 +98,33 @@ TestLenderEnforcer:testLERevertInvalidLoanTerms() (gas: 78341) TestLenderEnforcer:testLEValidLoanTerms() (gas: 69496) TestLenderEnforcer:testLEValidLoanTermsAnyBorrower() (gas: 69494) TestLenderEnforcer:testLEValidLoanTermsWithAdditionalTransfers() (gas: 70740) -TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 537008) -TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 524637) -TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 554832) -TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 544574) -TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 550050) +TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 537052) +TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 524681) +TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 554876) +TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 544618) +TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 550094) TestNewLoan:testBuyNowPayLater() (gas: 2832923) TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 394541) TestNewLoan:testNewLoanERC721CollateralLessDebtThanOffered() (gas: 2348) TestNewLoan:testNewLoanRefinanceNew() (gas: 207) TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 305741) TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 358465) -TestNewLoan:testSettleLoan() (gas: 608050) +TestNewLoan:testSettleLoan() (gas: 608094) TestPausableNonReentrant:testNotOwner() (gas: 21254) TestPausableNonReentrant:testPauseAndUnpause() (gas: 22555) TestPausableNonReentrant:testReentrancy() (gas: 15360) TestPausableNonReentrant:testUnpauseWhenNotPaused() (gas: 12582) TestRefStarportLib:testSpentToReceived() (gas: 13315) TestRefStarportLib:testValidateSalt(address,bytes32) (runs: 256, μ: 33865, ~: 33865) -TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 629456) -TestRepayLoan:testRepayLoanBase() (gas: 565750) +TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 629500) +TestRepayLoan:testRepayLoanBase() (gas: 565794) TestRepayLoan:testRepayLoanGenerateOrderNotSeaport() (gas: 402462) -TestRepayLoan:testRepayLoanInSettlement() (gas: 550056) -TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 564465) -TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 837042) -TestSimpleInterestPricing:test_calculateInterest() (gas: 808192) -TestSimpleInterestPricing:test_getPaymentConsideration() (gas: 889476) -TestSimpleInterestPricing:test_getRefinanceConsideration() (gas: 883676) +TestRepayLoan:testRepayLoanInSettlement() (gas: 550078) +TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 564487) +TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 837152) +TestSimpleInterestPricing:test_calculateInterest() (gas: 800891) +TestSimpleInterestPricing:test_getPaymentConsideration() (gas: 882219) +TestSimpleInterestPricing:test_getRefinanceConsideration() (gas: 876412) TestStarport:testActive() (gas: 67100) TestStarport:testAdditionalTransfers() (gas: 295920) TestStarport:testCannotIssueSameLoanTwice() (gas: 336999) diff --git a/src/pricing/AstariaV1Pricing.sol b/src/pricing/AstariaV1Pricing.sol index 3df5369e..064ca5aa 100644 --- a/src/pricing/AstariaV1Pricing.sol +++ b/src/pricing/AstariaV1Pricing.sol @@ -12,6 +12,7 @@ import {BaseRecall} from "starport-core/status/BaseRecall.sol"; import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; import {StarportLib} from "starport-core/lib/StarportLib.sol"; import {AdditionalTransfer} from "starport-core/lib/StarportLib.sol"; +import "forge-std/console.sol"; contract AstariaV1Pricing is CompoundInterestPricing { using FixedPointMathLib for uint256; @@ -21,7 +22,7 @@ contract AstariaV1Pricing is CompoundInterestPricing { error InsufficientRefinance(); - function getRefinanceConsideration(Starport.Loan memory loan, bytes memory newPricingData, address fulfiller) + function getRefinanceConsideration(Starport.Loan memory loan, bytes calldata newPricingData, address fulfiller) external view virtual @@ -35,19 +36,18 @@ contract AstariaV1Pricing is CompoundInterestPricing { // borrowers can refinance a loan at any time if (fulfiller != loan.borrower) { // check if a recall is occuring - AstariaV1Status hook = AstariaV1Status(loan.terms.status); - Details memory newDetails = abi.decode(newPricingData, (Details)); - if (hook.isRecalled(loan)) { - uint256 rate = hook.getRecallRate(loan); - // offered loan did not meet the terms of the recall auction - if (newDetails.rate > rate) { - revert InsufficientRefinance(); - } - } - // recall is not occuring - else { + AstariaV1Status status = AstariaV1Status(loan.terms.status); + + if (!status.isRecalled(loan)) { revert InvalidRefinance(); } + Details memory newDetails = abi.decode(newPricingData, (Details)); + uint256 rate = status.getRecallRate(loan); + // offered loan did not meet the terms of the recall auction + if (newDetails.rate > rate) { + revert InsufficientRefinance(); + } + Details memory oldDetails = abi.decode(loan.terms.pricingData, (Details)); uint256 proportion; @@ -57,14 +57,14 @@ contract AstariaV1Pricing is CompoundInterestPricing { // recaller stake is refunded if (newDetails.rate > oldDetails.rate) { proportion = 1e18; - (receiver,) = hook.recalls(loanId); + (receiver,) = status.recalls(loanId); } else { // scenario where the recaller is penalized // essentially the old lender and the new lender split the stake of the recaller // split is proportional to the difference in rate proportion = 1e18 - (oldDetails.rate - newDetails.rate).divWad(oldDetails.rate); } - recallConsideration = hook.generateRecallConsideration(loan, proportion, fulfiller, receiver); + recallConsideration = status.generateRecallConsideration(loan, proportion, fulfiller, receiver); } (repayConsideration, carryConsideration) = getPaymentConsideration(loan); diff --git a/src/pricing/Pricing.sol b/src/pricing/Pricing.sol index 5e4391f6..392ad229 100644 --- a/src/pricing/Pricing.sol +++ b/src/pricing/Pricing.sol @@ -25,7 +25,7 @@ import {SpentItem} from "seaport-types/src/lib/ConsiderationStructs.sol"; import {AdditionalTransfer} from "starport-core/lib/StarportLib.sol"; abstract contract Pricing { - Starport SP; + Starport public immutable SP; error InvalidRefinance(); diff --git a/test/AstariaV1Test.sol b/test/AstariaV1Test.sol index e63cddf6..b2e9a6e9 100644 --- a/test/AstariaV1Test.sol +++ b/test/AstariaV1Test.sol @@ -20,7 +20,7 @@ import {CaveatEnforcer} from "starport-core/enforcers/CaveatEnforcer.sol"; contract AstariaV1Test is StarportTest { Account recaller; - function setUp() public override { + function setUp() public virtual override { super.setUp(); recaller = makeAndAllocateAccount("recaller"); diff --git a/test/StarportTest.sol b/test/StarportTest.sol index 07f233bf..edfa5df9 100644 --- a/test/StarportTest.sol +++ b/test/StarportTest.sol @@ -470,7 +470,7 @@ contract StarportTest is BaseOrderTest { return newLoan(loan, bytes32(msg.sig), bytes32(msg.sig), borrower.addr); } - function generateDefaultLoanTerms() public view returns (Starport.Loan memory) { + function generateDefaultLoanTerms() public view virtual returns (Starport.Loan memory) { SpentItem[] memory newCollateral = new SpentItem[](1); newCollateral[0] = SpentItem({itemType: ItemType.ERC721, token: address(erc721s[0]), identifier: 1, amount: 1}); SpentItem[] memory newDebt = new SpentItem[](1); diff --git a/test/unit-testing/TestV1Pricing.sol b/test/unit-testing/TestV1Pricing.sol new file mode 100644 index 00000000..4204c7ed --- /dev/null +++ b/test/unit-testing/TestV1Pricing.sol @@ -0,0 +1,342 @@ +pragma solidity ^0.8.17; + +import "starport-test/AstariaV1Test.sol"; +import {StarportLib, Actions} from "starport-core/lib/StarportLib.sol"; +import {DeepEq} from "starport-test/utils/DeepEq.sol"; +import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; +import {SpentItemLib} from "seaport-sol/src/lib/SpentItemLib.sol"; +import {Originator} from "starport-core/originators/Originator.sol"; +import {CaveatEnforcer} from "starport-core/enforcers/CaveatEnforcer.sol"; +import "forge-std/console2.sol"; + +contract TestAstariaV1Pricing is AstariaV1Test, DeepEq { + using Cast for *; + using FixedPointMathLib for uint256; + using stdStorage for StdStorage; + using {StarportLib.getId} for Starport.Loan; + + function setUp() public override { + super.setUp(); + defaultPricingData = abi.encode(BasePricing.Details({carryRate: 0, rate: uint256(1e16) / (365 * 1 days)})); + pricing = new AstariaV1Pricing(SP); + } + + function testGetRefinanceConsiderationInvalidRefinance() public { + Starport.Loan memory loan = generateDefaultLoanTerms(); + + loan.start = uint256(1); + loan.originator = address(this); + vm.warp(2); + + BasePricing.Details memory baseDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); + BaseRecall.Details memory statusDetails = abi.decode(loan.terms.statusData, (BaseRecall.Details)); + bytes memory newPricingData = abi.encode(BasePricing.Details({carryRate: 0, rate: 0})); + + vm.expectRevert(abi.encodeWithSelector(Pricing.InvalidRefinance.selector)); + Pricing(loan.terms.pricing).getRefinanceConsideration(loan, newPricingData, address(this)); + } + + function testGetRefinanceConsiderationInsufficientRefinance() public { + Starport.Loan memory loan = generateDefaultLoanTerms(); + + loan.start = uint256(1); + loan.originator = address(this); + vm.warp(2); + + BasePricing.Details memory baseDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); + BaseRecall.Details memory statusDetails = abi.decode(loan.terms.statusData, (BaseRecall.Details)); + + //we're lower than the old rate so pay proportions + uint256 proportion = 1e18; + vm.mockCall( + loan.terms.status, abi.encodeWithSelector(AstariaV1Status.isRecalled.selector, loan), abi.encode(true) + ); + uint256 recallRate = AstariaV1Status(loan.terms.status).getRecallRate(loan); + bytes memory newPricingData = abi.encode(BasePricing.Details({carryRate: 0, rate: recallRate * 2})); + + vm.expectRevert(abi.encodeWithSelector(AstariaV1Pricing.InsufficientRefinance.selector)); + Pricing(loan.terms.pricing).getRefinanceConsideration(loan, newPricingData, address(this)); + } + + function testGetRefinanceConsiderationAsBorrowerZeroRate() public { + Starport.Loan memory loan = generateDefaultLoanTerms(); + loan.start = uint256(1); + loan.originator = address(this); + vm.warp(2); + BasePricing.Details memory baseDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); + bytes memory newPricingData = abi.encode(BasePricing.Details({carryRate: 0, rate: 0})); + SpentItem[] memory expectedConsideration = new SpentItem[](1); + expectedConsideration[0] = SpentItem({ + itemType: loan.debt[0].itemType, + amount: loan.debt[0].amount + + StarportLib.calculateCompoundInterest(block.timestamp - loan.start, loan.debt[0].amount, baseDetails.rate), + identifier: loan.debt[0].identifier, + token: loan.debt[0].token + }); + SpentItem[] memory expectedCarryConsideration = new SpentItem[](0); + AdditionalTransfer[] memory expectedAdditionalTransfers = new AdditionalTransfer[](0); + + ( + SpentItem[] memory consideration, + SpentItem[] memory carryConsideration, + AdditionalTransfer[] memory additionalTransfers + ) = Pricing(loan.terms.pricing).getRefinanceConsideration(loan, newPricingData, address(loan.borrower)); + _deepEq(consideration, expectedConsideration); + _deepEq(carryConsideration, expectedCarryConsideration); + _deepEq(expectedAdditionalTransfers, additionalTransfers); + } + + //TODO: is 0 rate allowed? + function testGetRefinanceConsiderationZeroRate() public { + Starport.Loan memory loan = generateDefaultLoanTerms(); + loan.start = uint256(1); + loan.originator = address(this); + vm.warp(2); + BasePricing.Details memory baseDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); + bytes memory newPricingData = abi.encode(BasePricing.Details({carryRate: 0, rate: 0})); + BaseRecall.Details memory statusDetails = abi.decode(loan.terms.statusData, (BaseRecall.Details)); + uint256 proportion = 1e18 - (baseDetails.rate - 0).divWad(baseDetails.rate); + vm.mockCall( + loan.terms.status, abi.encodeWithSelector(AstariaV1Status.isRecalled.selector, loan), abi.encode(true) + ); + SpentItem[] memory expectedConsideration = new SpentItem[](1); + expectedConsideration[0] = SpentItem({ + itemType: loan.debt[0].itemType, + amount: loan.debt[0].amount + + StarportLib.calculateCompoundInterest(block.timestamp - loan.start, loan.debt[0].amount, baseDetails.rate), + identifier: loan.debt[0].identifier, + token: loan.debt[0].token + }); + SpentItem[] memory expectedCarryConsideration = new SpentItem[](0); + AdditionalTransfer[] memory expectedAdditionalTransfers = new AdditionalTransfer[](1); + expectedAdditionalTransfers[0] = AdditionalTransfer({ + identifier: loan.debt[0].identifier, + itemType: loan.debt[0].itemType, + token: loan.debt[0].token, + amount: StarportLib.calculateCompoundInterest( + statusDetails.recallStakeDuration, loan.debt[0].amount, baseDetails.rate + ).mulWad(proportion), + to: loan.issuer, + from: address(this) + }); + + ( + SpentItem[] memory consideration, + SpentItem[] memory carryConsideration, + AdditionalTransfer[] memory additionalTransfers + ) = Pricing(loan.terms.pricing).getRefinanceConsideration(loan, newPricingData, address(this)); + _deepEq(consideration, expectedConsideration); + _deepEq(carryConsideration, expectedCarryConsideration); + _deepEq(expectedAdditionalTransfers, additionalTransfers); + } + + function testGetRefiannceConsiderationValidEqualRate() public { + Starport.Loan memory loan = generateDefaultLoanTerms(); + + loan.start = uint256(1); + loan.originator = address(this); + vm.warp(2); + + BasePricing.Details memory baseDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); + BaseRecall.Details memory statusDetails = abi.decode(loan.terms.statusData, (BaseRecall.Details)); + + vm.mockCall( + loan.terms.status, abi.encodeWithSelector(AstariaV1Status.isRecalled.selector, loan), abi.encode(true) + ); + skip(statusDetails.recallWindow - 10); + bytes memory newPricingData = abi.encode(BasePricing.Details({carryRate: 0, rate: baseDetails.rate})); + uint256 proportion = 1e18 - (baseDetails.rate - baseDetails.rate).divWad(baseDetails.rate); + + SpentItem[] memory expectedConsideration = new SpentItem[](1); + expectedConsideration[0] = SpentItem({ + itemType: loan.debt[0].itemType, + amount: loan.debt[0].amount + + StarportLib.calculateCompoundInterest(block.timestamp - loan.start, loan.debt[0].amount, baseDetails.rate), + identifier: loan.debt[0].identifier, + token: loan.debt[0].token + }); + SpentItem[] memory expectedCarryConsideration = new SpentItem[](0); + AdditionalTransfer[] memory expectedAdditionalTransfers = new AdditionalTransfer[](1); + expectedAdditionalTransfers[0] = AdditionalTransfer({ + identifier: loan.debt[0].identifier, + itemType: loan.debt[0].itemType, + token: loan.debt[0].token, + amount: StarportLib.calculateCompoundInterest( + statusDetails.recallStakeDuration, loan.debt[0].amount, baseDetails.rate + ).mulWad(proportion), + to: loan.issuer, + from: address(this) + }); + + vm.mockCall( + loan.terms.status, + abi.encodeWithSelector(bytes4(keccak256("recalls(uint256)")), loan.getId()), + abi.encode(recaller.addr, uint256(0)) + ); + ( + SpentItem[] memory consideration, + SpentItem[] memory carryConsideration, + AdditionalTransfer[] memory additionalTransfers + ) = Pricing(loan.terms.pricing).getRefinanceConsideration(loan, newPricingData, address(this)); + _deepEq(consideration, expectedConsideration); + _deepEq(carryConsideration, expectedCarryConsideration); + _deepEq(expectedAdditionalTransfers, additionalTransfers); + } + + function testGetRefiannceConsiderationValidHigherRate() public { + Starport.Loan memory loan = generateDefaultLoanTerms(); + + loan.start = uint256(1); + loan.originator = address(this); + vm.warp(2); + + BasePricing.Details memory baseDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); + BaseRecall.Details memory statusDetails = abi.decode(loan.terms.statusData, (BaseRecall.Details)); + + //we're lower than the old rate so pay proportions + uint256 proportion = 1e18; + vm.mockCall( + loan.terms.status, abi.encodeWithSelector(AstariaV1Status.isRecalled.selector, loan), abi.encode(true) + ); + skip(statusDetails.recallWindow - 10); + uint256 recallRate = AstariaV1Status(loan.terms.status).getRecallRate(loan); + bytes memory newPricingData = abi.encode(BasePricing.Details({carryRate: 0, rate: recallRate})); + + SpentItem[] memory expectedConsideration = new SpentItem[](1); + expectedConsideration[0] = SpentItem({ + itemType: loan.debt[0].itemType, + amount: loan.debt[0].amount + + StarportLib.calculateCompoundInterest(block.timestamp - loan.start, loan.debt[0].amount, baseDetails.rate), + identifier: loan.debt[0].identifier, + token: loan.debt[0].token + }); + SpentItem[] memory expectedCarryConsideration = new SpentItem[](0); + AdditionalTransfer[] memory expectedAdditionalTransfers = new AdditionalTransfer[](1); + expectedAdditionalTransfers[0] = AdditionalTransfer({ + identifier: loan.debt[0].identifier, + itemType: loan.debt[0].itemType, + token: loan.debt[0].token, + amount: StarportLib.calculateCompoundInterest( + statusDetails.recallStakeDuration, loan.debt[0].amount, baseDetails.rate + ).mulWad(proportion), + to: recaller.addr, + from: address(this) + }); + + vm.mockCall( + loan.terms.status, + abi.encodeWithSelector(bytes4(keccak256("recalls(uint256)")), loan.getId()), + abi.encode(recaller.addr, uint256(0)) + ); + ( + SpentItem[] memory consideration, + SpentItem[] memory carryConsideration, + AdditionalTransfer[] memory additionalTransfers + ) = Pricing(loan.terms.pricing).getRefinanceConsideration(loan, newPricingData, address(this)); + _deepEq(consideration, expectedConsideration); + _deepEq(carryConsideration, expectedCarryConsideration); + _deepEq(expectedAdditionalTransfers, additionalTransfers); + } + + function testGetRefiannceConsiderationValidLowerRate() public { + Starport.Loan memory loan = generateDefaultLoanTerms(); + + loan.start = uint256(1); + loan.originator = address(this); + vm.warp(2); + uint256 recallRate = AstariaV1Status(loan.terms.status).getRecallRate(loan); + + BasePricing.Details memory baseDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); + BaseRecall.Details memory statusDetails = abi.decode(loan.terms.statusData, (BaseRecall.Details)); + bytes memory newPricingData = abi.encode(BasePricing.Details({carryRate: 0, rate: recallRate})); + + //we're lower than the old rate so pay proportions + uint256 proportion = 1e18 - (baseDetails.rate - recallRate).divWad(baseDetails.rate); + vm.mockCall( + loan.terms.status, abi.encodeWithSelector(AstariaV1Status.isRecalled.selector, loan), abi.encode(true) + ); + SpentItem[] memory expectedConsideration = new SpentItem[](1); + expectedConsideration[0] = SpentItem({ + itemType: loan.debt[0].itemType, + amount: loan.debt[0].amount + + StarportLib.calculateCompoundInterest(block.timestamp - loan.start, loan.debt[0].amount, baseDetails.rate), + identifier: loan.debt[0].identifier, + token: loan.debt[0].token + }); + SpentItem[] memory expectedCarryConsideration = new SpentItem[](0); + AdditionalTransfer[] memory expectedAdditionalTransfers = new AdditionalTransfer[](1); + expectedAdditionalTransfers[0] = AdditionalTransfer({ + identifier: loan.debt[0].identifier, + itemType: loan.debt[0].itemType, + token: loan.debt[0].token, + amount: StarportLib.calculateCompoundInterest( + statusDetails.recallStakeDuration, loan.debt[0].amount, baseDetails.rate + ).mulWad(proportion), + to: loan.issuer, + from: address(this) + }); + + ( + SpentItem[] memory consideration, + SpentItem[] memory carryConsideration, + AdditionalTransfer[] memory additionalTransfers + ) = Pricing(loan.terms.pricing).getRefinanceConsideration(loan, newPricingData, address(this)); + _deepEq(consideration, expectedConsideration); + _deepEq(carryConsideration, expectedCarryConsideration); + _deepEq(expectedAdditionalTransfers, additionalTransfers); + } + + event log_additional_transfers(AdditionalTransfer[] transfers); + event log_spent_items(SpentItem[] items); + + // function testGetRefiannceConsiderationValidHigherRate() public { + // Starport.Loan memory loan = generateDefaultLoanTerms(); + // + // loan.start = uint256(1); + // loan.originator = address(this); + // vm.warp(2); + // + // uint256 recallRate = AstariaV1Status(loan.terms.status).getRecallRate(loan); + // + // BasePricing.Details memory baseDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); + // BaseRecall.Details memory statusDetails = abi.decode(loan.terms.statusData, (BaseRecall.Details)); + // + // statusDetails.recallMax + // + // bytes memory newPricingData = abi.encode(BasePricing.Details({carryRate: 0, rate: recallRate})); + // + // uint256 proportion = 1e18; + // vm.mockCall( + // loan.terms.status, abi.encodeWithSelector(AstariaV1Status.isRecalled.selector, loan), abi.encode(true) + // ); + // SpentItem[] memory expectedConsideration = new SpentItem[](1); + // expectedConsideration[0] = SpentItem({ + // itemType: loan.debt[0].itemType, + // amount: loan.debt[0].amount + // + StarportLib.calculateCompoundInterest(block.timestamp - loan.start, loan.debt[0].amount, baseDetails.rate), + // identifier: loan.debt[0].identifier, + // token: loan.debt[0].token + // }); + // SpentItem[] memory expectedCarryConsideration = new SpentItem[](0); + // AdditionalTransfer[] memory expectedAdditionalTransfers = new AdditionalTransfer[](1); + // expectedAdditionalTransfers[0] = AdditionalTransfer({ + // identifier: loan.debt[0].identifier, + // itemType: loan.debt[0].itemType, + // token: loan.debt[0].token, + // amount: StarportLib.calculateCompoundInterest( + // statusDetails.recallStakeDuration, loan.debt[0].amount, baseDetails.rate + // ).mulWad(proportion), + // to: loan.issuer, + // from: address(this) + // }); + // + // ( + // SpentItem[] memory consideration, + // SpentItem[] memory carryConsideration, + // AdditionalTransfer[] memory additionalTransfers + // ) = Pricing(loan.terms.pricing).getRefinanceConsideration(loan, newPricingData, address(this)); + // _deepEq(consideration, expectedConsideration); + // _deepEq(carryConsideration, expectedCarryConsideration); + // _deepEq(expectedAdditionalTransfers, additionalTransfers); + // } +} diff --git a/test/utils/DeepEq.sol b/test/utils/DeepEq.sol index 959ffe5c..189efc2c 100644 --- a/test/utils/DeepEq.sol +++ b/test/utils/DeepEq.sol @@ -1,4 +1,5 @@ import {ItemType, SpentItem, ReceivedItem} from "seaport-types/src/lib/ConsiderationStructs.sol"; +import {AdditionalTransfer} from "starport-core/lib/StarportLib.sol"; import {Cast} from "starport-test/utils/Cast.sol"; import "starport-test/utils/FuzzStructs.sol" as Fuzz; import "forge-std/Test.sol"; @@ -24,4 +25,16 @@ abstract contract DeepEq { assert(a[i].amount == b[i].amount); } } + + function _deepEq(AdditionalTransfer[] memory a, AdditionalTransfer[] memory b) internal pure { + assert(a.length == b.length); + for (uint256 i = 0; i < a.length; i++) { + assert(a[i].itemType == b[i].itemType); + assert(a[i].token == b[i].token); + assert(a[i].identifier == b[i].identifier); + assert(a[i].amount == b[i].amount); + assert(a[i].from == b[i].from); + assert(a[i].to == b[i].to); + } + } } From b3500bb3b78a5a5229f8d86292df94a11e010707 Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 07:54:06 -0300 Subject: [PATCH 02/11] clean up if else to adopt {} braces --- src/pricing/BasePricing.sol | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pricing/BasePricing.sol b/src/pricing/BasePricing.sol index 2f238b3a..6453f11f 100644 --- a/src/pricing/BasePricing.sol +++ b/src/pricing/BasePricing.sol @@ -48,8 +48,11 @@ abstract contract BasePricing is Pricing { returns (SpentItem[] memory repayConsideration, SpentItem[] memory carryConsideration) { Details memory details = abi.decode(loan.terms.pricingData, (Details)); - if (details.carryRate > 0) carryConsideration = new SpentItem[](loan.debt.length); - else carryConsideration = new SpentItem[](0); + if (details.carryRate > 0) { + carryConsideration = new SpentItem[](loan.debt.length); + } else { + carryConsideration = new SpentItem[](0); + } repayConsideration = new SpentItem[](loan.debt.length); uint256 i = 0; From 63d56213b25e4f0a6b84d6b7753a1b6b2e3ff141 Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 08:00:13 -0300 Subject: [PATCH 03/11] remove console imports from core and modules --- src/BNPLHelper.sol | 1 - src/Custodian.sol | 1 - src/enforcers/AstariaV1LenderEnforcer.sol | 1 - src/lib/RefStarportLib.sol | 1 - src/lib/StarportLib.sol | 3 +-- src/pricing/AstariaV1Pricing.sol | 1 - src/pricing/BasePricing.sol | 1 - src/pricing/BaseRecallPricing.sol | 1 - src/settlement/AstariaV1Settlement.sol | 1 - src/status/AstariaV1Status.sol | 1 - src/status/BaseRecall.sol | 2 -- 11 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/BNPLHelper.sol b/src/BNPLHelper.sol index df932cdf..de8467d4 100644 --- a/src/BNPLHelper.sol +++ b/src/BNPLHelper.sol @@ -15,7 +15,6 @@ import {AdditionalTransfer} from "starport-core/lib/StarportLib.sol"; import {Seaport} from "seaport/contracts/Seaport.sol"; import {Starport} from "./Starport.sol"; import {CaveatEnforcer} from "./enforcers/CaveatEnforcer.sol"; -import "forge-std/console.sol"; interface IVault { function flashLoan( diff --git a/src/Custodian.sol b/src/Custodian.sol index 885ec4bd..648758de 100644 --- a/src/Custodian.sol +++ b/src/Custodian.sol @@ -34,7 +34,6 @@ import {Settlement} from "starport-core/settlement/Settlement.sol"; import {Pricing} from "starport-core/pricing/Pricing.sol"; import {Starport} from "starport-core/Starport.sol"; import {StarportLib, Actions} from "starport-core/lib/StarportLib.sol"; -import "forge-std/console2.sol"; contract Custodian is ERC721, ContractOffererInterface { using {StarportLib.getId} for Starport.Loan; diff --git a/src/enforcers/AstariaV1LenderEnforcer.sol b/src/enforcers/AstariaV1LenderEnforcer.sol index f8537db9..de00abe2 100644 --- a/src/enforcers/AstariaV1LenderEnforcer.sol +++ b/src/enforcers/AstariaV1LenderEnforcer.sol @@ -6,7 +6,6 @@ import {Starport} from "starport-core/Starport.sol"; import {BasePricing} from "starport-core/pricing/BasePricing.sol"; import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; import {StarportLib} from "starport-core/lib/StarportLib.sol"; -import "forge-std/console2.sol"; contract AstariaV1LenderEnforcer is LenderEnforcer { using FixedPointMathLib for uint256; diff --git a/src/lib/RefStarportLib.sol b/src/lib/RefStarportLib.sol index 12ea8edf..e4694fbd 100644 --- a/src/lib/RefStarportLib.sol +++ b/src/lib/RefStarportLib.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.17; import {ItemType, ReceivedItem, SpentItem} from "seaport-types/src/lib/ConsiderationStructs.sol"; import {Starport} from "starport-core/Starport.sol"; -import "forge-std/console.sol"; enum Actions { Nothing, diff --git a/src/lib/StarportLib.sol b/src/lib/StarportLib.sol index 36e807ec..66e6634c 100644 --- a/src/lib/StarportLib.sol +++ b/src/lib/StarportLib.sol @@ -2,13 +2,12 @@ pragma solidity ^0.8.17; import {ItemType, ReceivedItem, SpentItem} from "seaport-types/src/lib/ConsiderationStructs.sol"; import {Starport} from "starport-core/Starport.sol"; -import "forge-std/console.sol"; + import {ERC721} from "solady/src/tokens/ERC721.sol"; import {ERC20} from "solady/src/tokens/ERC20.sol"; import {ERC1155} from "solady/src/tokens/ERC1155.sol"; import {SafeTransferLib} from "solady/src/utils/SafeTransferLib.sol"; import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; -import "forge-std/console2.sol"; enum Actions { Nothing, diff --git a/src/pricing/AstariaV1Pricing.sol b/src/pricing/AstariaV1Pricing.sol index 064ca5aa..a1d5c201 100644 --- a/src/pricing/AstariaV1Pricing.sol +++ b/src/pricing/AstariaV1Pricing.sol @@ -12,7 +12,6 @@ import {BaseRecall} from "starport-core/status/BaseRecall.sol"; import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; import {StarportLib} from "starport-core/lib/StarportLib.sol"; import {AdditionalTransfer} from "starport-core/lib/StarportLib.sol"; -import "forge-std/console.sol"; contract AstariaV1Pricing is CompoundInterestPricing { using FixedPointMathLib for uint256; diff --git a/src/pricing/BasePricing.sol b/src/pricing/BasePricing.sol index 6453f11f..f4210b05 100644 --- a/src/pricing/BasePricing.sol +++ b/src/pricing/BasePricing.sol @@ -25,7 +25,6 @@ import {Pricing} from "starport-core/pricing/Pricing.sol"; import {ReceivedItem} from "seaport-types/src/lib/ConsiderationStructs.sol"; import {Status} from "starport-core/status/Status.sol"; import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; -import "forge-std/console2.sol"; import {BaseStatus} from "starport-core/status/BaseStatus.sol"; import {StarportLib} from "starport-core/lib/StarportLib.sol"; diff --git a/src/pricing/BaseRecallPricing.sol b/src/pricing/BaseRecallPricing.sol index 334e842b..7abe6302 100644 --- a/src/pricing/BaseRecallPricing.sol +++ b/src/pricing/BaseRecallPricing.sol @@ -26,7 +26,6 @@ import {ReceivedItem} from "seaport-types/src/lib/ConsiderationStructs.sol"; import {SpentItem} from "seaport-types/src/lib/ConsiderationStructs.sol"; import {Status} from "starport-core/status/Status.sol"; import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; -import "forge-std/console2.sol"; import {BaseStatus} from "starport-core/status/BaseStatus.sol"; import {StarportLib} from "starport-core/lib/StarportLib.sol"; diff --git a/src/settlement/AstariaV1Settlement.sol b/src/settlement/AstariaV1Settlement.sol index 09f845b1..e3b59107 100644 --- a/src/settlement/AstariaV1Settlement.sol +++ b/src/settlement/AstariaV1Settlement.sol @@ -9,7 +9,6 @@ import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; import {Pricing} from "starport-core/pricing/Pricing.sol"; import {BasePricing} from "starport-core/pricing/BasePricing.sol"; -import "forge-std/console2.sol"; contract AstariaV1Settlement is DutchAuctionSettlement { using {StarportLib.getId} for Starport.Loan; diff --git a/src/status/AstariaV1Status.sol b/src/status/AstariaV1Status.sol index 0930a56f..2d40ce8b 100644 --- a/src/status/AstariaV1Status.sol +++ b/src/status/AstariaV1Status.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.17; import {Starport} from "starport-core/Starport.sol"; import {BaseRecall} from "starport-core/status/BaseRecall.sol"; -import "forge-std/console2.sol"; import {BaseStatus} from "starport-core/status/BaseStatus.sol"; import {StarportLib} from "starport-core/lib/StarportLib.sol"; diff --git a/src/status/BaseRecall.sol b/src/status/BaseRecall.sol index 6482d6ff..d9cdc75d 100644 --- a/src/status/BaseRecall.sol +++ b/src/status/BaseRecall.sol @@ -20,8 +20,6 @@ */ pragma solidity ^0.8.17; -import "forge-std/console2.sol"; - import {Starport} from "starport-core/Starport.sol"; import {Status} from "starport-core/status/Status.sol"; import {ERC20} from "solady/src/tokens/ERC20.sol"; From 9a4eea40fb08ecb630775b99268a73cde2e6630e Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 08:01:22 -0300 Subject: [PATCH 04/11] newest snapshot --- .gas-snapshot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index aed653dd..f79cea92 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,5 +1,5 @@ -DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880390, ~: 883335) -DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232905, ~: 237832) +DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880466, ~: 882693) +DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232918, ~: 237832) IntegrationTestCaveats:testOriginateUnapprovedFulfiller() (gas: 341293) IntegrationTestCaveats:testOriginateWBorrowerApproval() (gas: 298091) IntegrationTestCaveats:testOriginateWCaveats() (gas: 272268) From b45a20218137005844c4f8b776f6d5263a6ea6dd Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 09:00:28 -0300 Subject: [PATCH 05/11] always execute settlement flow even on repayments --- .gas-snapshot | 79 +++++++++---------- src/Custodian.sol | 24 ++++-- src/settlement/AstariaV1Settlement.sol | 9 ++- src/settlement/EnglishAuctionSettlement.sol | 3 +- src/status/BaseRecall.sol | 15 ++-- test/AstariaV1Test.sol | 4 +- test/StarportTest.sol | 6 +- .../integration-testing/TestAstariaV1Loan.sol | 54 ++++++++----- test/integration-testing/TestNewLoan.sol | 2 +- test/integration-testing/TestRepayLoan.sol | 12 +-- test/unit-testing/TestPricing.sol | 2 +- test/unit-testing/TestV1Settlement.sol | 48 +++++------ test/unit-testing/TestV1Status.sol | 22 +++--- 13 files changed, 152 insertions(+), 128 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index f79cea92..d963ac6b 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,5 +1,5 @@ -DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880466, ~: 882693) -DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232918, ~: 237832) +DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880486, ~: 882492) +DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232911, ~: 237832) IntegrationTestCaveats:testOriginateUnapprovedFulfiller() (gas: 341293) IntegrationTestCaveats:testOriginateWBorrowerApproval() (gas: 298091) IntegrationTestCaveats:testOriginateWCaveats() (gas: 272268) @@ -15,37 +15,36 @@ IntegrationTestCaveats:testRefinanceWCaveatsInvalidSalt() (gas: 381151) IntegrationTestCaveats:testRefinanceWLenderApproval() (gas: 405713) PausableNonReentrantImpl:test() (gas: 2442) PausableNonReentrantImpl:testReentrancy() (gas: 2735) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1023396) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 708447) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 747230) -TestAstariaV1Pricing:testGetRefiannceConsiderationValidEqualRate() (gas: 146499) -TestAstariaV1Pricing:testGetRefiannceConsiderationValidHigherRate() (gas: 158898) -TestAstariaV1Pricing:testGetRefiannceConsiderationValidLowerRate() (gas: 153927) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1021044) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 727567) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 1404892) +TestAstariaV1Pricing:testGetRefiannceConsiderationValidEqualRate() (gas: 146135) +TestAstariaV1Pricing:testGetRefiannceConsiderationValidHigherRate() (gas: 158343) +TestAstariaV1Pricing:testGetRefiannceConsiderationValidLowerRate() (gas: 153372) TestAstariaV1Pricing:testGetRefinanceConsiderationAsBorrowerZeroRate() (gas: 81159) -TestAstariaV1Pricing:testGetRefinanceConsiderationInsufficientRefinance() (gas: 108392) -TestAstariaV1Pricing:testGetRefinanceConsiderationInvalidRefinance() (gas: 88455) -TestAstariaV1Pricing:testGetRefinanceConsiderationZeroRate() (gas: 139117) -TestAstariaV1Settlement:testGetAuctionStart() (gas: 433653) -TestAstariaV1Settlement:testGetAuctionStartNotStarted() (gas: 433226) -TestAstariaV1Settlement:testGetCurrentAuctionPrice() (gas: 448508) -TestAstariaV1Settlement:testGetCurrentAuctionPriceNoAuction() (gas: 436857) -TestAstariaV1Settlement:testGetSettlementDutchAuctionSettlementAbove() (gas: 490478) -TestAstariaV1Settlement:testGetSettlementFailedDutchAuction() (gas: 448831) -TestAstariaV1Settlement:testGetSettlementLoanNotRecalled() (gas: 439333) -TestAstariaV1Settlement:testV1SettlementHandlerExecute() (gas: 419840) -TestAstariaV1Settlement:testV1SettlementHandlerValidate() (gas: 419952) -TestAstariaV1Settlement:testV1SettlementHandlerValidateInvalidHandler() (gas: 420076) -TestAstariaV1Status:testCannotRecallTwice() (gas: 580760) -TestAstariaV1Status:testCannotWithdrawLoanHasNotBeenRefinanced() (gas: 425689) -TestAstariaV1Status:testCannotWithdrawWithdrawDoesNotExist() (gas: 432118) -TestAstariaV1Status:testGenerateRecallConsideration() (gas: 481620) -TestAstariaV1Status:testInvalidRecallInvalidStakeType() (gas: 507923) -TestAstariaV1Status:testInvalidRecallLoanDoesNotExist() (gas: 523908) -TestAstariaV1Status:testIsActive() (gas: 432838) -TestAstariaV1Status:testIsRecalledInsideWindow() (gas: 571531) -TestAstariaV1Status:testIsRecalledOutsideWindow() (gas: 569432) -TestAstariaV1Status:testRecallRateActiveRecall() (gas: 557070) -TestAstariaV1Status:testRecallRateEmptyRecall() (gas: 430492) +TestAstariaV1Pricing:testGetRefinanceConsiderationInsufficientRefinance() (gas: 108010) +TestAstariaV1Pricing:testGetRefinanceConsiderationInvalidRefinance() (gas: 88264) +TestAstariaV1Pricing:testGetRefinanceConsiderationZeroRate() (gas: 138753) +TestAstariaV1Settlement:testGetAuctionStart() (gas: 433631) +TestAstariaV1Settlement:testGetAuctionStartNotStarted() (gas: 433204) +TestAstariaV1Settlement:testGetCurrentAuctionPrice() (gas: 448460) +TestAstariaV1Settlement:testGetCurrentAuctionPriceNoAuction() (gas: 436835) +TestAstariaV1Settlement:testGetSettlementDutchAuctionSettlementAbove() (gas: 490360) +TestAstariaV1Settlement:testGetSettlementFailedDutchAuction() (gas: 448783) +TestAstariaV1Settlement:testGetSettlementLoanNotRecalled() (gas: 439311) +TestAstariaV1Settlement:testV1SettlementHandlerValidate() (gas: 419948) +TestAstariaV1Settlement:testV1SettlementHandlerValidateInvalidHandler() (gas: 420072) +TestAstariaV1Status:testCannotRecallTwice() (gas: 580032) +TestAstariaV1Status:testCannotWithdrawLoanHasNotBeenRefinanced() (gas: 425604) +TestAstariaV1Status:testCannotWithdrawWithdrawDoesNotExist() (gas: 432033) +TestAstariaV1Status:testGenerateRecallConsideration() (gas: 481274) +TestAstariaV1Status:testInvalidRecallInvalidStakeType() (gas: 507301) +TestAstariaV1Status:testInvalidRecallLoanDoesNotExist() (gas: 523544) +TestAstariaV1Status:testIsActive() (gas: 432647) +TestAstariaV1Status:testIsRecalledInsideWindow() (gas: 570785) +TestAstariaV1Status:testIsRecalledOutsideWindow() (gas: 568686) +TestAstariaV1Status:testRecallRateActiveRecall() (gas: 556515) +TestAstariaV1Status:testRecallRateEmptyRecall() (gas: 430301) TestBorrowerEnforcer:testBERevertAdditionalTransfers() (gas: 73195) TestBorrowerEnforcer:testBERevertInvalidLoanTerms() (gas: 78316) TestBorrowerEnforcer:testBEValidLoanTerms() (gas: 69518) @@ -57,20 +56,20 @@ TestCompoundInterest:testRateTooLowZero() (gas: 68419) TestCustodian:testCannotLazyMintTwice() (gas: 76686) TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 66861) TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 72489) -TestCustodian:testCustodySelector() (gas: 2728398) +TestCustodian:testCustodySelector() (gas: 2719375) TestCustodian:testDefaultCustodySelectorRevert() (gas: 70083) -TestCustodian:testGenerateOrderInvalidHandlerExecution() (gas: 133050) +TestCustodian:testGenerateOrderInvalidHandlerExecution() (gas: 158631) TestCustodian:testGenerateOrderRepay() (gas: 171937) TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 197540) TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 833734) -TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 757868) +TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 757730) TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 516688) TestCustodian:testGenerateOrderRepayInvalidHookAddress() (gas: 90335) TestCustodian:testGenerateOrderRepayInvalidHookReturnType() (gas: 84652) TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 96426) -TestCustodian:testGenerateOrderSettlement() (gas: 146907) -TestCustodian:testGenerateOrderSettlementHandlerAuthorized() (gas: 155902) -TestCustodian:testGenerateOrderSettlementNoActiveLoan() (gas: 155924) +TestCustodian:testGenerateOrderSettlement() (gas: 150387) +TestCustodian:testGenerateOrderSettlementHandlerAuthorized() (gas: 155833) +TestCustodian:testGenerateOrderSettlementNoActiveLoan() (gas: 155836) TestCustodian:testGenerateOrderSettlementUnauthorized() (gas: 94410) TestCustodian:testGenerateOrdersWithLoanStartAtBlockTimestampInvalidLoan() (gas: 453017) TestCustodian:testGetBorrower() (gas: 76234) @@ -83,7 +82,7 @@ TestCustodian:testOnlySeaport() (gas: 17895) TestCustodian:testPayableFunctions() (gas: 41667) TestCustodian:testPreviewOrderNoActiveLoan() (gas: 98786) TestCustodian:testPreviewOrderRepay() (gas: 227692) -TestCustodian:testPreviewOrderSettlement() (gas: 178524) +TestCustodian:testPreviewOrderSettlement() (gas: 182004) TestCustodian:testPreviewOrderSettlementInvalidFufliller() (gas: 100823) TestCustodian:testPreviewOrderSettlementInvalidRepayer() (gas: 106856) TestCustodian:testRatifyOrder() (gas: 178432) @@ -109,7 +108,7 @@ TestNewLoan:testNewLoanERC721CollateralLessDebtThanOffered() (gas: 2348) TestNewLoan:testNewLoanRefinanceNew() (gas: 207) TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 305741) TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 358465) -TestNewLoan:testSettleLoan() (gas: 608094) +TestNewLoan:testSettleLoan() (gas: 611574) TestPausableNonReentrant:testNotOwner() (gas: 21254) TestPausableNonReentrant:testPauseAndUnpause() (gas: 22555) TestPausableNonReentrant:testReentrancy() (gas: 15360) diff --git a/src/Custodian.sol b/src/Custodian.sol index 648758de..f5fa32bd 100644 --- a/src/Custodian.sol +++ b/src/Custodian.sol @@ -222,6 +222,7 @@ contract Custodian is ERC721, ContractOffererInterface { consideration = StarportLib.mergeSpentItemsToReceivedItems(payment, loan.issuer, carry, loan.originator); _settleLoan(loan); + _settlementExecute(loan, fulfiller); } else if (action == Actions.Settlement && !Status(loan.terms.status).isActive(loan)) { address authorized; //add in originator fee @@ -236,18 +237,11 @@ contract Custodian is ERC721, ContractOffererInterface { _setOfferApprovalsWithSeaport(offer); } else if (authorized == loan.terms.settlement || authorized == loan.issuer) { _moveCollateralToAuthorized(loan.collateral, authorized); - _beforeSettlementHandlerHook(loan); - if ( - authorized == loan.terms.settlement - && Settlement(loan.terms.settlement).execute(loan, fulfiller) != Settlement.execute.selector - ) { - revert InvalidHandlerExecution(); - } - _afterSettlementHandlerHook(loan); } else { revert InvalidFulfiller(); } _settleLoan(loan); + _settlementExecute(loan, fulfiller); } else { revert InvalidAction(); } @@ -400,6 +394,20 @@ contract Custodian is ERC721, ContractOffererInterface { } } + /** + * @dev settle the loan with the LoanManager + * + * @param loan The the loan that is settled + * @param fulfiller The address executing seaport + */ + function _settlementExecute(Starport.Loan memory loan, address fulfiller) internal virtual { + _beforeSettlementHandlerHook(loan); + if (Settlement(loan.terms.settlement).execute(loan, fulfiller) != Settlement.execute.selector) { + revert InvalidHandlerExecution(); + } + _afterSettlementHandlerHook(loan); + } + /** * @dev settle the loan with the LoanManager * diff --git a/src/settlement/AstariaV1Settlement.sol b/src/settlement/AstariaV1Settlement.sol index e3b59107..af9eed2d 100644 --- a/src/settlement/AstariaV1Settlement.sol +++ b/src/settlement/AstariaV1Settlement.sol @@ -6,7 +6,6 @@ import {BaseRecall} from "starport-core/status/BaseRecall.sol"; import {DutchAuctionSettlement} from "starport-core/settlement/DutchAuctionSettlement.sol"; import {StarportLib} from "starport-core/lib/StarportLib.sol"; import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; - import {Pricing} from "starport-core/pricing/Pricing.sol"; import {BasePricing} from "starport-core/pricing/BasePricing.sol"; @@ -146,7 +145,13 @@ contract AstariaV1Settlement is DutchAuctionSettlement { } function execute(Starport.Loan calldata loan, address fulfiller) external virtual override returns (bytes4) { - revert ExecuteHandlerNotImplemented(); + // TODO: do we need the commented out code if we dont care about reverts anyways, seems like extra gas + // (address recaller, uint64 recallStart) = BaseRecall(loan.terms.status).recalls(loan.getId()); + // if (recallStart != 0 || recaller != address(0)) { + //we dont wanna revert if theres ever a halt in the underlying call, settlement must complete + loan.terms.status.call(abi.encodeWithSelector(BaseRecall.withdraw.selector, loan, fulfiller)); + // } + return Settlement.execute.selector; } function validate(Starport.Loan calldata loan) external view virtual override returns (bool) { diff --git a/src/settlement/EnglishAuctionSettlement.sol b/src/settlement/EnglishAuctionSettlement.sol index df7806b7..11171743 100644 --- a/src/settlement/EnglishAuctionSettlement.sol +++ b/src/settlement/EnglishAuctionSettlement.sol @@ -25,6 +25,7 @@ import { OrderType } from "seaport-types/src/lib/ConsiderationStructs.sol"; import {Pricing} from "starport-core/pricing/Pricing.sol"; +import {Status} from "starport-core/status/Status.sol"; contract EnglishAuctionSettlement is Settlement { using FixedPointMathLib for uint256; @@ -56,7 +57,7 @@ contract EnglishAuctionSettlement is Settlement { } function execute(Starport.Loan calldata loan, address fulfiller) external virtual override returns (bytes4) { - if (fulfiller != address(this)) { + if (fulfiller != address(this) && !Status(loan.terms.status).isActive(loan)) { revert("must liquidate via the handler to trigger english auction"); } return Settlement.execute.selector; diff --git a/src/status/BaseRecall.sol b/src/status/BaseRecall.sol index d9cdc75d..7261cd91 100644 --- a/src/status/BaseRecall.sol +++ b/src/status/BaseRecall.sol @@ -117,7 +117,7 @@ abstract contract BaseRecall { } // transfers all stake to anyone who asks after the LM token is burned - function withdraw(Starport.Loan calldata loan, address payable receiver) external { + function withdraw(Starport.Loan calldata loan, address receiver) external { Details memory details = abi.decode(loan.terms.statusData, (Details)); bytes memory encodedLoan = abi.encode(loan); uint256 loanId = uint256(keccak256(encodedLoan)); @@ -171,12 +171,11 @@ abstract contract BaseRecall { } } - function generateRecallConsideration( - Starport.Loan calldata loan, - uint256 proportion, - address from, - address payable to - ) external view returns (AdditionalTransfer[] memory consideration) { + function generateRecallConsideration(Starport.Loan calldata loan, uint256 proportion, address from, address to) + external + view + returns (AdditionalTransfer[] memory consideration) + { Details memory details = abi.decode(loan.terms.statusData, (Details)); return _generateRecallConsideration(loan, 0, details.recallStakeDuration, proportion, from, to); } @@ -187,7 +186,7 @@ abstract contract BaseRecall { uint256 end, uint256 proportion, address from, - address payable to + address to ) internal view returns (AdditionalTransfer[] memory additionalTransfers) { uint256[] memory stake = _getRecallStake(loan, start, end); additionalTransfers = new AdditionalTransfer[](stake.length); diff --git a/test/AstariaV1Test.sol b/test/AstariaV1Test.sol index b2e9a6e9..61b0b4fe 100644 --- a/test/AstariaV1Test.sol +++ b/test/AstariaV1Test.sol @@ -29,12 +29,12 @@ contract AstariaV1Test is StarportTest { pricing = new AstariaV1Pricing(SP); settlement = new AstariaV1Settlement(SP); - hook = new AstariaV1Status(SP); + status = new AstariaV1Status(SP); lenderEnforcer = new AstariaV1LenderEnforcer(); vm.startPrank(recaller.addr); - erc20s[0].approve(address(hook), 1e18); + erc20s[0].approve(address(status), 1e18); vm.stopPrank(); // // 1% interest rate per second diff --git a/test/StarportTest.sol b/test/StarportTest.sol index edfa5df9..27681a88 100644 --- a/test/StarportTest.sol +++ b/test/StarportTest.sol @@ -128,7 +128,7 @@ contract StarportTest is BaseOrderTest { Pricing pricing; Settlement settlement; - Status hook; + Status status; uint256 defaultLoanDuration = 14 days; @@ -205,7 +205,7 @@ contract StarportTest is BaseOrderTest { SO = new StrategistOriginator(SP, strategist.addr, 1e16, address(this)); pricing = new SimpleInterestPricing(SP); settlement = new FixedTermDutchAuctionSettlement(SP); - hook = new FixedTermStatus(); + status = new FixedTermStatus(); vm.label(address(erc721s[0]), "Collateral NFT"); vm.label(address(erc721s[1]), "Collateral2 NFT"); vm.label(address(erc20s[0]), "Debt ERC20"); @@ -484,7 +484,7 @@ contract StarportTest is BaseOrderTest { collateral: newCollateral, debt: newDebt, terms: Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, diff --git a/test/integration-testing/TestAstariaV1Loan.sol b/test/integration-testing/TestAstariaV1Loan.sol index 2734f4c0..90b4c217 100644 --- a/test/integration-testing/TestAstariaV1Loan.sol +++ b/test/integration-testing/TestAstariaV1Loan.sol @@ -11,10 +11,13 @@ import {FixedPointMathLib} from "solady/src/utils/FixedPointMathLib.sol"; contract TestAstariaV1Loan is AstariaV1Test { using FixedPointMathLib for uint256; using {StarportLib.getId} for Starport.Loan; + using Cast for *; + + Starport.Loan activeLoan; function testNewLoanERC721CollateralDefaultTermsRecallBase() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -29,7 +32,7 @@ contract TestAstariaV1Loan is AstariaV1Test { vm.startPrank(recaller.addr); vm.expectRevert(BaseRecall.RecallBeforeHoneymoonExpiry.selector); // attempt recall before honeymoon period has ended - BaseRecall(address(hook)).recall(loan); + BaseRecall(address(status)).recall(loan); vm.stopPrank(); } { @@ -59,17 +62,17 @@ contract TestAstariaV1Loan is AstariaV1Test { uint256 stake; { uint256 balanceBefore = erc20s[0].balanceOf(recaller.addr); - uint256 recallContractBalanceBefore = erc20s[0].balanceOf(address(hook)); + uint256 recallContractBalanceBefore = erc20s[0].balanceOf(address(status)); BaseRecall.Details memory details = abi.decode(loan.terms.statusData, (BaseRecall.Details)); vm.warp(block.timestamp + details.honeymoon); vm.startPrank(recaller.addr); - BaseRecall recallContract = BaseRecall(address(hook)); + BaseRecall recallContract = BaseRecall(address(status)); recallContract.recall(loan); vm.stopPrank(); uint256 balanceAfter = erc20s[0].balanceOf(recaller.addr); - uint256 recallContractBalanceAfter = erc20s[0].balanceOf(address(hook)); + uint256 recallContractBalanceAfter = erc20s[0].balanceOf(address(status)); BasePricing.Details memory pricingDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); stake = BasePricing(address(pricing)).calculateInterest( @@ -84,7 +87,7 @@ contract TestAstariaV1Loan is AstariaV1Test { } { uint256 loanId = loan.getId(); - BaseRecall recallContract = BaseRecall(address(hook)); + BaseRecall recallContract = BaseRecall(address(status)); address recallerAddr; uint64 start; (recallerAddr, start) = recallContract.recalls(loanId); @@ -93,7 +96,7 @@ contract TestAstariaV1Loan is AstariaV1Test { assertEq(start, block.timestamp, "Recall start logged incorrectly"); } { - BaseRecall recallContract = BaseRecall(address(hook)); + BaseRecall recallContract = BaseRecall(address(status)); vm.expectRevert(BaseRecall.LoanHasNotBeenRefinanced.selector); // attempt a withdraw without the loan being refinanced recallContract.withdraw(loan, payable(address(this))); @@ -203,13 +206,13 @@ contract TestAstariaV1Loan is AstariaV1Test { } { uint256 withdrawerBalanceBefore = erc20s[0].balanceOf(address(this)); - uint256 recallContractBalanceBefore = erc20s[0].balanceOf(address(hook)); - BaseRecall recallContract = BaseRecall(address(hook)); + uint256 recallContractBalanceBefore = erc20s[0].balanceOf(address(status)); + BaseRecall recallContract = BaseRecall(address(status)); // attempt a withdraw after the loan has been successfully refinanced recallContract.withdraw(loan, payable(address(this))); uint256 withdrawerBalanceAfter = erc20s[0].balanceOf(address(this)); - uint256 recallContractBalanceAfter = erc20s[0].balanceOf(address(hook)); + uint256 recallContractBalanceAfter = erc20s[0].balanceOf(address(status)); assertEq( withdrawerBalanceBefore + stake, withdrawerBalanceAfter, "Withdrawer did not recover stake as expected" ); @@ -224,7 +227,7 @@ contract TestAstariaV1Loan is AstariaV1Test { // lender is recaller, liquidation amount is 0 function testNewLoanERC721CollateralDefaultTermsRecallLender() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -238,18 +241,18 @@ contract TestAstariaV1Loan is AstariaV1Test { uint256 stake; { uint256 balanceBefore = erc20s[0].balanceOf(lender.addr); - uint256 recallContractBalanceBefore = erc20s[0].balanceOf(address(hook)); + uint256 recallContractBalanceBefore = erc20s[0].balanceOf(address(status)); BaseRecall.Details memory details = abi.decode(loan.terms.statusData, (BaseRecall.Details)); vm.warp(block.timestamp + details.honeymoon); vm.startPrank(lender.addr); - conduitController.updateChannel(lenderConduit, address(hook), true); - BaseRecall recallContract = BaseRecall(address(hook)); + conduitController.updateChannel(lenderConduit, address(status), true); + BaseRecall recallContract = BaseRecall(address(status)); erc20s[0].approve(loan.terms.status, 10e18); recallContract.recall(loan); vm.stopPrank(); uint256 balanceAfter = erc20s[0].balanceOf(lender.addr); - uint256 recallContractBalanceAfter = erc20s[0].balanceOf(address(hook)); + uint256 recallContractBalanceAfter = erc20s[0].balanceOf(address(status)); BasePricing.Details memory pricingDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); stake = BasePricing(address(pricing)).calculateInterest( @@ -336,7 +339,7 @@ contract TestAstariaV1Loan is AstariaV1Test { // recaller is not the lender, liquidation amount is a dutch auction function testNewLoanERC721CollateralDefaultTermsRecallLiquidation() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -347,22 +350,23 @@ contract TestAstariaV1Loan is AstariaV1Test { _createLoan721Collateral20Debt({lender: lender.addr, borrowAmount: 1e18, terms: terms}); uint256 loanId = loan.getId(); + loan.toStorage(activeLoan); uint256 elapsedTime; uint256 stake; { uint256 balanceBefore = erc20s[0].balanceOf(recaller.addr); - uint256 recallContractBalanceBefore = erc20s[0].balanceOf(address(hook)); + uint256 recallContractBalanceBefore = erc20s[0].balanceOf(address(status)); BaseRecall.Details memory details = abi.decode(loan.terms.statusData, (BaseRecall.Details)); vm.warp(block.timestamp + details.honeymoon); elapsedTime += details.honeymoon; vm.startPrank(recaller.addr); - BaseRecall recallContract = BaseRecall(address(hook)); + BaseRecall recallContract = BaseRecall(address(status)); recallContract.recall(loan); vm.stopPrank(); uint256 balanceAfter = erc20s[0].balanceOf(recaller.addr); - uint256 recallContractBalanceAfter = erc20s[0].balanceOf(address(hook)); + uint256 recallContractBalanceAfter = erc20s[0].balanceOf(address(status)); BasePricing.Details memory pricingDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); stake = BasePricing(address(pricing)).calculateInterest( @@ -406,6 +410,7 @@ contract TestAstariaV1Loan is AstariaV1Test { "Settlement consideration length for a dutch auction should be 3 (carry, recaller, and the lender)" ); assertEq(restricted, address(0), "SettlementConsideration should be unrestricted"); + AdditionalTransfer[] memory extraPayment; { BasePricing.Details memory pricingDetails = abi.decode(loan.terms.pricingData, (BasePricing.Details)); uint256 interest = @@ -422,6 +427,9 @@ contract TestAstariaV1Loan is AstariaV1Test { settlementPrice - recallerReward, "Settlement consideration for lender incorrect" ); + extraPayment = AstariaV1Status(activeLoan.terms.status).generateRecallConsideration( + activeLoan, 1e18, activeLoan.terms.status, address(this) + ); } ConsiderationItem[] memory consider = new ConsiderationItem[]( settlementConsideration.length @@ -446,7 +454,7 @@ contract TestAstariaV1Loan is AstariaV1Test { numerator: 1, denominator: 1, parameters: op, - extraData: abi.encode(Actions.Settlement, loan), + extraData: abi.encode(Actions.Settlement, activeLoan), signature: "" }); @@ -458,7 +466,11 @@ contract TestAstariaV1Loan is AstariaV1Test { }); uint256 balanceAfter = erc20s[0].balanceOf(address(this)); address owner = erc721s[0].ownerOf(1); - assertEq(balanceBefore - 500 ether, balanceAfter, "balance of buyer not decremented correctly"); + assertEq( + balanceBefore - 500 ether + extraPayment[0].amount, + balanceAfter, + "balance of buyer not decremented correctly" + ); assertEq(owner, address(this), "Test address should be the owner of the NFT after settlement"); } } diff --git a/test/integration-testing/TestNewLoan.sol b/test/integration-testing/TestNewLoan.sol index 7ff29dd9..0c31f4c4 100644 --- a/test/integration-testing/TestNewLoan.sol +++ b/test/integration-testing/TestNewLoan.sol @@ -57,7 +57,7 @@ contract TestNewLoan is StarportTest { Custodian custody = Custodian(SP.defaultCustodian()); Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, diff --git a/test/integration-testing/TestRepayLoan.sol b/test/integration-testing/TestRepayLoan.sol index 7cfe4021..4adfe229 100644 --- a/test/integration-testing/TestRepayLoan.sol +++ b/test/integration-testing/TestRepayLoan.sol @@ -13,7 +13,7 @@ contract TestRepayLoan is StarportTest { function testRepayLoanBase() public { uint256 borrowAmount = 1e18; Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -37,7 +37,7 @@ contract TestRepayLoan is StarportTest { function testRepayLoanInvalidRepayer() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -105,7 +105,7 @@ contract TestRepayLoan is StarportTest { function testRepayLoanApprovedRepayer() public { uint256 borrowAmount = 1e18; Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -131,7 +131,7 @@ contract TestRepayLoan is StarportTest { // calling generateOrder on the Custodian to test the onlySeaport modifier function testRepayLoanGenerateOrderNotSeaport() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -155,7 +155,7 @@ contract TestRepayLoan is StarportTest { function testRepayLoanInSettlement() public { uint256 borrowAmount = 1e18; Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -220,7 +220,7 @@ contract TestRepayLoan is StarportTest { function testRepayLoanThatDoesNotExist() public { uint256 borrowAmount = 1e18; Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, diff --git a/test/unit-testing/TestPricing.sol b/test/unit-testing/TestPricing.sol index 988928af..dadd0e25 100644 --- a/test/unit-testing/TestPricing.sol +++ b/test/unit-testing/TestPricing.sol @@ -35,7 +35,7 @@ contract TestSimpleInterestPricing is StarportTest, DeepEq { collateral: newCollateral, debt: newDebt, terms: Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: abi.encode( diff --git a/test/unit-testing/TestV1Settlement.sol b/test/unit-testing/TestV1Settlement.sol index 5bd57721..958ecaac 100644 --- a/test/unit-testing/TestV1Settlement.sol +++ b/test/unit-testing/TestV1Settlement.sol @@ -18,7 +18,7 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { function testGetSettlementFailedDutchAuction() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -48,7 +48,7 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { function testGetSettlementLoanNotRecalled() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -65,7 +65,7 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { function testGetSettlementDutchAuctionSettlementAbove() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -121,7 +121,7 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { function testGetAuctionStartNotStarted() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -137,7 +137,7 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { function testGetAuctionStart() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -166,7 +166,7 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { function testGetCurrentAuctionPrice() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -196,7 +196,7 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { function testGetCurrentAuctionPriceNoAuction() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -211,25 +211,25 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { uint256 currentAuctionPrice = AstariaV1Settlement(loan.terms.settlement).getCurrentAuctionPrice(loan); } - function testV1SettlementHandlerExecute() public { - Starport.Terms memory terms = Starport.Terms({ - status: address(hook), - settlement: address(settlement), - pricing: address(pricing), - pricingData: defaultPricingData, - settlementData: defaultSettlementData, - statusData: defaultStatusData - }); - Starport.Loan memory loan = - _createLoan721Collateral20Debt({lender: lender.addr, borrowAmount: 1e18, terms: terms}); - - vm.expectRevert(abi.encodeWithSelector(AstariaV1Settlement.ExecuteHandlerNotImplemented.selector)); - AstariaV1Settlement(loan.terms.settlement).execute(loan, address(this)); - } + // function testV1SettlementHandlerExecute() public { + // Starport.Terms memory terms = Starport.Terms({ + // status: address(hook), + // settlement: address(settlement), + // pricing: address(pricing), + // pricingData: defaultPricingData, + // settlementData: defaultSettlementData, + // statusData: defaultStatusData + // }); + // Starport.Loan memory loan = + // _createLoan721Collateral20Debt({lender: lender.addr, borrowAmount: 1e18, terms: terms}); + // + // vm.expectRevert(abi.encodeWithSelector(AstariaV1Settlement.ExecuteHandlerNotImplemented.selector)); + // AstariaV1Settlement(loan.terms.settlement).execute(loan, address(this)); + // } function testV1SettlementHandlerValidate() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -244,7 +244,7 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { function testV1SettlementHandlerValidateInvalidHandler() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, diff --git a/test/unit-testing/TestV1Status.sol b/test/unit-testing/TestV1Status.sol index 1249468b..617802ed 100644 --- a/test/unit-testing/TestV1Status.sol +++ b/test/unit-testing/TestV1Status.sol @@ -20,7 +20,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testIsActive() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -35,7 +35,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testIsRecalledInsideWindow() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -63,7 +63,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testInvalidRecallLoanDoesNotExist() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -87,7 +87,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testInvalidRecallInvalidStakeType() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -113,7 +113,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testCannotRecallTwice() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -137,7 +137,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testIsRecalledOutsideWindow() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -162,7 +162,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testGenerateRecallConsideration() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -201,7 +201,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testRecallRateEmptyRecall() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -219,7 +219,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testRecallRateActiveRecall() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -245,7 +245,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testCannotWithdrawWithdrawDoesNotExist() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, @@ -261,7 +261,7 @@ contract TestAstariaV1Status is AstariaV1Test, DeepEq { function testCannotWithdrawLoanHasNotBeenRefinanced() public { Starport.Terms memory terms = Starport.Terms({ - status: address(hook), + status: address(status), settlement: address(settlement), pricing: address(pricing), pricingData: defaultPricingData, From f82ada6cec3d6e1b6525d6a27d97fde35a503b62 Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 10:49:18 -0300 Subject: [PATCH 06/11] update snapshot and disable fuzz testing for snapshot check --- .gas-snapshot | 36 ++++++++++++++------------------- .github/workflows/lint_test.yml | 2 +- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index d963ac6b..46438fa6 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,5 +1,3 @@ -DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880486, ~: 882492) -DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232911, ~: 237832) IntegrationTestCaveats:testOriginateUnapprovedFulfiller() (gas: 341293) IntegrationTestCaveats:testOriginateWBorrowerApproval() (gas: 298091) IntegrationTestCaveats:testOriginateWCaveats() (gas: 272268) @@ -56,14 +54,14 @@ TestCompoundInterest:testRateTooLowZero() (gas: 68419) TestCustodian:testCannotLazyMintTwice() (gas: 76686) TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 66861) TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 72489) -TestCustodian:testCustodySelector() (gas: 2719375) +TestCustodian:testCustodySelector() (gas: 2721382) TestCustodian:testDefaultCustodySelectorRevert() (gas: 70083) TestCustodian:testGenerateOrderInvalidHandlerExecution() (gas: 158631) -TestCustodian:testGenerateOrderRepay() (gas: 171937) -TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 197540) -TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 833734) +TestCustodian:testGenerateOrderRepay() (gas: 177918) +TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 203521) +TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 843195) TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 757730) -TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 516688) +TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 522668) TestCustodian:testGenerateOrderRepayInvalidHookAddress() (gas: 90335) TestCustodian:testGenerateOrderRepayInvalidHookReturnType() (gas: 84652) TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 96426) @@ -81,11 +79,11 @@ TestCustodian:testNonPayableFunctions() (gas: 225792) TestCustodian:testOnlySeaport() (gas: 17895) TestCustodian:testPayableFunctions() (gas: 41667) TestCustodian:testPreviewOrderNoActiveLoan() (gas: 98786) -TestCustodian:testPreviewOrderRepay() (gas: 227692) +TestCustodian:testPreviewOrderRepay() (gas: 231173) TestCustodian:testPreviewOrderSettlement() (gas: 182004) TestCustodian:testPreviewOrderSettlementInvalidFufliller() (gas: 100823) TestCustodian:testPreviewOrderSettlementInvalidRepayer() (gas: 106856) -TestCustodian:testRatifyOrder() (gas: 178432) +TestCustodian:testRatifyOrder() (gas: 184413) TestCustodian:testSeaportMetadata() (gas: 8567) TestCustodian:testSetRepayApproval() (gas: 37861) TestCustodian:testSupportsInterface() (gas: 9450) @@ -97,11 +95,11 @@ TestLenderEnforcer:testLERevertInvalidLoanTerms() (gas: 78341) TestLenderEnforcer:testLEValidLoanTerms() (gas: 69496) TestLenderEnforcer:testLEValidLoanTermsAnyBorrower() (gas: 69494) TestLenderEnforcer:testLEValidLoanTermsWithAdditionalTransfers() (gas: 70740) -TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 537052) -TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 524681) -TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 554876) -TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 544618) -TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 550094) +TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 543033) +TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 530662) +TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 560856) +TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 550598) +TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 561586) TestNewLoan:testBuyNowPayLater() (gas: 2832923) TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 394541) TestNewLoan:testNewLoanERC721CollateralLessDebtThanOffered() (gas: 2348) @@ -113,14 +111,12 @@ TestPausableNonReentrant:testNotOwner() (gas: 21254) TestPausableNonReentrant:testPauseAndUnpause() (gas: 22555) TestPausableNonReentrant:testReentrancy() (gas: 15360) TestPausableNonReentrant:testUnpauseWhenNotPaused() (gas: 12582) -TestRefStarportLib:testSpentToReceived() (gas: 13315) -TestRefStarportLib:testValidateSalt(address,bytes32) (runs: 256, μ: 33865, ~: 33865) -TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 629500) -TestRepayLoan:testRepayLoanBase() (gas: 565794) +TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 635481) +TestRepayLoan:testRepayLoanBase() (gas: 571775) TestRepayLoan:testRepayLoanGenerateOrderNotSeaport() (gas: 402462) TestRepayLoan:testRepayLoanInSettlement() (gas: 550078) TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 564487) -TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 837152) +TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 843133) TestSimpleInterestPricing:test_calculateInterest() (gas: 800891) TestSimpleInterestPricing:test_getPaymentConsideration() (gas: 882219) TestSimpleInterestPricing:test_getRefinanceConsideration() (gas: 876412) @@ -155,8 +151,6 @@ TestStarport:testTokenURI() (gas: 65021) TestStarport:testTokenURIInvalidLoan() (gas: 13394) TestStarport:testTransferFromFail() (gas: 80066) TestStarport:testUnpause() (gas: 16309) -TestStarportLib:testSpentToReceived() (gas: 13315) -TestStarportLib:testValidateSalt(address,bytes32) (runs: 256, μ: 33865, ~: 33865) TestStrategistOriginator:testEncodeWithAccountCounter() (gas: 12307) TestStrategistOriginator:testGetStrategistData() (gas: 1471010) TestStrategistOriginator:testIncrementCounterAsStrategist() (gas: 18676) diff --git a/.github/workflows/lint_test.yml b/.github/workflows/lint_test.yml index 6303ef52..25b3fe1c 100644 --- a/.github/workflows/lint_test.yml +++ b/.github/workflows/lint_test.yml @@ -32,7 +32,7 @@ jobs: run: forge test -vvv - name: Snapshot - run: forge snapshot --check + run: forge snapshot --check --no-match-path '*fuzz*' From 2267b08702ae9f5062fb1cff0ffeff8ba49b8907 Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 12:00:18 -0300 Subject: [PATCH 07/11] updates to the repayApproval flow, so its now using the underlying erc721 approvals, new method for borrowers to mint with approval set --- .gas-snapshot | 95 ++++++++++--------- src/Custodian.sol | 53 ++++++++--- src/settlement/AstariaV1Settlement.sol | 9 +- src/settlement/DutchAuctionSettlement.sol | 13 ++- src/settlement/EnglishAuctionSettlement.sol | 15 ++- .../FixedTermDutchAuctionSettlement.sol | 9 +- src/settlement/Settlement.sol | 4 +- test/integration-testing/TestRepayLoan.sol | 2 +- test/unit-testing/TestCustodian.sol | 31 ++++-- test/unit-testing/TestV1Settlement.sol | 2 +- test/utils/MockCall.sol | 2 +- 11 files changed, 156 insertions(+), 79 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 46438fa6..394f7d6b 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,3 +1,5 @@ +DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880419, ~: 883142) +DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232911, ~: 237832) IntegrationTestCaveats:testOriginateUnapprovedFulfiller() (gas: 341293) IntegrationTestCaveats:testOriginateWBorrowerApproval() (gas: 298091) IntegrationTestCaveats:testOriginateWCaveats() (gas: 272268) @@ -14,8 +16,8 @@ IntegrationTestCaveats:testRefinanceWLenderApproval() (gas: 405713) PausableNonReentrantImpl:test() (gas: 2442) PausableNonReentrantImpl:testReentrancy() (gas: 2735) TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1021044) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 727567) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 1404892) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 727610) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 1404935) TestAstariaV1Pricing:testGetRefiannceConsiderationValidEqualRate() (gas: 146135) TestAstariaV1Pricing:testGetRefiannceConsiderationValidHigherRate() (gas: 158343) TestAstariaV1Pricing:testGetRefiannceConsiderationValidLowerRate() (gas: 153372) @@ -23,15 +25,15 @@ TestAstariaV1Pricing:testGetRefinanceConsiderationAsBorrowerZeroRate() (gas: 811 TestAstariaV1Pricing:testGetRefinanceConsiderationInsufficientRefinance() (gas: 108010) TestAstariaV1Pricing:testGetRefinanceConsiderationInvalidRefinance() (gas: 88264) TestAstariaV1Pricing:testGetRefinanceConsiderationZeroRate() (gas: 138753) -TestAstariaV1Settlement:testGetAuctionStart() (gas: 433631) -TestAstariaV1Settlement:testGetAuctionStartNotStarted() (gas: 433204) -TestAstariaV1Settlement:testGetCurrentAuctionPrice() (gas: 448460) -TestAstariaV1Settlement:testGetCurrentAuctionPriceNoAuction() (gas: 436835) -TestAstariaV1Settlement:testGetSettlementDutchAuctionSettlementAbove() (gas: 490360) -TestAstariaV1Settlement:testGetSettlementFailedDutchAuction() (gas: 448783) -TestAstariaV1Settlement:testGetSettlementLoanNotRecalled() (gas: 439311) -TestAstariaV1Settlement:testV1SettlementHandlerValidate() (gas: 419948) -TestAstariaV1Settlement:testV1SettlementHandlerValidateInvalidHandler() (gas: 420072) +TestAstariaV1Settlement:testGetAuctionStart() (gas: 433653) +TestAstariaV1Settlement:testGetAuctionStartNotStarted() (gas: 433226) +TestAstariaV1Settlement:testGetCurrentAuctionPrice() (gas: 448437) +TestAstariaV1Settlement:testGetCurrentAuctionPriceNoAuction() (gas: 436790) +TestAstariaV1Settlement:testGetSettlementDutchAuctionSettlementAbove() (gas: 490359) +TestAstariaV1Settlement:testGetSettlementFailedDutchAuction() (gas: 448827) +TestAstariaV1Settlement:testGetSettlementLoanNotRecalled() (gas: 439333) +TestAstariaV1Settlement:testV1SettlementHandlerValidate() (gas: 419903) +TestAstariaV1Settlement:testV1SettlementHandlerValidateInvalidHandler() (gas: 420027) TestAstariaV1Status:testCannotRecallTwice() (gas: 580032) TestAstariaV1Status:testCannotWithdrawLoanHasNotBeenRefinanced() (gas: 425604) TestAstariaV1Status:testCannotWithdrawWithdrawDoesNotExist() (gas: 432033) @@ -51,42 +53,43 @@ TestCompoundInterest:testAmountMax() (gas: 65767) TestCompoundInterest:testRateMax() (gas: 68106) TestCompoundInterest:testRateTooLowOne() (gas: 73157) TestCompoundInterest:testRateTooLowZero() (gas: 68419) -TestCustodian:testCannotLazyMintTwice() (gas: 76686) -TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 66861) -TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 72489) -TestCustodian:testCustodySelector() (gas: 2721382) +TestCustodian:testCannotLazyMintTwice() (gas: 76731) +TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 66906) +TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 72534) +TestCustodian:testCustodySelector() (gas: 2799181) TestCustodian:testDefaultCustodySelectorRevert() (gas: 70083) -TestCustodian:testGenerateOrderInvalidHandlerExecution() (gas: 158631) -TestCustodian:testGenerateOrderRepay() (gas: 177918) -TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 203521) -TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 843195) -TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 757730) -TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 522668) +TestCustodian:testGenerateOrderInvalidHandlerExecution() (gas: 158640) +TestCustodian:testGenerateOrderRepay() (gas: 177948) +TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 194060) +TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 843299) +TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 757717) +TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 522720) TestCustodian:testGenerateOrderRepayInvalidHookAddress() (gas: 90335) TestCustodian:testGenerateOrderRepayInvalidHookReturnType() (gas: 84652) -TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 96426) -TestCustodian:testGenerateOrderSettlement() (gas: 150387) -TestCustodian:testGenerateOrderSettlementHandlerAuthorized() (gas: 155833) +TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 99126) +TestCustodian:testGenerateOrderSettlement() (gas: 150386) +TestCustodian:testGenerateOrderSettlementHandlerAuthorized() (gas: 155832) TestCustodian:testGenerateOrderSettlementNoActiveLoan() (gas: 155836) TestCustodian:testGenerateOrderSettlementUnauthorized() (gas: 94410) -TestCustodian:testGenerateOrdersWithLoanStartAtBlockTimestampInvalidLoan() (gas: 453017) -TestCustodian:testGetBorrower() (gas: 76234) +TestCustodian:testGenerateOrdersWithLoanStartAtBlockTimestampInvalidLoan() (gas: 452995) +TestCustodian:testGetBorrower() (gas: 76344) TestCustodian:testInvalidAction() (gas: 114498) -TestCustodian:testInvalidActionRepayInActiveLoan() (gas: 117469) +TestCustodian:testInvalidActionRepayInActiveLoan() (gas: 117447) TestCustodian:testInvalidActionSettleActiveLoan() (gas: 117407) +TestCustodian:testMintWithApprovalSetAsBorrower() (gas: 356392) +TestCustodian:testMintWithApprovalSetNotAuthorized() (gas: 74650) TestCustodian:testName() (gas: 7098) -TestCustodian:testNonPayableFunctions() (gas: 225792) +TestCustodian:testNonPayableFunctions() (gas: 212635) TestCustodian:testOnlySeaport() (gas: 17895) TestCustodian:testPayableFunctions() (gas: 41667) TestCustodian:testPreviewOrderNoActiveLoan() (gas: 98786) -TestCustodian:testPreviewOrderRepay() (gas: 231173) -TestCustodian:testPreviewOrderSettlement() (gas: 182004) +TestCustodian:testPreviewOrderRepay() (gas: 231225) +TestCustodian:testPreviewOrderSettlement() (gas: 182003) TestCustodian:testPreviewOrderSettlementInvalidFufliller() (gas: 100823) TestCustodian:testPreviewOrderSettlementInvalidRepayer() (gas: 106856) -TestCustodian:testRatifyOrder() (gas: 184413) +TestCustodian:testRatifyOrder() (gas: 184443) TestCustodian:testSeaportMetadata() (gas: 8567) -TestCustodian:testSetRepayApproval() (gas: 37861) -TestCustodian:testSupportsInterface() (gas: 9450) +TestCustodian:testSupportsInterface() (gas: 9428) TestCustodian:testSymbol() (gas: 7127) TestCustodian:testTokenURI() (gas: 64817) TestCustodian:testTokenURIInvalidLoan() (gas: 13218) @@ -95,28 +98,30 @@ TestLenderEnforcer:testLERevertInvalidLoanTerms() (gas: 78341) TestLenderEnforcer:testLEValidLoanTerms() (gas: 69496) TestLenderEnforcer:testLEValidLoanTermsAnyBorrower() (gas: 69494) TestLenderEnforcer:testLEValidLoanTermsWithAdditionalTransfers() (gas: 70740) -TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 543033) -TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 530662) -TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 560856) -TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 550598) -TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 561586) +TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 543085) +TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 530714) +TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 560908) +TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 550650) +TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 556284) TestNewLoan:testBuyNowPayLater() (gas: 2832923) TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 394541) TestNewLoan:testNewLoanERC721CollateralLessDebtThanOffered() (gas: 2348) TestNewLoan:testNewLoanRefinanceNew() (gas: 207) TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 305741) TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 358465) -TestNewLoan:testSettleLoan() (gas: 611574) +TestNewLoan:testSettleLoan() (gas: 611617) TestPausableNonReentrant:testNotOwner() (gas: 21254) TestPausableNonReentrant:testPauseAndUnpause() (gas: 22555) TestPausableNonReentrant:testReentrancy() (gas: 15360) TestPausableNonReentrant:testUnpauseWhenNotPaused() (gas: 12582) -TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 635481) -TestRepayLoan:testRepayLoanBase() (gas: 571775) +TestRefStarportLib:testSpentToReceived() (gas: 13315) +TestRefStarportLib:testValidateSalt(address,bytes32) (runs: 256, μ: 33865, ~: 33865) +TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 635539) +TestRepayLoan:testRepayLoanBase() (gas: 571829) TestRepayLoan:testRepayLoanGenerateOrderNotSeaport() (gas: 402462) -TestRepayLoan:testRepayLoanInSettlement() (gas: 550078) -TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 564487) -TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 843133) +TestRepayLoan:testRepayLoanInSettlement() (gas: 550102) +TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 569889) +TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 843189) TestSimpleInterestPricing:test_calculateInterest() (gas: 800891) TestSimpleInterestPricing:test_getPaymentConsideration() (gas: 882219) TestSimpleInterestPricing:test_getRefinanceConsideration() (gas: 876412) @@ -151,6 +156,8 @@ TestStarport:testTokenURI() (gas: 65021) TestStarport:testTokenURIInvalidLoan() (gas: 13394) TestStarport:testTransferFromFail() (gas: 80066) TestStarport:testUnpause() (gas: 16309) +TestStarportLib:testSpentToReceived() (gas: 13315) +TestStarportLib:testValidateSalt(address,bytes32) (runs: 256, μ: 33865, ~: 33865) TestStrategistOriginator:testEncodeWithAccountCounter() (gas: 12307) TestStrategistOriginator:testGetStrategistData() (gas: 1471010) TestStrategistOriginator:testIncrementCounterAsStrategist() (gas: 18676) diff --git a/src/Custodian.sol b/src/Custodian.sol index f5fa32bd..8ef5e54f 100644 --- a/src/Custodian.sol +++ b/src/Custodian.sol @@ -52,6 +52,7 @@ contract Custodian is ERC721, ContractOffererInterface { error InvalidHandlerExecution(); error InvalidLoan(); error InvalidRepayer(); + error NotAuthorized(); error NotSeaport(); error NotEnteredViaSeaport(); error NotStarport(); @@ -154,16 +155,24 @@ contract Custodian is ERC721, ContractOffererInterface { _safeMint(loan.borrower, loanId, encodedLoan); } - /** - * @dev Set's approvals for who can repay a loan on behalf of the borrower. + * @dev Mints a custody token for a loan. * - * @param who The address of the account to modify approval for - * @param approved The approval status + * @param loan The loan to mint a custody token for + * @param approvedTo The address with pre approvals set */ - function setRepayApproval(address who, bool approved) external { - repayApproval[msg.sender][who] = approved; - emit RepayApproval(msg.sender, who, approved); + + function mintWithApprovalSet(Starport.Loan calldata loan, address approvedTo) external { + bytes memory encodedLoan = abi.encode(loan); + uint256 loanId = uint256(keccak256(encodedLoan)); + if (loan.custodian != address(this) || !SP.active(loanId)) { + revert InvalidLoan(); + } + if (msg.sender != loan.borrower) { + revert NotAuthorized(); + } + _safeMint(loan.borrower, loanId, encodedLoan); + _approve(loan.borrower, approvedTo, loanId); } /** @@ -208,7 +217,7 @@ contract Custodian is ERC721, ContractOffererInterface { } if (action == Actions.Repayment && Status(loan.terms.status).isActive(loan)) { address borrower = getBorrower(loan); - if (fulfiller != borrower && !repayApproval[borrower][fulfiller]) { + if (fulfiller != borrower && fulfiller != _getApproved(loan.getId())) { revert InvalidRepayer(); } @@ -222,7 +231,7 @@ contract Custodian is ERC721, ContractOffererInterface { consideration = StarportLib.mergeSpentItemsToReceivedItems(payment, loan.issuer, carry, loan.originator); _settleLoan(loan); - _settlementExecute(loan, fulfiller); + _postRepaymentExecute(loan, fulfiller); } else if (action == Actions.Settlement && !Status(loan.terms.status).isActive(loan)) { address authorized; //add in originator fee @@ -241,7 +250,7 @@ contract Custodian is ERC721, ContractOffererInterface { revert InvalidFulfiller(); } _settleLoan(loan); - _settlementExecute(loan, fulfiller); + _postSettlementExecute(loan, fulfiller); } else { revert InvalidAction(); } @@ -400,9 +409,29 @@ contract Custodian is ERC721, ContractOffererInterface { * @param loan The the loan that is settled * @param fulfiller The address executing seaport */ - function _settlementExecute(Starport.Loan memory loan, address fulfiller) internal virtual { + function _postSettlementExecute(Starport.Loan memory loan, address fulfiller) internal virtual { + _beforeSettlementHandlerHook(loan); + if ( + Settlement(loan.terms.settlement).postSettlement{gas: 100_000}(loan, fulfiller) + != Settlement.postSettlement.selector + ) { + revert InvalidHandlerExecution(); + } + _afterSettlementHandlerHook(loan); + } + /** + * @dev settle the loan with the LoanManager + * + * @param loan The the loan that is settled + * @param fulfiller The address executing seaport + */ + + function _postRepaymentExecute(Starport.Loan memory loan, address fulfiller) internal virtual { _beforeSettlementHandlerHook(loan); - if (Settlement(loan.terms.settlement).execute(loan, fulfiller) != Settlement.execute.selector) { + if ( + Settlement(loan.terms.settlement).postRepayment{gas: 100_000}(loan, fulfiller) + != Settlement.postRepayment.selector + ) { revert InvalidHandlerExecution(); } _afterSettlementHandlerHook(loan); diff --git a/src/settlement/AstariaV1Settlement.sol b/src/settlement/AstariaV1Settlement.sol index af9eed2d..f0387af6 100644 --- a/src/settlement/AstariaV1Settlement.sol +++ b/src/settlement/AstariaV1Settlement.sol @@ -144,14 +144,19 @@ contract AstariaV1Settlement is DutchAuctionSettlement { } } - function execute(Starport.Loan calldata loan, address fulfiller) external virtual override returns (bytes4) { + function postSettlement(Starport.Loan calldata loan, address fulfiller) + external + virtual + override + returns (bytes4) + { // TODO: do we need the commented out code if we dont care about reverts anyways, seems like extra gas // (address recaller, uint64 recallStart) = BaseRecall(loan.terms.status).recalls(loan.getId()); // if (recallStart != 0 || recaller != address(0)) { //we dont wanna revert if theres ever a halt in the underlying call, settlement must complete loan.terms.status.call(abi.encodeWithSelector(BaseRecall.withdraw.selector, loan, fulfiller)); // } - return Settlement.execute.selector; + return Settlement.postSettlement.selector; } function validate(Starport.Loan calldata loan) external view virtual override returns (bool) { diff --git a/src/settlement/DutchAuctionSettlement.sol b/src/settlement/DutchAuctionSettlement.sol index 7e7ecbe7..4a31e126 100644 --- a/src/settlement/DutchAuctionSettlement.sol +++ b/src/settlement/DutchAuctionSettlement.sol @@ -30,8 +30,17 @@ abstract contract DutchAuctionSettlement is Settlement, AmountDeriver { uint256 window; } - function execute(Starport.Loan calldata loan, address fulfiller) external virtual override returns (bytes4) { - return Settlement.execute.selector; + function postSettlement(Starport.Loan calldata loan, address fulfiller) + external + virtual + override + returns (bytes4) + { + return Settlement.postSettlement.selector; + } + + function postRepayment(Starport.Loan calldata loan, address fulfiller) external virtual override returns (bytes4) { + return Settlement.postRepayment.selector; } function getAuctionStart(Starport.Loan calldata loan) public view virtual returns (uint256); diff --git a/src/settlement/EnglishAuctionSettlement.sol b/src/settlement/EnglishAuctionSettlement.sol index 11171743..9ca812df 100644 --- a/src/settlement/EnglishAuctionSettlement.sol +++ b/src/settlement/EnglishAuctionSettlement.sol @@ -56,11 +56,20 @@ contract EnglishAuctionSettlement is Settlement { return details.reservePrice.length == loan.debt.length; } - function execute(Starport.Loan calldata loan, address fulfiller) external virtual override returns (bytes4) { - if (fulfiller != address(this) && !Status(loan.terms.status).isActive(loan)) { + function postSettlement(Starport.Loan calldata loan, address fulfiller) + external + virtual + override + returns (bytes4) + { + if (fulfiller != address(this)) { revert("must liquidate via the handler to trigger english auction"); } - return Settlement.execute.selector; + return Settlement.postSettlement.selector; + } + + function postRepayment(Starport.Loan calldata loan, address fulfiller) external virtual override returns (bytes4) { + return Settlement.postRepayment.selector; } function getSettlement(Starport.Loan calldata loan) diff --git a/src/settlement/FixedTermDutchAuctionSettlement.sol b/src/settlement/FixedTermDutchAuctionSettlement.sol index 6d33a7ee..4e930a19 100644 --- a/src/settlement/FixedTermDutchAuctionSettlement.sol +++ b/src/settlement/FixedTermDutchAuctionSettlement.sol @@ -18,8 +18,13 @@ contract FixedTermDutchAuctionSettlement is DutchAuctionSettlement { return loan.start + details.loanDuration; } - function execute(Starport.Loan calldata loan, address fulfiller) external virtual override returns (bytes4) { - return Settlement.execute.selector; + function postSettlement(Starport.Loan calldata loan, address fulfiller) + external + virtual + override + returns (bytes4) + { + return Settlement.postSettlement.selector; } function validate(Starport.Loan calldata loan) external view virtual override returns (bool) { diff --git a/src/settlement/Settlement.sol b/src/settlement/Settlement.sol index abe59624..81d336f1 100644 --- a/src/settlement/Settlement.sol +++ b/src/settlement/Settlement.sol @@ -32,7 +32,9 @@ abstract contract Settlement is TokenReceiverInterface { SP = SP_; } - function execute(Starport.Loan calldata loan, address fulfiller) external virtual returns (bytes4); + function postSettlement(Starport.Loan calldata loan, address fulfiller) external virtual returns (bytes4); + + function postRepayment(Starport.Loan calldata loan, address fulfiller) external virtual returns (bytes4); function validate(Starport.Loan calldata loan) external view virtual returns (bool); diff --git a/test/integration-testing/TestRepayLoan.sol b/test/integration-testing/TestRepayLoan.sol index 4adfe229..a9450a5d 100644 --- a/test/integration-testing/TestRepayLoan.sol +++ b/test/integration-testing/TestRepayLoan.sol @@ -122,7 +122,7 @@ contract TestRepayLoan is StarportTest { uint256 interest = SimpleInterestPricing(loan.terms.pricing).calculateInterest(10 days, loan.debt[0].amount, details.rate); erc20s[0].approve(address(SP.seaport()), loan.debt[0].amount + interest); - custodian.setRepayApproval(address(this), true); + custodian.mintWithApprovalSet(loan, address(this)); vm.stopPrank(); _repayLoan(loan, address(this)); diff --git a/test/unit-testing/TestCustodian.sol b/test/unit-testing/TestCustodian.sol index 2ce625b2..ee864896 100644 --- a/test/unit-testing/TestCustodian.sol +++ b/test/unit-testing/TestCustodian.sol @@ -70,10 +70,6 @@ contract TestCustodian is StarportTest, DeepEq, MockCall { vm.expectRevert(); payable(address(custodian)).call{value: 1 ether}(abi.encodeWithSelector(Custodian.mint.selector, activeLoan)); vm.expectRevert(); - payable(address(custodian)).call{value: 1 ether}( - abi.encodeWithSelector(Custodian.setRepayApproval.selector, address(0), false) - ); - vm.expectRevert(); payable(address(custodian)).call{value: 1 ether}( abi.encodeWithSelector( Custodian.ratifyOrder.selector, @@ -130,11 +126,26 @@ contract TestCustodian is StarportTest, DeepEq, MockCall { custodian.tokenURI(uint256(0)); } - function testSetRepayApproval() public { - vm.expectEmit(true, false, false, false); - emit RepayApproval(address(this), borrower.addr, true); - Custodian(custodian).setRepayApproval(borrower.addr, true); - assert(Custodian(custodian).repayApproval(address(this), borrower.addr)); + event Approval(address owner, address account, uint256 id); + + function testMintWithApprovalSetAsBorrower() public { + Starport.Loan memory loan = generateDefaultLoanTerms(); + loan.collateral[0].identifier = uint256(3); + loan.start = block.timestamp; + loan.originator = borrower.addr; + newLoan(loan, bytes32(msg.sig), bytes32(msg.sig), borrower.addr); + // vm.expectEmit(); + // emit Transfer(address(0), borrower.addr, loan.getId()); + // vm.expectEmit(address(custodian)); + // emit Approval(loan.borrower, address(this), loan.getId()); + vm.prank(borrower.addr); + Custodian(custodian).mintWithApprovalSet(loan, address(this)); + assert(Custodian(custodian).getApproved(loan.getId()) == address(this)); + } + + function testMintWithApprovalSetNotAuthorized() public { + vm.expectRevert(abi.encodeWithSelector(Custodian.NotAuthorized.selector)); + Custodian(custodian).mintWithApprovalSet(activeLoan, address(this)); } function testCannotMintInvalidLoanValidCustodian() public { @@ -211,7 +222,7 @@ contract TestCustodian is StarportTest, DeepEq, MockCall { function testGenerateOrderRepayAsRepayApprovedBorrower() public { vm.prank(activeLoan.borrower); - custodian.setRepayApproval(address(this), true); + custodian.approve(address(this), activeLoan.getId()); vm.prank(seaportAddr); custodian.generateOrder( address(this), new SpentItem[](0), activeDebt, abi.encode(Actions.Repayment, activeLoan) diff --git a/test/unit-testing/TestV1Settlement.sol b/test/unit-testing/TestV1Settlement.sol index 958ecaac..f1ed840b 100644 --- a/test/unit-testing/TestV1Settlement.sol +++ b/test/unit-testing/TestV1Settlement.sol @@ -224,7 +224,7 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { // _createLoan721Collateral20Debt({lender: lender.addr, borrowAmount: 1e18, terms: terms}); // // vm.expectRevert(abi.encodeWithSelector(AstariaV1Settlement.ExecuteHandlerNotImplemented.selector)); - // AstariaV1Settlement(loan.terms.settlement).execute(loan, address(this)); + // AstariaV1Settlement(loan.terms.settlement).postSettlement(loan, address(this)); // } function testV1SettlementHandlerValidate() public { diff --git a/test/utils/MockCall.sol b/test/utils/MockCall.sol index 785b117b..fa4ab37f 100644 --- a/test/utils/MockCall.sol +++ b/test/utils/MockCall.sol @@ -32,6 +32,6 @@ abstract contract MockCall is TestBase { } function mockHandlerExecuteFail(address settlement) public { - vm.mockCall(settlement, abi.encodeWithSelector(Settlement.execute.selector), abi.encode(bytes4(0))); + vm.mockCall(settlement, abi.encodeWithSelector(Settlement.postSettlement.selector), abi.encode(bytes4(0))); } } From 3a037eed532bfbe10619ec4ac51b450d69a70fe2 Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 12:15:11 -0300 Subject: [PATCH 08/11] update coverage and add additional tests for reverts --- src/Custodian.sol | 7 ++++--- test/unit-testing/TestCustodian.sol | 27 ++++++++++++++++++++++++--- test/unit-testing/TestStarport.sol | 5 +++++ test/utils/MockCall.sol | 6 +++++- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/Custodian.sol b/src/Custodian.sol index 8ef5e54f..99f49a04 100644 --- a/src/Custodian.sol +++ b/src/Custodian.sol @@ -49,7 +49,8 @@ contract Custodian is ERC721, ContractOffererInterface { error ImplementInChild(); error InvalidAction(); error InvalidFulfiller(); - error InvalidHandlerExecution(); + error InvalidPostSettlement(); + error InvalidPostRepayment(); error InvalidLoan(); error InvalidRepayer(); error NotAuthorized(); @@ -415,7 +416,7 @@ contract Custodian is ERC721, ContractOffererInterface { Settlement(loan.terms.settlement).postSettlement{gas: 100_000}(loan, fulfiller) != Settlement.postSettlement.selector ) { - revert InvalidHandlerExecution(); + revert InvalidPostSettlement(); } _afterSettlementHandlerHook(loan); } @@ -432,7 +433,7 @@ contract Custodian is ERC721, ContractOffererInterface { Settlement(loan.terms.settlement).postRepayment{gas: 100_000}(loan, fulfiller) != Settlement.postRepayment.selector ) { - revert InvalidHandlerExecution(); + revert InvalidPostRepayment(); } _afterSettlementHandlerHook(loan); } diff --git a/test/unit-testing/TestCustodian.sol b/test/unit-testing/TestCustodian.sol index ee864896..66823148 100644 --- a/test/unit-testing/TestCustodian.sol +++ b/test/unit-testing/TestCustodian.sol @@ -143,6 +143,17 @@ contract TestCustodian is StarportTest, DeepEq, MockCall { assert(Custodian(custodian).getApproved(loan.getId()) == address(this)); } + function testMintWithApprovalSetAsBorrowerInvalidLoan() public { + Starport.Loan memory loan = generateDefaultLoanTerms(); + loan.collateral[0].identifier = uint256(3); + loan.start = block.timestamp; + loan.originator = borrower.addr; + loan.custodian = address(this); + vm.expectRevert(abi.encodeWithSelector(Custodian.InvalidLoan.selector)); + vm.prank(borrower.addr); + Custodian(custodian).mintWithApprovalSet(loan, address(this)); + } + function testMintWithApprovalSetNotAuthorized() public { vm.expectRevert(abi.encodeWithSelector(Custodian.NotAuthorized.selector)); Custodian(custodian).mintWithApprovalSet(activeLoan, address(this)); @@ -406,18 +417,28 @@ contract TestCustodian is StarportTest, DeepEq, MockCall { vm.stopPrank(); } - function testGenerateOrderInvalidHandlerExecution() public { + function testGenerateOrderInvalidPostSettlement() public { vm.startPrank(seaportAddr); bytes memory context = abi.encode(Actions.Settlement, activeLoan); mockStatusCall(activeLoan.terms.status, false); mockSettlementCall(activeLoan.terms.settlement, new ReceivedItem[](0), address(activeLoan.terms.settlement)); - mockHandlerExecuteFail(activeLoan.terms.settlement); - vm.expectRevert(abi.encodeWithSelector(Custodian.InvalidHandlerExecution.selector)); + mockPostSettlementFail(activeLoan.terms.settlement); + vm.expectRevert(abi.encodeWithSelector(Custodian.InvalidPostSettlement.selector)); custodian.generateOrder(alice, new SpentItem[](0), activeDebt, context); vm.stopPrank(); } + function testGenerateOrderInvalidPostRepayment() public { + bytes memory context = abi.encode(Actions.Repayment, activeLoan); + mockStatusCall(activeLoan.terms.status, true); + // mockSettlementCall(activeLoan.terms.settlement, new ReceivedItem[](0), address(activeLoan.terms.settlement)); + mockPostRepaymentFail(activeLoan.terms.settlement); + vm.expectRevert(abi.encodeWithSelector(Custodian.InvalidPostRepayment.selector)); + vm.prank(seaportAddr); + custodian.generateOrder(activeLoan.borrower, new SpentItem[](0), activeDebt, context); + } + function testPreviewOrderRepay() public { mockStatusCall(activeLoan.terms.status, true); mockSettlementCall(activeLoan.terms.settlement, new ReceivedItem[](0), address(0)); diff --git a/test/unit-testing/TestStarport.sol b/test/unit-testing/TestStarport.sol index 08ac5fc1..aa343dd2 100644 --- a/test/unit-testing/TestStarport.sol +++ b/test/unit-testing/TestStarport.sol @@ -164,6 +164,11 @@ contract TestStarport is StarportTest, DeepEq { SP.unpause(); } + function testApplyRefinanceConsiderationToLoanMalformed() public { + vm.expectRevert(Starport.MalformedRefinance.selector); + SP.applyRefinanceConsiderationToLoan(activeLoan, new SpentItem[](0), new SpentItem[](0), ""); + } + function testInitializedFlagSetProperly() public { activeLoan.borrower = address(0); assert(SP.inactive(activeLoan.getId())); diff --git a/test/utils/MockCall.sol b/test/utils/MockCall.sol index fa4ab37f..21526f28 100644 --- a/test/utils/MockCall.sol +++ b/test/utils/MockCall.sol @@ -31,7 +31,11 @@ abstract contract MockCall is TestBase { ); } - function mockHandlerExecuteFail(address settlement) public { + function mockPostSettlementFail(address settlement) public { vm.mockCall(settlement, abi.encodeWithSelector(Settlement.postSettlement.selector), abi.encode(bytes4(0))); } + + function mockPostRepaymentFail(address settlement) public { + vm.mockCall(settlement, abi.encodeWithSelector(Settlement.postRepayment.selector), abi.encode(bytes4(0))); + } } From 0904eac1fff4fff9213ba3ac9c48ef26ebc05ec1 Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 12:20:31 -0300 Subject: [PATCH 09/11] remove on Loan settled callback from starport, can be done via new postSettlement/postRepayment flows --- src/Starport.sol | 8 -------- test/unit-testing/TestCustodian.sol | 27 --------------------------- 2 files changed, 35 deletions(-) diff --git a/src/Starport.sol b/src/Starport.sol index 23cc748e..681303f6 100644 --- a/src/Starport.sol +++ b/src/Starport.sol @@ -37,10 +37,6 @@ import {Ownable} from "solady/src/auth/Ownable.sol"; import {SafeTransferLib} from "solady/src/utils/SafeTransferLib.sol"; import {PausableNonReentrant} from "starport-core/lib/PausableNonReentrant.sol"; -interface LoanSettledCallback { - function onLoanSettled(Starport.Loan calldata loan) external; -} - contract Starport is ERC721, PausableNonReentrant { using FixedPointMathLib for uint256; @@ -473,10 +469,6 @@ contract Starport is ERC721, PausableNonReentrant { _burn(tokenId); } _setExtraData(tokenId, uint8(FieldFlags.INACTIVE)); - - if (loan.issuer.code.length > 0) { - loan.issuer.call(abi.encodeWithSelector(LoanSettledCallback.onLoanSettled.selector, loan)); - } emit Close(tokenId); } diff --git a/test/unit-testing/TestCustodian.sol b/test/unit-testing/TestCustodian.sol index 66823148..90edc1d7 100644 --- a/test/unit-testing/TestCustodian.sol +++ b/test/unit-testing/TestCustodian.sol @@ -239,32 +239,6 @@ contract TestCustodian is StarportTest, DeepEq, MockCall { address(this), new SpentItem[](0), activeDebt, abi.encode(Actions.Repayment, activeLoan) ); } - //TODO: add assertions - - function testGenerateOrderRepayERC1155WithRevert() public { - // 1155 - Starport.Loan memory originationDetails = _generateOriginationDetails( - _getERC1155SpentItem(erc1155s[0]), _getERC20SpentItem(erc20s[0], borrowAmount), address(issuer) - ); - - Starport.Loan memory loan = - newLoan(originationDetails, bytes32(uint256(2)), bytes32(uint256(2)), address(issuer)); - skip(1); - - loan.toStorage(activeLoan); - vm.prank(seaportAddr); - //function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; - vm.mockCallRevert( - address(issuer), - abi.encodeWithSelector( - LoanSettledCallback.onLoanSettled.selector, abi.encode(Actions.Repayment, activeLoan) - ), - new bytes(0) - ); - custodian.generateOrder( - activeLoan.borrower, new SpentItem[](0), activeDebt, abi.encode(Actions.Repayment, activeLoan) - ); - } function testGenerateOrdersWithLoanStartAtBlockTimestampInvalidLoan() public { // 1155 @@ -276,7 +250,6 @@ contract TestCustodian is StarportTest, DeepEq, MockCall { newLoan(originationDetails, bytes32(uint256(2)), bytes32(uint256(2)), address(issuer)); loan.toStorage(activeLoan); vm.prank(seaportAddr); - //function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; vm.expectRevert(abi.encodeWithSelector(Custodian.InvalidLoan.selector)); custodian.generateOrder( activeLoan.borrower, new SpentItem[](0), activeDebt, abi.encode(Actions.Repayment, activeLoan) From 1d1650be56496b6cb8e9933f97fdf5f8974ffa59 Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 12:22:49 -0300 Subject: [PATCH 10/11] snapshot and remove loansettled callback import --- .gas-snapshot | 197 +++++++++++++++++++++--------------------- test/StarportTest.sol | 5 +- 2 files changed, 99 insertions(+), 103 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index d1cfe8d0..eda659a8 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,23 +1,23 @@ -DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880469, ~: 882686) -DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232899, ~: 237832) -IntegrationTestCaveats:testOriginateUnapprovedFulfiller() (gas: 341316) -IntegrationTestCaveats:testOriginateWBorrowerApproval() (gas: 298157) -IntegrationTestCaveats:testOriginateWCaveats() (gas: 272224) +DiffFuzzTestStarportLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880557, ~: 883183) +DiffFuzzTestStarportLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232911, ~: 237832) +IntegrationTestCaveats:testOriginateUnapprovedFulfiller() (gas: 341166) +IntegrationTestCaveats:testOriginateWBorrowerApproval() (gas: 298037) +IntegrationTestCaveats:testOriginateWCaveats() (gas: 272104) IntegrationTestCaveats:testOriginateWCaveatsIncrementedNonce() (gas: 200214) -IntegrationTestCaveats:testOriginateWCaveatsInvalidSalt() (gas: 257879) +IntegrationTestCaveats:testOriginateWCaveatsInvalidSalt() (gas: 257759) IntegrationTestCaveats:testOriginateWCaveatsInvalidSaltManual() (gas: 175780) -IntegrationTestCaveats:testOriginateWLenderApproval() (gas: 298211) -IntegrationTestCaveats:testRefinanceAsLender() (gas: 1036565) -IntegrationTestCaveats:testRefinanceCaveatFailure() (gas: 402687) -IntegrationTestCaveats:testRefinanceLoanStartAtBlockTimestampInvalidLoan() (gas: 377478) -IntegrationTestCaveats:testRefinanceUnapprovedFulfiller() (gas: 460114) -IntegrationTestCaveats:testRefinanceWCaveatsInvalidSalt() (gas: 381107) -IntegrationTestCaveats:testRefinanceWLenderApproval() (gas: 405669) +IntegrationTestCaveats:testOriginateWLenderApproval() (gas: 298091) +IntegrationTestCaveats:testRefinanceAsLender() (gas: 1036148) +IntegrationTestCaveats:testRefinanceCaveatFailure() (gas: 402330) +IntegrationTestCaveats:testRefinanceLoanStartAtBlockTimestampInvalidLoan() (gas: 377358) +IntegrationTestCaveats:testRefinanceUnapprovedFulfiller() (gas: 459637) +IntegrationTestCaveats:testRefinanceWCaveatsInvalidSalt() (gas: 380750) +IntegrationTestCaveats:testRefinanceWLenderApproval() (gas: 405252) PausableNonReentrantImpl:test() (gas: 2442) PausableNonReentrantImpl:testReentrancy() (gas: 2735) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1021044) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 727610) -TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 1404935) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1021149) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 727571) +TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 1404896) TestAstariaV1Pricing:testGetRefiannceConsiderationValidEqualRate() (gas: 146135) TestAstariaV1Pricing:testGetRefiannceConsiderationValidHigherRate() (gas: 158343) TestAstariaV1Pricing:testGetRefiannceConsiderationValidLowerRate() (gas: 153372) @@ -25,26 +25,26 @@ TestAstariaV1Pricing:testGetRefinanceConsiderationAsBorrowerZeroRate() (gas: 811 TestAstariaV1Pricing:testGetRefinanceConsiderationInsufficientRefinance() (gas: 108010) TestAstariaV1Pricing:testGetRefinanceConsiderationInvalidRefinance() (gas: 88264) TestAstariaV1Pricing:testGetRefinanceConsiderationZeroRate() (gas: 138753) -TestAstariaV1Settlement:testGetAuctionStart() (gas: 433653) -TestAstariaV1Settlement:testGetAuctionStartNotStarted() (gas: 433226) -TestAstariaV1Settlement:testGetCurrentAuctionPrice() (gas: 448437) -TestAstariaV1Settlement:testGetCurrentAuctionPriceNoAuction() (gas: 436790) -TestAstariaV1Settlement:testGetSettlementDutchAuctionSettlementAbove() (gas: 490359) -TestAstariaV1Settlement:testGetSettlementFailedDutchAuction() (gas: 448827) -TestAstariaV1Settlement:testGetSettlementLoanNotRecalled() (gas: 439333) -TestAstariaV1Settlement:testV1SettlementHandlerValidate() (gas: 419903) -TestAstariaV1Settlement:testV1SettlementHandlerValidateInvalidHandler() (gas: 420027) -TestAstariaV1Status:testCannotRecallTwice() (gas: 580032) -TestAstariaV1Status:testCannotWithdrawLoanHasNotBeenRefinanced() (gas: 425604) -TestAstariaV1Status:testCannotWithdrawWithdrawDoesNotExist() (gas: 432033) -TestAstariaV1Status:testGenerateRecallConsideration() (gas: 481274) -TestAstariaV1Status:testInvalidRecallInvalidStakeType() (gas: 507301) -TestAstariaV1Status:testInvalidRecallLoanDoesNotExist() (gas: 523544) -TestAstariaV1Status:testIsActive() (gas: 432647) -TestAstariaV1Status:testIsRecalledInsideWindow() (gas: 570785) -TestAstariaV1Status:testIsRecalledOutsideWindow() (gas: 568686) -TestAstariaV1Status:testRecallRateActiveRecall() (gas: 556515) -TestAstariaV1Status:testRecallRateEmptyRecall() (gas: 430301) +TestAstariaV1Settlement:testGetAuctionStart() (gas: 433743) +TestAstariaV1Settlement:testGetAuctionStartNotStarted() (gas: 433316) +TestAstariaV1Settlement:testGetCurrentAuctionPrice() (gas: 448527) +TestAstariaV1Settlement:testGetCurrentAuctionPriceNoAuction() (gas: 436880) +TestAstariaV1Settlement:testGetSettlementDutchAuctionSettlementAbove() (gas: 490449) +TestAstariaV1Settlement:testGetSettlementFailedDutchAuction() (gas: 448917) +TestAstariaV1Settlement:testGetSettlementLoanNotRecalled() (gas: 439423) +TestAstariaV1Settlement:testV1SettlementHandlerValidate() (gas: 419993) +TestAstariaV1Settlement:testV1SettlementHandlerValidateInvalidHandler() (gas: 420117) +TestAstariaV1Status:testCannotRecallTwice() (gas: 580122) +TestAstariaV1Status:testCannotWithdrawLoanHasNotBeenRefinanced() (gas: 425694) +TestAstariaV1Status:testCannotWithdrawWithdrawDoesNotExist() (gas: 432123) +TestAstariaV1Status:testGenerateRecallConsideration() (gas: 481364) +TestAstariaV1Status:testInvalidRecallInvalidStakeType() (gas: 507391) +TestAstariaV1Status:testInvalidRecallLoanDoesNotExist() (gas: 523634) +TestAstariaV1Status:testIsActive() (gas: 432737) +TestAstariaV1Status:testIsRecalledInsideWindow() (gas: 570875) +TestAstariaV1Status:testIsRecalledOutsideWindow() (gas: 568776) +TestAstariaV1Status:testRecallRateActiveRecall() (gas: 556605) +TestAstariaV1Status:testRecallRateEmptyRecall() (gas: 430391) TestBorrowerEnforcer:testBERevertAdditionalTransfers() (gas: 73195) TestBorrowerEnforcer:testBERevertInvalidLoanTerms() (gas: 78316) TestBorrowerEnforcer:testBEValidLoanTerms() (gas: 69518) @@ -54,108 +54,107 @@ TestCompoundInterest:testRateMax() (gas: 68106) TestCompoundInterest:testRateTooLowOne() (gas: 73157) TestCompoundInterest:testRateTooLowZero() (gas: 68419) TestCustodian:testCannotLazyMintTwice() (gas: 76753) -TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 66906) -TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 72468) -TestCustodian:testCustodySelector() (gas: 2820937) -TestCustodian:testDefaultCustodySelectorRevert() (gas: 70083) -TestCustodian:testGenerateOrderInvalidPostRepayment() (gas: 173958) -TestCustodian:testGenerateOrderInvalidPostSettlement() (gas: 158618) -TestCustodian:testGenerateOrderRepay() (gas: 177948) -TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 194104) -TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 843321) -TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 757695) -TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 522764) +TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 66884) +TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 72556) +TestCustodian:testCustodySelector() (gas: 2820915) +TestCustodian:testDefaultCustodySelectorRevert() (gas: 70061) +TestCustodian:testGenerateOrderInvalidPostRepayment() (gas: 171281) +TestCustodian:testGenerateOrderInvalidPostSettlement() (gas: 155941) +TestCustodian:testGenerateOrderRepay() (gas: 175271) +TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 191405) +TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 827047) +TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 744382) TestCustodian:testGenerateOrderRepayInvalidHookAddress() (gas: 90248) TestCustodian:testGenerateOrderRepayInvalidHookReturnType() (gas: 84652) -TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 99170) -TestCustodian:testGenerateOrderSettlement() (gas: 150297) -TestCustodian:testGenerateOrderSettlementHandlerAuthorized() (gas: 155854) -TestCustodian:testGenerateOrderSettlementNoActiveLoan() (gas: 155880) -TestCustodian:testGenerateOrderSettlementUnauthorized() (gas: 94410) -TestCustodian:testGenerateOrdersWithLoanStartAtBlockTimestampInvalidLoan() (gas: 452995) -TestCustodian:testGetBorrower() (gas: 76344) -TestCustodian:testInvalidAction() (gas: 114542) +TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 99148) +TestCustodian:testGenerateOrderSettlement() (gas: 147620) +TestCustodian:testGenerateOrderSettlementHandlerAuthorized() (gas: 153177) +TestCustodian:testGenerateOrderSettlementNoActiveLoan() (gas: 155828) +TestCustodian:testGenerateOrderSettlementUnauthorized() (gas: 94388) +TestCustodian:testGenerateOrdersWithLoanStartAtBlockTimestampInvalidLoan() (gas: 452795) +TestCustodian:testGetBorrower() (gas: 76322) +TestCustodian:testInvalidAction() (gas: 114520) TestCustodian:testInvalidActionRepayInActiveLoan() (gas: 117469) TestCustodian:testInvalidActionSettleActiveLoan() (gas: 117429) -TestCustodian:testMintWithApprovalSetAsBorrower() (gas: 356392) +TestCustodian:testMintWithApprovalSetAsBorrower() (gas: 356360) TestCustodian:testMintWithApprovalSetAsBorrowerInvalidLoan() (gas: 58579) TestCustodian:testMintWithApprovalSetNotAuthorized() (gas: 74561) TestCustodian:testName() (gas: 7076) TestCustodian:testNonPayableFunctions() (gas: 212635) TestCustodian:testOnlySeaport() (gas: 17873) -TestCustodian:testPayableFunctions() (gas: 41667) +TestCustodian:testPayableFunctions() (gas: 41645) TestCustodian:testPreviewOrderNoActiveLoan() (gas: 98764) -TestCustodian:testPreviewOrderRepay() (gas: 231269) -TestCustodian:testPreviewOrderSettlement() (gas: 182003) -TestCustodian:testPreviewOrderSettlementInvalidFufliller() (gas: 100823) -TestCustodian:testPreviewOrderSettlementInvalidRepayer() (gas: 106856) -TestCustodian:testRatifyOrder() (gas: 184465) +TestCustodian:testPreviewOrderRepay() (gas: 228570) +TestCustodian:testPreviewOrderSettlement() (gas: 179304) +TestCustodian:testPreviewOrderSettlementInvalidFufliller() (gas: 100931) +TestCustodian:testPreviewOrderSettlementInvalidRepayer() (gas: 106834) +TestCustodian:testRatifyOrder() (gas: 181788) TestCustodian:testSeaportMetadata() (gas: 8545) TestCustodian:testSupportsInterface() (gas: 9428) -TestCustodian:testSymbol() (gas: 7149) -TestCustodian:testTokenURI() (gas: 64817) +TestCustodian:testSymbol() (gas: 7127) +TestCustodian:testTokenURI() (gas: 64906) TestCustodian:testTokenURIInvalidLoan() (gas: 13218) TestLenderEnforcer:testLERevertAdditionalTransfersFromLender() (gas: 73743) TestLenderEnforcer:testLERevertInvalidLoanTerms() (gas: 78341) TestLenderEnforcer:testLEValidLoanTerms() (gas: 69496) TestLenderEnforcer:testLEValidLoanTermsAnyBorrower() (gas: 69494) TestLenderEnforcer:testLEValidLoanTermsWithAdditionalTransfers() (gas: 70740) -TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 543085) -TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 530714) -TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 560908) -TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 550650) -TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 556284) -TestNewLoan:testBuyNowPayLater() (gas: 2832923) -TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 394541) +TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 542758) +TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 530387) +TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 560581) +TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 550323) +TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 556101) +TestNewLoan:testBuyNowPayLater() (gas: 2832773) +TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 394391) TestNewLoan:testNewLoanERC721CollateralLessDebtThanOffered() (gas: 2348) TestNewLoan:testNewLoanRefinanceNew() (gas: 207) -TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 305741) -TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 358465) -TestNewLoan:testSettleLoan() (gas: 611617) +TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 305651) +TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 358345) +TestNewLoan:testSettleLoan() (gas: 611290) TestPausableNonReentrant:testNotOwner() (gas: 21254) TestPausableNonReentrant:testPauseAndUnpause() (gas: 22555) TestPausableNonReentrant:testReentrancy() (gas: 15360) TestPausableNonReentrant:testUnpauseWhenNotPaused() (gas: 12582) TestRefStarportLib:testSpentToReceived() (gas: 13315) TestRefStarportLib:testValidateSalt(address,bytes32) (runs: 256, μ: 33865, ~: 33865) -TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 635539) -TestRepayLoan:testRepayLoanBase() (gas: 571829) -TestRepayLoan:testRepayLoanGenerateOrderNotSeaport() (gas: 402462) -TestRepayLoan:testRepayLoanInSettlement() (gas: 550102) -TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 569889) -TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 843189) +TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 635212) +TestRepayLoan:testRepayLoanBase() (gas: 571502) +TestRepayLoan:testRepayLoanGenerateOrderNotSeaport() (gas: 402312) +TestRepayLoan:testRepayLoanInSettlement() (gas: 549952) +TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 569739) +TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 842802) TestSimpleInterestPricing:test_calculateInterest() (gas: 800891) TestSimpleInterestPricing:test_getPaymentConsideration() (gas: 882219) TestSimpleInterestPricing:test_getRefinanceConsideration() (gas: 876412) TestStarport:testActive() (gas: 67122) -TestStarport:testAdditionalTransfers() (gas: 295920) +TestStarport:testAdditionalTransfers() (gas: 295800) TestStarport:testApplyRefinanceConsiderationToLoanMalformed() (gas: 76450) -TestStarport:testCannotIssueSameLoanTwice() (gas: 337021) +TestStarport:testCannotIssueSameLoanTwice() (gas: 336811) TestStarport:testCannotOriginateWhilePaused() (gas: 70790) -TestStarport:testCannotSettleInvalidLoan() (gas: 72753) +TestStarport:testCannotSettleInvalidLoan() (gas: 72723) TestStarport:testCannotSettleUnlessValidCustodian() (gas: 68866) TestStarport:testCaveatEnforcerRevert() (gas: 124015) -TestStarport:testDefaultFeeRake() (gas: 355025) -TestStarport:testExoticDebtWithNoCaveatsNotAsBorrower() (gas: 371202) +TestStarport:testDefaultFeeRake() (gas: 354905) +TestStarport:testExoticDebtWithNoCaveatsNotAsBorrower() (gas: 371048) TestStarport:testIncrementCaveatNonce() (gas: 34604) TestStarport:testInitializedFlagSetProperly() (gas: 65282) -TestStarport:testInvalidAmountCollateral() (gas: 157864) -TestStarport:testInvalidAmountCollateral721() (gas: 157841) -TestStarport:testInvalidItemType() (gas: 143763) -TestStarport:testInvalidTransferLengthCollateral() (gas: 165920) -TestStarport:testInvalidTransferLengthDebt() (gas: 170490) +TestStarport:testInvalidAmountCollateral() (gas: 157834) +TestStarport:testInvalidAmountCollateral721() (gas: 157811) +TestStarport:testInvalidItemType() (gas: 143733) +TestStarport:testInvalidTransferLengthCollateral() (gas: 165890) +TestStarport:testInvalidTransferLengthDebt() (gas: 170460) TestStarport:testInvalidateCaveatSalt() (gas: 32852) -TestStarport:testName() (gas: 7238) -TestStarport:testNonDefaultCustodianCustodyCallFails() (gas: 195173) -TestStarport:testNonDefaultCustodianCustodyCallSuccess() (gas: 261047) +TestStarport:testName() (gas: 7216) +TestStarport:testNonDefaultCustodianCustodyCallFails() (gas: 195113) +TestStarport:testNonDefaultCustodianCustodyCallSuccess() (gas: 260897) TestStarport:testNonPayableFunctions() (gas: 180435) -TestStarport:testOverrideFeeRake() (gas: 348758) +TestStarport:testOverrideFeeRake() (gas: 348638) TestStarport:testPause() (gas: 17119) TestStarport:testSupportsInterface() (gas: 9203) -TestStarport:testSymbol() (gas: 7171) -TestStarport:testTokenNoCodeCollateral() (gas: 142510) -TestStarport:testTokenNoCodeDebt() (gas: 175638) -TestStarport:testTokenURI() (gas: 64962) +TestStarport:testSymbol() (gas: 7149) +TestStarport:testTokenNoCodeCollateral() (gas: 142480) +TestStarport:testTokenNoCodeDebt() (gas: 175608) +TestStarport:testTokenURI() (gas: 64928) TestStarport:testTokenURIInvalidLoan() (gas: 13307) TestStarport:testTransferFromFail() (gas: 80172) TestStarport:testUnpause() (gas: 16331) @@ -172,6 +171,6 @@ TestStrategistOriginator:testInvalidDebtAmountAskingMoreThanOffered() (gas: 2085 TestStrategistOriginator:testInvalidDebtAmountOfferingZero() (gas: 188880) TestStrategistOriginator:testInvalidDebtAmountRequestingZero() (gas: 208756) TestStrategistOriginator:testInvalidDebtLength() (gas: 207383) -TestStrategistOriginator:testInvalidOffer() (gas: 400847) +TestStrategistOriginator:testInvalidOffer() (gas: 400727) TestStrategistOriginator:testInvalidSigner() (gas: 210594) TestStrategistOriginator:testSetStrategist() (gas: 17818) \ No newline at end of file diff --git a/test/StarportTest.sol b/test/StarportTest.sol index 27681a88..5749648d 100644 --- a/test/StarportTest.sol +++ b/test/StarportTest.sol @@ -61,7 +61,6 @@ import {ERC721} from "solady/src/tokens/ERC721.sol"; import {ERC1155} from "solady/src/tokens/ERC1155.sol"; import {ContractOffererInterface} from "seaport-types/src/interfaces/ContractOffererInterface.sol"; import {TokenReceiverInterface} from "starport-core/interfaces/TokenReceiverInterface.sol"; -import {LoanSettledCallback} from "starport-core/Starport.sol"; import {Actions} from "starport-core/lib/StarportLib.sol"; import {CaveatEnforcer} from "starport-core/enforcers/CaveatEnforcer.sol"; @@ -77,9 +76,7 @@ interface IWETH9 { function withdraw(uint256) external; } -contract MockIssuer is LoanSettledCallback, TokenReceiverInterface { - function onLoanSettled(Starport.Loan memory loan) external {} - +contract MockIssuer is TokenReceiverInterface { function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external override From 03cf17fd266c81cec67e02632cf9d5cbc22c5558 Mon Sep 17 00:00:00 2001 From: Andrew Redden Date: Sat, 4 Nov 2023 15:13:51 -0300 Subject: [PATCH 11/11] remove dead test --- test/unit-testing/TestV1Settlement.sol | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/test/unit-testing/TestV1Settlement.sol b/test/unit-testing/TestV1Settlement.sol index f1ed840b..96d8f641 100644 --- a/test/unit-testing/TestV1Settlement.sol +++ b/test/unit-testing/TestV1Settlement.sol @@ -211,22 +211,6 @@ contract TestAstariaV1Settlement is AstariaV1Test, DeepEq { uint256 currentAuctionPrice = AstariaV1Settlement(loan.terms.settlement).getCurrentAuctionPrice(loan); } - // function testV1SettlementHandlerExecute() public { - // Starport.Terms memory terms = Starport.Terms({ - // status: address(hook), - // settlement: address(settlement), - // pricing: address(pricing), - // pricingData: defaultPricingData, - // settlementData: defaultSettlementData, - // statusData: defaultStatusData - // }); - // Starport.Loan memory loan = - // _createLoan721Collateral20Debt({lender: lender.addr, borrowAmount: 1e18, terms: terms}); - // - // vm.expectRevert(abi.encodeWithSelector(AstariaV1Settlement.ExecuteHandlerNotImplemented.selector)); - // AstariaV1Settlement(loan.terms.settlement).postSettlement(loan, address(this)); - // } - function testV1SettlementHandlerValidate() public { Starport.Terms memory terms = Starport.Terms({ status: address(status),