Skip to content

Commit

Permalink
Feat/compound (#48)
Browse files Browse the repository at this point in the history
* feat: compound interest

* feat: add tests and cleanup

* format & snapshot

---------

Co-authored-by: androolloyd <[email protected]>
  • Loading branch information
dangerousfood and androolloyd authored Nov 3, 2023
1 parent 4fb8308 commit 01e1c26
Show file tree
Hide file tree
Showing 14 changed files with 334 additions and 264 deletions.
180 changes: 91 additions & 89 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,58 +1,62 @@
DiffFuzzTestStarPortLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880457, ~: 882299)
DiffFuzzTestStarPortLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232905, ~: 237832)
IntegrationTestCaveats:testOriginateUnapprovedFulfiller() (gas: 341266)
IntegrationTestCaveats:testOriginateWBorrowerApproval() (gas: 296157)
IntegrationTestCaveats:testOriginateWCaveats() (gas: 272197)
DiffFuzzTestStarPortLib:testSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 880514, ~: 882644)
DiffFuzzTestStarPortLib:testUnboundSpentToReceived((uint8,address,uint256,uint256)[]) (runs: 256, μ: 232893, ~: 237832)
IntegrationTestCaveats:testOriginateUnapprovedFulfiller() (gas: 341364)
IntegrationTestCaveats:testOriginateWBorrowerApproval() (gas: 296255)
IntegrationTestCaveats:testOriginateWCaveats() (gas: 272295)
IntegrationTestCaveats:testOriginateWCaveatsIncrementedNonce() (gas: 200191)
IntegrationTestCaveats:testOriginateWCaveatsInvalidSalt() (gas: 257806)
IntegrationTestCaveats:testOriginateWCaveatsInvalidSalt() (gas: 257950)
IntegrationTestCaveats:testOriginateWCaveatsInvalidSaltManual() (gas: 175868)
IntegrationTestCaveats:testOriginateWLenderApproval() (gas: 296276)
IntegrationTestCaveats:testRefinanceAsLender() (gas: 1056340)
IntegrationTestCaveats:testRefinanceCaveatFailure() (gas: 422075)
IntegrationTestCaveats:testRefinanceUnapprovedFulfiller() (gas: 479978)
IntegrationTestCaveats:testRefinanceWCaveatsInvalidSalt() (gas: 400966)
IntegrationTestCaveats:testRefinanceWLenderApproval() (gas: 423604)
IntegrationTestCaveats:testOriginateWLenderApproval() (gas: 296374)
IntegrationTestCaveats:testRefinanceAsLender() (gas: 1056510)
IntegrationTestCaveats:testRefinanceCaveatFailure() (gas: 422245)
IntegrationTestCaveats:testRefinanceUnapprovedFulfiller() (gas: 480148)
IntegrationTestCaveats:testRefinanceWCaveatsInvalidSalt() (gas: 401136)
IntegrationTestCaveats:testRefinanceWLenderApproval() (gas: 423774)
PausableNonReentrantImpl:test() (gas: 2442)
PausableNonReentrantImpl:testReentrancy() (gas: 2735)
TestAstariaV1Handler:testGetAuctionStart() (gas: 427553)
TestAstariaV1Handler:testGetAuctionStartNotStarted() (gas: 427126)
TestAstariaV1Handler:testGetCurrentAuctionPrice() (gas: 442408)
TestAstariaV1Handler:testGetCurrentAuctionPriceNoAuction() (gas: 430757)
TestAstariaV1Handler:testGetSettlementDutchAuctionSettlementAbove() (gas: 484940)
TestAstariaV1Handler:testGetSettlementFailedDutchAuction() (gas: 442731)
TestAstariaV1Handler:testGetSettlementLoanNotRecalled() (gas: 433233)
TestAstariaV1Handler:testV1SettlementHandlerExecute() (gas: 413740)
TestAstariaV1Handler:testV1SettlementHandlerValidate() (gas: 413852)
TestAstariaV1Handler:testV1SettlementHandlerValidateInvalidHandler() (gas: 413976)
TestAstariaV1Hook:testCannotRecallTwice() (gas: 569694)
TestAstariaV1Hook:testCannotWithdrawLoanHasNotBeenRefinanced() (gas: 419557)
TestAstariaV1Hook:testCannotWithdrawWithdrawDoesNotExist() (gas: 425996)
TestAstariaV1Hook:testGenerateRecallConsideration() (gas: 469070)
TestAstariaV1Hook:testInvalidRecallInvalidStakeType() (gas: 486195)
TestAstariaV1Hook:testInvalidRecallLoanDoesNotExist() (gas: 515422)
TestAstariaV1Hook:testIsActive() (gas: 426738)
TestAstariaV1Hook:testIsRecalledInsideWindow() (gas: 562926)
TestAstariaV1Hook:testIsRecalledOutsideWindow() (gas: 560827)
TestAstariaV1Hook:testRecallRateActiveRecall() (gas: 548487)
TestAstariaV1Hook:testRecallRateEmptyRecall() (gas: 424392)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1016002)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 719993)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 747659)
TestAstariaV1Handler:testGetAuctionStart() (gas: 433724)
TestAstariaV1Handler:testGetAuctionStartNotStarted() (gas: 433297)
TestAstariaV1Handler:testGetCurrentAuctionPrice() (gas: 448579)
TestAstariaV1Handler:testGetCurrentAuctionPriceNoAuction() (gas: 436928)
TestAstariaV1Handler:testGetSettlementDutchAuctionSettlementAbove() (gas: 490549)
TestAstariaV1Handler:testGetSettlementFailedDutchAuction() (gas: 448902)
TestAstariaV1Handler:testGetSettlementLoanNotRecalled() (gas: 439404)
TestAstariaV1Handler:testV1SettlementHandlerExecute() (gas: 419911)
TestAstariaV1Handler:testV1SettlementHandlerValidate() (gas: 420023)
TestAstariaV1Handler:testV1SettlementHandlerValidateInvalidHandler() (gas: 420147)
TestAstariaV1Hook:testCannotRecallTwice() (gas: 580637)
TestAstariaV1Hook:testCannotWithdrawLoanHasNotBeenRefinanced() (gas: 425728)
TestAstariaV1Hook:testCannotWithdrawWithdrawDoesNotExist() (gas: 432167)
TestAstariaV1Hook:testGenerateRecallConsideration() (gas: 481691)
TestAstariaV1Hook:testInvalidRecallInvalidStakeType() (gas: 507972)
TestAstariaV1Hook:testInvalidRecallLoanDoesNotExist() (gas: 523979)
TestAstariaV1Hook:testIsActive() (gas: 432909)
TestAstariaV1Hook:testIsRecalledInsideWindow() (gas: 571483)
TestAstariaV1Hook:testIsRecalledOutsideWindow() (gas: 569384)
TestAstariaV1Hook:testRecallRateActiveRecall() (gas: 557044)
TestAstariaV1Hook:testRecallRateEmptyRecall() (gas: 430563)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallBase() (gas: 1043573)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 728313)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 767096)
TestBorrowerEnforcer:testBERevertAdditionalTransfers() (gas: 73195)
TestBorrowerEnforcer:testBERevertInvalidLoanTerms() (gas: 78316)
TestBorrowerEnforcer:testBEValidLoanTerms() (gas: 69518)
TestBorrowerEnforcer:testBEValidLoanTermsAnyIssuer() (gas: 69581)
TestCompoundInterest:testAmountMax() (gas: 65767)
TestCompoundInterest:testRateMax() (gas: 68106)
TestCompoundInterest:testRateTooLowOne() (gas: 73157)
TestCompoundInterest:testRateTooLowZero() (gas: 68419)
TestCustodian:testCannotLazyMintTwice() (gas: 76589)
TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 66861)
TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 72392)
TestCustodian:testCustodySelector() (gas: 2718590)
TestCustodian:testDefaultCustodySelectorRevert() (gas: 70083)
TestCustodian:testGenerateOrderInvalidHandlerExecution() (gas: 133022)
TestCustodian:testGenerateOrderRepay() (gas: 173924)
TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 199549)
TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 868168)
TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 793746)
TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 532529)
TestCustodian:testGenerateOrderRepay() (gas: 174635)
TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 200260)
TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNative() (gas: 869852)
TestCustodian:testGenerateOrderRepayERC1155AndERC20AndNativeHandlerAuthorized() (gas: 794008)
TestCustodian:testGenerateOrderRepayERC1155WithRevert() (gas: 533358)
TestCustodian:testGenerateOrderRepayInvalidHookAddress() (gas: 90307)
TestCustodian:testGenerateOrderRepayInvalidHookReturnType() (gas: 84624)
TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 96398)
Expand All @@ -69,11 +73,11 @@ TestCustodian:testNonPayableFunctions() (gas: 225770)
TestCustodian:testOnlySeaport() (gas: 17895)
TestCustodian:testPayableFunctions() (gas: 41667)
TestCustodian:testPreviewOrderNoActiveLoan() (gas: 98628)
TestCustodian:testPreviewOrderRepay() (gas: 225769)
TestCustodian:testPreviewOrderRepay() (gas: 227191)
TestCustodian:testPreviewOrderSettlement() (gas: 183136)
TestCustodian:testPreviewOrderSettlementInvalidFufliller() (gas: 100751)
TestCustodian:testPreviewOrderSettlementInvalidRepayer() (gas: 106676)
TestCustodian:testRatifyOrder() (gas: 180093)
TestCustodian:testRatifyOrder() (gas: 180804)
TestCustodian:testSeaportMetadata() (gas: 8567)
TestCustodian:testSetRepayApproval() (gas: 37861)
TestCustodian:testSupportsInterface() (gas: 9428)
Expand All @@ -85,67 +89,65 @@ TestLenderEnforcer:testLERevertInvalidLoanTerms() (gas: 78341)
TestLenderEnforcer:testLEValidLoanTerms() (gas: 69496)
TestLenderEnforcer:testLEValidLoanTermsAnyBorrower() (gas: 69494)
TestLenderEnforcer:testLEValidLoanTermsWithAdditionalTransfers() (gas: 70740)
TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 555315)
TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 542898)
TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 573042)
TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 562881)
TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 568355)
TestLoanManager:testActive() (gas: 67048)
TestLoanManager:testAdditionalTransfers() (gas: 295623)
TestLoanManager:testCannotIssueSameLoanTwice() (gas: 336855)
TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 556835)
TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 544464)
TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 574562)
TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 564401)
TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 569877)
TestLoanManager:testActive() (gas: 67003)
TestLoanManager:testAdditionalTransfers() (gas: 296003)
TestLoanManager:testCannotIssueSameLoanTwice() (gas: 337165)
TestLoanManager:testCannotOriginateWhilePaused() (gas: 70834)
TestLoanManager:testCannotSettleInvalidLoan() (gas: 72745)
TestLoanManager:testCannotSettleUnlessValidCustodian() (gas: 68816)
TestLoanManager:testCaveatEnforcerRevert() (gas: 124049)
TestLoanManager:testDefaultFeeRake() (gas: 355038)
TestLoanManager:testExoticDebtWithNoCaveatsNotAsBorrower() (gas: 371270)
TestLoanManager:testIncrementCaveatNonce() (gas: 34560)
TestLoanManager:testCannotSettleUnlessValidCustodian() (gas: 68838)
TestLoanManager:testCaveatEnforcerRevert() (gas: 124071)
TestLoanManager:testDefaultFeeRake() (gas: 355208)
TestLoanManager:testExoticDebtWithNoCaveatsNotAsBorrower() (gas: 371351)
TestLoanManager:testIncrementCaveatNonce() (gas: 34582)
TestLoanManager:testInitializedFlagSetProperly() (gas: 65344)
TestLoanManager:testInvalidAmountCollateral() (gas: 157784)
TestLoanManager:testInvalidAmountCollateral721() (gas: 157949)
TestLoanManager:testInvalidAmountDebt() (gas: 182139)
TestLoanManager:testInvalidIdentifierDebt() (gas: 202133)
TestLoanManager:testInvalidItemType() (gas: 143832)
TestLoanManager:testInvalidTransferLengthCollateral() (gas: 166018)
TestLoanManager:testInvalidTransferLengthDebt() (gas: 170605)
TestLoanManager:testInvalidateCaveatSalt() (gas: 32830)
TestLoanManager:testInvalidAmountCollateral() (gas: 157920)
TestLoanManager:testInvalidAmountCollateral721() (gas: 157897)
TestLoanManager:testInvalidItemType() (gas: 143819)
TestLoanManager:testInvalidTransferLengthCollateral() (gas: 165976)
TestLoanManager:testInvalidTransferLengthDebt() (gas: 170546)
TestLoanManager:testInvalidateCaveatSalt() (gas: 32852)
TestLoanManager:testIssued() (gas: 67216)
TestLoanManager:testName() (gas: 7206)
TestLoanManager:testNonDefaultCustodianCustodyCallFails() (gas: 195269)
TestLoanManager:testNonDefaultCustodianCustodyCallSuccess() (gas: 261010)
TestLoanManager:testName() (gas: 7228)
TestLoanManager:testNonDefaultCustodianCustodyCallFails() (gas: 195229)
TestLoanManager:testNonDefaultCustodianCustodyCallSuccess() (gas: 261108)
TestLoanManager:testNonPayableFunctions() (gas: 180369)
TestLoanManager:testOverrideFeeRake() (gas: 348799)
TestLoanManager:testPause() (gas: 17164)
TestLoanManager:testOverrideFeeRake() (gas: 348919)
TestLoanManager:testPause() (gas: 17208)
TestLoanManager:testSupportsInterface() (gas: 9181)
TestLoanManager:testSymbol() (gas: 7257)
TestLoanManager:testTokenNoCodeCollateral() (gas: 142648)
TestLoanManager:testTokenNoCodeDebt() (gas: 175748)
TestLoanManager:testTokenURI() (gas: 64879)
TestLoanManager:testSymbol() (gas: 7279)
TestLoanManager:testTokenNoCodeCollateral() (gas: 142676)
TestLoanManager:testTokenNoCodeDebt() (gas: 175694)
TestLoanManager:testTokenURI() (gas: 64923)
TestLoanManager:testTokenURIInvalidLoan() (gas: 13296)
TestLoanManager:testTransferFromFail() (gas: 80110)
TestLoanManager:testUnpause() (gas: 16199)
TestNewLoan:testBuyNowPayLater() (gas: 2832660)
TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 394514)
TestLoanManager:testUnpause() (gas: 16221)
TestNewLoan:testBuyNowPayLater() (gas: 2832994)
TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 394612)
TestNewLoan:testNewLoanERC721CollateralLessDebtThanOffered() (gas: 2348)
TestNewLoan:testNewLoanRefinanceNew() (gas: 207)
TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 301900)
TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 356531)
TestNewLoan:testSettleLoan() (gas: 630607)
TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 301998)
TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 356629)
TestNewLoan:testSettleLoan() (gas: 628057)
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: 646307)
TestRepayLoan:testRepayLoanBase() (gas: 582601)
TestRepayLoan:testRepayLoanGenerateOrderNotSeaport() (gas: 402435)
TestRepayLoan:testRepayLoanInSettlement() (gas: 545252)
TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 562730)
TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 851564)
TestSimpleInterestPricing:test_calculateInterest() (gas: 780091)
TestSimpleInterestPricing:test_getPaymentConsideration() (gas: 862975)
TestSimpleInterestPricing:test_isValidRefinance() (gas: 857743)
TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 649261)
TestRepayLoan:testRepayLoanBase() (gas: 585555)
TestRepayLoan:testRepayLoanGenerateOrderNotSeaport() (gas: 402533)
TestRepayLoan:testRepayLoanInSettlement() (gas: 549847)
TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 564256)
TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 856651)
TestSimpleInterestPricing:test_calculateInterest() (gas: 808104)
TestSimpleInterestPricing:test_getPaymentConsideration() (gas: 889542)
TestSimpleInterestPricing:test_isValidRefinance() (gas: 883589)
TestStarPortLib:testSpentToReceived() (gas: 13315)
TestStarPortLib:testValidateSalt(address,bytes32) (runs: 256, μ: 33865, ~: 33865)
TestStrategistOriginator:testEncodeWithAccountCounter() (gas: 12307)
Expand All @@ -159,6 +161,6 @@ TestStrategistOriginator:testInvalidDebtAmountAskingMoreThanOffered() (gas: 2066
TestStrategistOriginator:testInvalidDebtAmountOfferingZero() (gas: 187017)
TestStrategistOriginator:testInvalidDebtAmountRequestingZero() (gas: 206893)
TestStrategistOriginator:testInvalidDebtLength() (gas: 205520)
TestStrategistOriginator:testInvalidOffer() (gas: 398913)
TestStrategistOriginator:testInvalidOffer() (gas: 399011)
TestStrategistOriginator:testInvalidSigner() (gas: 208731)
TestStrategistOriginator:testSetStrategist() (gas: 17818)
68 changes: 6 additions & 62 deletions src/LoanManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,6 @@ contract LoanManager is ERC721, PausableNonReentrant {
error InvalidRefinance();
error InvalidCustodian();
error InvalidLoan();
error InvalidItemAmount();
error InvalidItemIdentifier(); //must be zero for ERC20's
error InvalidItemTokenNoCode();
error InvalidItemType();
error InvalidTransferLength();
error CannotTransferLoans();
error AdditionalTransferError();
error LoanExists();
Expand Down Expand Up @@ -198,17 +193,17 @@ contract LoanManager is ERC721, PausableNonReentrant {
_validateAndEnforceCaveats(lenderCaveat, issuer, additionalTransfers, loan);
}

_transferSpentItems(loan.collateral, borrower, loan.custodian);
StarPortLib.transferSpentItems(loan.collateral, borrower, loan.custodian, true);

_callCustody(loan);
if (feeRecipient == address(0)) {
_transferSpentItems(loan.debt, issuer, borrower);
StarPortLib.transferSpentItems(loan.debt, issuer, borrower, false);
} else {
(SpentItem[] memory feeItems, SpentItem[] memory sentToBorrower) = _feeRake(loan.debt);
if (feeItems.length > 0) {
_transferSpentItems(feeItems, issuer, feeRecipient);
StarPortLib.transferSpentItems(feeItems, issuer, feeRecipient, false);
}
_transferSpentItems(sentToBorrower, issuer, borrower);
StarPortLib.transferSpentItems(sentToBorrower, issuer, borrower, false);
}

if (additionalTransfers.length > 0) {
Expand All @@ -235,10 +230,9 @@ contract LoanManager is ERC721, PausableNonReentrant {
_settle(loan);
loan = applyRefinanceConsiderationToLoan(loan, considerationPayment, carryPayment, pricingData);

_transferSpentItems(considerationPayment, lender, loan.issuer);

StarPortLib.transferSpentItems(considerationPayment, lender, loan.issuer, false);
if (carryPayment.length > 0) {
_transferSpentItems(carryPayment, lender, loan.originator);
StarPortLib.transferSpentItems(carryPayment, lender, loan.originator, false);
}

loan.issuer = lender;
Expand Down Expand Up @@ -378,56 +372,6 @@ contract LoanManager is ERC721, PausableNonReentrant {
}
}

function _transferItem(
ItemType itemType,
address token,
uint256 identifier,
uint256 amount,
address from,
address to
) internal {
if (token.code.length == 0) {
revert InvalidItemTokenNoCode();
}
if (amount > 0) {
if (itemType == ItemType.ERC20) {
if (identifier > 0) {
revert InvalidItemIdentifier();
}
SafeTransferLib.safeTransferFrom(token, from, to, amount);
} else if (itemType == ItemType.ERC721) {
// erc721 transfer
if (amount > 1) {
revert InvalidItemAmount();
}
ERC721(token).transferFrom(from, to, identifier);
} else if (itemType == ItemType.ERC1155) {
// erc1155 transfer
ERC1155(token).safeTransferFrom(from, to, identifier, amount, new bytes(0));
} else {
revert InvalidItemType();
}
} else {
revert InvalidItemAmount();
}
}

function _transferSpentItems(SpentItem[] memory transfers, address from, address to) internal {
if (transfers.length > 0) {
uint256 i = 0;
for (i; i < transfers.length;) {
_transferItem(
transfers[i].itemType, transfers[i].token, transfers[i].identifier, transfers[i].amount, from, to
);
unchecked {
++i;
}
}
} else {
revert InvalidTransferLength();
}
}

function hashCaveatWithSaltAndNonce(address validator, bytes32 salt, CaveatEnforcer.Caveat[] calldata caveat)
public
view
Expand Down
Loading

0 comments on commit 01e1c26

Please sign in to comment.