From 748326b72101e4e0073d794f5772ac4afe78ef3a Mon Sep 17 00:00:00 2001 From: Joseph Delong Date: Wed, 24 Jan 2024 21:28:09 -0600 Subject: [PATCH] Fix/audit fixes round 8 (#95) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: validate that window is not zero i nthe valdiate method * fix: I-10. maximumSpent isn’t used on Custodian.generateOrder and can be removed * fix: activeUserDataHash unused in BNPLHelper * fix: M-3. Error-prone string casting for tokenURI * fix: strategist fee unused * fix: remove mentions of loan manager * fix: remove mention of fee * fix: remove address(this) in params for call to transferSpentItemsSelf * fix: gas optimization of assignment * fix: gas snapshot --- .gas-snapshot | 159 +++++++++--------- src/BNPLHelper.sol | 20 +-- src/Custodian.sol | 11 +- src/lib/StarportLib.sol | 14 +- src/originators/StrategistOriginator.sol | 28 ++- src/pricing/BasePricing.sol | 3 +- src/settlement/DutchAuctionSettlement.sol | 6 +- test/StarportTest.sol | 2 +- test/unit-testing/TestCustodian.sol | 2 +- test/unit-testing/TestStarport.sol | 8 +- .../unit-testing/TestStrategistOriginator.sol | 7 - 11 files changed, 120 insertions(+), 140 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 12013561..17ffae23 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -16,94 +16,94 @@ IntegrationTestCaveats:testRefinanceWCaveatsInvalidSalt() (gas: 377260) IntegrationTestCaveats:testRefinanceWLenderApproval() (gas: 402978) ModuleTesting:testFixedTermDutchAuctionSettlement() (gas: 438123) ModuleTesting:testFixedTermDutchAuctionSettlementAuctionNotStarted() (gas: 441499) -ModuleTesting:testFixedTermDutchAuctionSettlementGetSettlementAuctionExpired() (gas: 440948) -ModuleTesting:testFixedTermDutchAuctionSettlementNotValid() (gas: 437157) -ModuleTesting:testFixedTermDutchAuctionSettlementValid() (gas: 438044) -ModuleTesting:testModuleValidation() (gas: 1274344) +ModuleTesting:testFixedTermDutchAuctionSettlementGetSettlementAuctionExpired() (gas: 440892) +ModuleTesting:testFixedTermDutchAuctionSettlementNotValid() (gas: 437177) +ModuleTesting:testFixedTermDutchAuctionSettlementValid() (gas: 438084) +ModuleTesting:testModuleValidation() (gas: 1262975) PausableNonReentrantImpl:test() (gas: 2464) PausableNonReentrantImpl:testReentrancy() (gas: 2757) TestBorrowerEnforcer:testBERevertAdditionalTransfersFromBorrower() (gas: 76462) TestBorrowerEnforcer:testBERevertInvalidLoanTerms() (gas: 81160) TestBorrowerEnforcer:testBEValidLoanTerms() (gas: 72257) TestBorrowerEnforcer:testBEValidLoanTermsAnyIssuer() (gas: 72343) -TestCustodian:testCannotLazyMintTwice() (gas: 82123) -TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 72495) -TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 77961) -TestCustodian:testCustodianCannotBeAuthorized() (gas: 142120) -TestCustodian:testCustodySelector() (gas: 2731962) +TestCustodian:testCannotLazyMintTwice() (gas: 82105) +TestCustodian:testCannotMintInvalidLoanInvalidCustodian() (gas: 72477) +TestCustodian:testCannotMintInvalidLoanValidCustodian() (gas: 77943) +TestCustodian:testCustodianCannotBeAuthorized() (gas: 141967) +TestCustodian:testCustodySelector() (gas: 2717132) TestCustodian:testDefaultCustodySelectorRevert() (gas: 72478) -TestCustodian:testGenerateOrderInvalidPostRepayment() (gas: 173134) -TestCustodian:testGenerateOrderInvalidPostSettlement() (gas: 163297) -TestCustodian:testGenerateOrderRepay() (gas: 177292) -TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 193778) -TestCustodian:testGenerateOrderRepayERC1155AndERC20() (gas: 876355) -TestCustodian:testGenerateOrderRepayERC1155AndERC20HandlerAuthorized() (gas: 804921) -TestCustodian:testGenerateOrderRepayInvalidHookAddress() (gas: 97670) -TestCustodian:testGenerateOrderRepayInvalidHookReturnType() (gas: 92031) -TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 106909) -TestCustodian:testGenerateOrderSettlement() (gas: 155008) -TestCustodian:testGenerateOrderSettlementHandlerAuthorized() (gas: 160405) -TestCustodian:testGenerateOrderSettlementNoActiveLoan() (gas: 163475) -TestCustodian:testGenerateOrderSettlementUnauthorized() (gas: 101874) -TestCustodian:testGenerateOrdersWithLoanStartAtBlockTimestampInvalidLoan() (gas: 461703) -TestCustodian:testGetBorrower() (gas: 78621) -TestCustodian:testInvalidAction() (gas: 173464) -TestCustodian:testInvalidActionRepayInActiveLoan() (gas: 130152) -TestCustodian:testInvalidActionSettleActiveLoan() (gas: 130090) +TestCustodian:testGenerateOrderInvalidPostRepayment() (gas: 172899) +TestCustodian:testGenerateOrderInvalidPostSettlement() (gas: 163178) +TestCustodian:testGenerateOrderRepay() (gas: 177059) +TestCustodian:testGenerateOrderRepayAsRepayApprovedBorrower() (gas: 193527) +TestCustodian:testGenerateOrderRepayERC1155AndERC20() (gas: 875677) +TestCustodian:testGenerateOrderRepayERC1155AndERC20HandlerAuthorized() (gas: 804495) +TestCustodian:testGenerateOrderRepayInvalidHookAddress() (gas: 97556) +TestCustodian:testGenerateOrderRepayInvalidHookReturnType() (gas: 91917) +TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 106827) +TestCustodian:testGenerateOrderSettlement() (gas: 154891) +TestCustodian:testGenerateOrderSettlementHandlerAuthorized() (gas: 160288) +TestCustodian:testGenerateOrderSettlementNoActiveLoan() (gas: 163374) +TestCustodian:testGenerateOrderSettlementUnauthorized() (gas: 101809) +TestCustodian:testGenerateOrdersWithLoanStartAtBlockTimestampInvalidLoan() (gas: 461511) +TestCustodian:testGetBorrower() (gas: 78603) +TestCustodian:testInvalidAction() (gas: 179690) +TestCustodian:testInvalidActionRepayInActiveLoan() (gas: 130036) +TestCustodian:testInvalidActionSettleActiveLoan() (gas: 129973) TestCustodian:testInvalidEncodedData() (gas: 26160) -TestCustodian:testMintWithApprovalSetAsBorrower() (gas: 366758) -TestCustodian:testMintWithApprovalSetAsBorrowerInvalidLoan() (gas: 64523) +TestCustodian:testMintWithApprovalSetAsBorrower() (gas: 366740) +TestCustodian:testMintWithApprovalSetAsBorrowerInvalidLoan() (gas: 64505) TestCustodian:testMintWithApprovalSetNotAuthorized() (gas: 66842) -TestCustodian:testName() (gas: 7099) +TestCustodian:testName() (gas: 7077) TestCustodian:testNonPayableFunctions() (gas: 215289) TestCustodian:testOnlySeaport() (gas: 17918) -TestCustodian:testPreviewOrderNoActiveLoan() (gas: 105688) -TestCustodian:testPreviewOrderRepay() (gas: 230231) -TestCustodian:testPreviewOrderSettlement() (gas: 191959) -TestCustodian:testPreviewOrderSettlementInvalidFufliller() (gas: 108249) -TestCustodian:testPreviewOrderSettlementInvalidRepayer() (gas: 116960) -TestCustodian:testRatifyOrder() (gas: 184113) -TestCustodian:testSeaportMetadata() (gas: 8644) +TestCustodian:testPreviewOrderNoActiveLoan() (gas: 105670) +TestCustodian:testPreviewOrderRepay() (gas: 229793) +TestCustodian:testPreviewOrderSettlement() (gas: 191754) +TestCustodian:testPreviewOrderSettlementInvalidFufliller() (gas: 108161) +TestCustodian:testPreviewOrderSettlementInvalidRepayer() (gas: 116854) +TestCustodian:testRatifyOrder() (gas: 183880) +TestCustodian:testSeaportMetadata() (gas: 8588) TestCustodian:testSupportsInterface() (gas: 9428) -TestCustodian:testSymbol() (gas: 7216) -TestCustodian:testTokenURI() (gas: 85150) +TestCustodian:testSymbol() (gas: 7194) +TestCustodian:testTokenURI() (gas: 85244) TestCustodian:testTokenURIInvalidLoan() (gas: 13179) TestLenderEnforcer:testLERevertAdditionalTransfersFromLender() (gas: 76455) TestLenderEnforcer:testLERevertInvalidLoanTerms() (gas: 81096) TestLenderEnforcer:testLEValidLoanTerms() (gas: 72169) TestLenderEnforcer:testLEValidLoanTermsAnyBorrower() (gas: 72234) TestLenderEnforcer:testLEValidLoanTermsWithAdditionalTransfers() (gas: 73525) -TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 592934) -TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 600147) -TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 590365) -TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 580182) -TestNewLoan:testBuyNowPayLater() (gas: 3018529) -TestNewLoan:testNewLoanAs1271ProxyAccountSender() (gas: 874195) -TestNewLoan:testNewLoanAs1271ProxyAccountThirdPartyFiller() (gas: 885220) +TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 592496) +TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 599709) +TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 589927) +TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 579744) +TestNewLoan:testBuyNowPayLater() (gas: 3018513) +TestNewLoan:testNewLoanAs1271ProxyAccountSender() (gas: 874179) +TestNewLoan:testNewLoanAs1271ProxyAccountThirdPartyFiller() (gas: 885204) TestNewLoan:testNewLoanERC721CollateralDefaultTerms2() (gas: 429635) -TestNewLoan:testNewLoanRefinance() (gas: 590070) -TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 324676) -TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 383472) -TestNewLoan:testSettleLoan() (gas: 642281) +TestNewLoan:testNewLoanRefinance() (gas: 589971) +TestNewLoan:testNewLoanViaOriginatorBorrowerApprovalAndLenderApproval() (gas: 324707) +TestNewLoan:testNewLoanViaOriginatorLenderApproval() (gas: 383503) +TestNewLoan:testSettleLoan() (gas: 642156) TestPausableNonReentrant:testNotOwner() (gas: 21276) TestPausableNonReentrant:testPauseAndUnpause() (gas: 22643) TestPausableNonReentrant:testReentrancy() (gas: 15404) TestPausableNonReentrant:testUnpauseWhenNotPaused() (gas: 12604) -TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 667145) -TestRepayLoan:testRepayLoanBase() (gas: 599975) +TestRepayLoan:testRepayLoanApprovedRepayer() (gas: 666673) +TestRepayLoan:testRepayLoanBase() (gas: 599539) TestRepayLoan:testRepayLoanGenerateOrderNotSeaport() (gas: 438777) -TestRepayLoan:testRepayLoanInSettlement() (gas: 585811) -TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 604010) -TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 858771) -TestSimpleInterestPricing:test_calculateInterest() (gas: 881296) -TestSimpleInterestPricing:test_getPaymentConsideration() (gas: 928510) -TestSimpleInterestPricing:test_getRefinanceConsideration() (gas: 919314) +TestRepayLoan:testRepayLoanInSettlement() (gas: 585633) +TestRepayLoan:testRepayLoanInvalidRepayer() (gas: 603643) +TestRepayLoan:testRepayLoanThatDoesNotExist() (gas: 857698) +TestSimpleInterestPricing:test_calculateInterest() (gas: 869870) +TestSimpleInterestPricing:test_getPaymentConsideration() (gas: 916886) +TestSimpleInterestPricing:test_getRefinanceConsideration() (gas: 907796) TestStarport:testAcquireTokensFail() (gas: 60473) -TestStarport:testAcquireTokensSuccess() (gas: 163042) +TestStarport:testAcquireTokensSuccess() (gas: 162844) TestStarport:testActive() (gas: 69358) TestStarport:testAdditionalTransfers() (gas: 300755) TestStarport:testAdditionalTransfersOriginate() (gas: 275540) -TestStarport:testAdditionalTransfersRefinance() (gas: 218206) +TestStarport:testAdditionalTransfersRefinance() (gas: 218107) TestStarport:testApplyRefinanceConsiderationToLoanMalformed() (gas: 129484) TestStarport:testCannotIssueSameLoanTwice() (gas: 364125) TestStarport:testCannotOriginateWhilePaused() (gas: 73479) @@ -112,16 +112,16 @@ TestStarport:testCannotSettleUnlessValidCustodian() (gas: 71007) TestStarport:testCaveatEnforcerRevert() (gas: 102601) TestStarport:testDefaultFeeRake1() (gas: 383458) TestStarport:testDefaultFeeRake2() (gas: 445821) -TestStarport:testDefaultFeeRakeExoticDebt() (gas: 394564) +TestStarport:testDefaultFeeRakeExoticDebt() (gas: 394368) TestStarport:testEIP712Signing() (gas: 83109) TestStarport:testExcessiveFeeRake() (gas: 19992) TestStarport:testExoticDebtWithCustomPricingAndRepayment() (gas: 1237783) -TestStarport:testExoticDebtWithCustomPricingAndSettlement() (gas: 1692826) -TestStarport:testExoticDebtWithNoCaveatsNotAsBorrower() (gas: 376831) +TestStarport:testExoticDebtWithCustomPricingAndSettlement() (gas: 1695822) +TestStarport:testExoticDebtWithNoCaveatsNotAsBorrower() (gas: 376639) TestStarport:testIncrementCaveatNonce() (gas: 35117) TestStarport:testInitializedFlagSetProperly() (gas: 67372) TestStarport:testInvalidAdditionalTransfersOriginate() (gas: 230426) -TestStarport:testInvalidAdditionalTransfersRefinance() (gas: 170766) +TestStarport:testInvalidAdditionalTransfersRefinance() (gas: 170667) TestStarport:testInvalidAmountCollateral() (gas: 165968) TestStarport:testInvalidAmountCollateral721() (gas: 165968) TestStarport:testInvalidItemType() (gas: 151916) @@ -133,23 +133,22 @@ TestStarport:testNonDefaultCustodianCustodyCallSuccess() (gas: 290392) TestStarport:testNonPayableFunctions() (gas: 114479) TestStarport:testOverrideFeeRake() (gas: 379873) TestStarport:testPause() (gas: 18127) -TestStarport:testRefinancePostRepaymentFails() (gas: 127864) +TestStarport:testRefinancePostRepaymentFails() (gas: 127765) TestStarport:testStargateGetOwner() (gas: 8851) TestStarport:testTokenNoCodeCollateral() (gas: 150707) TestStarport:testTokenNoCodeDebt() (gas: 180980) TestStarport:testUnpause() (gas: 17187) -TestStrategistOriginator:testEncodeWithAccountCounter() (gas: 12330) -TestStrategistOriginator:testGetStrategistData() (gas: 1790990) -TestStrategistOriginator:testIncrementCounterAsStrategist() (gas: 38488) -TestStrategistOriginator:testIncrementCounterNotAuthorized() (gas: 13423) -TestStrategistOriginator:testInvalidCollateral() (gas: 210380) -TestStrategistOriginator:testInvalidDeadline() (gas: 216201) -TestStrategistOriginator:testInvalidDebt() (gas: 212088) -TestStrategistOriginator:testInvalidDebtAmountAskingMoreThanOffered() (gas: 212462) -TestStrategistOriginator:testInvalidDebtAmountOfferingZero() (gas: 212792) -TestStrategistOriginator:testInvalidDebtAmountRequestingZero() (gas: 212727) -TestStrategistOriginator:testInvalidDebtLength() (gas: 211382) -TestStrategistOriginator:testInvalidOffer() (gas: 427161) -TestStrategistOriginator:testInvalidSigner() (gas: 214520) -TestStrategistOriginator:testSetStrategist() (gas: 17884) -TestStrategistOriginator:testWithdraw() (gas: 167966) \ No newline at end of file +TestStrategistOriginator:testEncodeWithAccountCounter() (gas: 12429) +TestStrategistOriginator:testIncrementCounterAsStrategist() (gas: 38457) +TestStrategistOriginator:testIncrementCounterNotAuthorized() (gas: 13468) +TestStrategistOriginator:testInvalidCollateral() (gas: 210516) +TestStrategistOriginator:testInvalidDeadline() (gas: 216337) +TestStrategistOriginator:testInvalidDebt() (gas: 212224) +TestStrategistOriginator:testInvalidDebtAmountAskingMoreThanOffered() (gas: 212708) +TestStrategistOriginator:testInvalidDebtAmountOfferingZero() (gas: 212928) +TestStrategistOriginator:testInvalidDebtAmountRequestingZero() (gas: 212863) +TestStrategistOriginator:testInvalidDebtLength() (gas: 211518) +TestStrategistOriginator:testInvalidOffer() (gas: 427273) +TestStrategistOriginator:testInvalidSigner() (gas: 214678) +TestStrategistOriginator:testSetStrategist() (gas: 17852) +TestStrategistOriginator:testWithdraw() (gas: 167733) \ No newline at end of file diff --git a/src/BNPLHelper.sol b/src/BNPLHelper.sol index 21e63c42..8667642f 100644 --- a/src/BNPLHelper.sol +++ b/src/BNPLHelper.sol @@ -77,17 +77,11 @@ contract BNPLHelper is IFlashLoanRecipient, Ownable { error InvalidUserDataProvided(); error SenderNotVault(); - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS AND IMMUTABLES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - address private VAULT; - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - bytes32 private activeUserDataHash; + address private vault; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STRUCTS */ @@ -105,13 +99,13 @@ contract BNPLHelper is IFlashLoanRecipient, Ownable { Fulfillment[] fulfillments; } - constructor(address vault, address owner) { - VAULT = vault; + constructor(address _vault, address owner) { + vault = _vault; _initializeOwner(owner); } function makeFlashLoan(address[] calldata tokens, uint256[] calldata amounts, bytes calldata userData) external { - IVault(VAULT).flashLoan(this, tokens, amounts, userData); + IVault(vault).flashLoan(this, tokens, amounts, userData); } function receiveFlashLoan( @@ -140,7 +134,7 @@ contract BNPLHelper is IFlashLoanRecipient, Ownable { identifier: 0, token: tokens[i], from: execution.borrower, - to: VAULT, + to: vault, amount: amounts[i] + feeAmounts[i] }); unchecked { @@ -152,7 +146,7 @@ contract BNPLHelper is IFlashLoanRecipient, Ownable { ); } - function setFlashVault(address vault) external onlyOwner { - VAULT = vault; + function setFlashVault(address _vault) external onlyOwner { + vault = _vault; } } diff --git a/src/Custodian.sol b/src/Custodian.sol index 9da68f90..ee6c5062 100644 --- a/src/Custodian.sol +++ b/src/Custodian.sol @@ -44,6 +44,7 @@ import {LibString} from "solady/src/utils/LibString.sol"; contract Custodian is ERC721, ContractOffererInterface { using {StarportLib.getId} for Starport.Loan; + using {LibString.concat} for string; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ @@ -124,7 +125,7 @@ contract Custodian is ERC721, ContractOffererInterface { if (!_exists(loanId)) { revert InvalidLoan(); } - return string(abi.encodePacked("https://astaria.xyz/loans/", LibString.toString(loanId))); + return string("https://astaria.xyz/metadata/loan/").concat(LibString.toString(loanId)); } /** @@ -210,7 +211,6 @@ contract Custodian is ERC721, ContractOffererInterface { /** * @dev Generates the order for this contract offerer * @param fulfiller The address of the contract fulfiller - * @param maximumSpent The maximum amount of items to be spent by the order * @param context The context of the order * @return offer The items spent by the order * @return consideration The items received by the order @@ -218,7 +218,7 @@ contract Custodian is ERC721, ContractOffererInterface { function generateOrder( address fulfiller, SpentItem[] calldata, - SpentItem[] calldata maximumSpent, + SpentItem[] calldata, bytes calldata context // encoded based on the schemaID ) external onlySeaport returns (SpentItem[] memory offer, ReceivedItem[] memory consideration) { (Command memory close) = abi.decode(context, (Command)); @@ -226,7 +226,8 @@ contract Custodian is ERC721, ContractOffererInterface { if (loan.start == block.timestamp) { revert InvalidLoan(); } - if (close.action == Actions.Repayment && Status(loan.terms.status).isActive(loan, close.extraData)) { + bool loanActive = Status(loan.terms.status).isActive(loan, close.extraData); + if (close.action == Actions.Repayment && loanActive) { if (fulfiller != getBorrower(loan) && fulfiller != _getApproved(loan.getId())) { revert InvalidRepayer(); } @@ -240,7 +241,7 @@ contract Custodian is ERC721, ContractOffererInterface { _settleLoan(loan); _postRepaymentExecute(loan, fulfiller); - } else if (close.action == Actions.Settlement && !Status(loan.terms.status).isActive(loan, close.extraData)) { + } else if (close.action == Actions.Settlement && !loanActive) { address authorized; _beforeGetSettlementConsideration(loan); (consideration, authorized) = Settlement(loan.terms.settlement).getSettlementConsideration(loan); diff --git a/src/lib/StarportLib.sol b/src/lib/StarportLib.sol index 70cc284a..5c74e8c1 100644 --- a/src/lib/StarportLib.sol +++ b/src/lib/StarportLib.sol @@ -250,7 +250,7 @@ library StarportLib { // erc1155 transfer if (transfer.amount > 0) { ERC1155(transfer.token).safeTransferFrom( - transfer.from, transfer.to, transfer.identifier, transfer.amount, new bytes(0) + transfer.from, transfer.to, transfer.identifier, transfer.amount, "" ); } } else { @@ -281,7 +281,7 @@ library StarportLib { // erc1155 transfer if (transfer.amount > 0) { ERC1155(transfer.token).safeTransferFrom( - transfer.from, transfer.to, transfer.identifier, transfer.amount, new bytes(0) + transfer.from, transfer.to, transfer.identifier, transfer.amount, "" ); } } else { @@ -308,12 +308,14 @@ library StarportLib { } } - function transferSpentItemsSelf(SpentItem[] memory transfers, address from, address to) internal { + function transferSpentItemsSelf(SpentItem[] memory transfers, address to) internal { if (transfers.length > 0) { uint256 i = 0; for (; i < transfers.length;) { SpentItem memory transfer = transfers[i]; - _transferItem(transfer.itemType, transfer.token, transfer.identifier, transfer.amount, from, to); + _transferItem( + transfer.itemType, transfer.token, transfer.identifier, transfer.amount, address(this), to + ); unchecked { ++i; } @@ -358,7 +360,7 @@ library StarportLib { revert InvalidItemAmount(); } // erc1155 transfer - ERC1155(token).safeTransferFrom(from, to, identifier, amount, new bytes(0)); + ERC1155(token).safeTransferFrom(from, to, identifier, amount, ""); } else { revert InvalidItemType(); } @@ -382,7 +384,7 @@ library StarportLib { ERC721(token).transferFrom(from, to, identifier); } else if (itemType == ItemType.ERC1155) { // erc1155 transfer - ERC1155(token).safeTransferFrom(from, to, identifier, amount, new bytes(0)); + ERC1155(token).safeTransferFrom(from, to, identifier, amount, ""); } else { revert InvalidItemType(); } diff --git a/src/originators/StrategistOriginator.sol b/src/originators/StrategistOriginator.sol index ea388978..01cedbb4 100644 --- a/src/originators/StrategistOriginator.sol +++ b/src/originators/StrategistOriginator.sol @@ -84,9 +84,8 @@ contract StrategistOriginator is Ownable, Originator, TokenReceiverInterface { mapping(bytes32 => bool) public usedHashes; - // Strategist address and fee + // Strategist address address public strategist; - uint256 public strategistFee; uint256 private _counter; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ @@ -111,11 +110,10 @@ contract StrategistOriginator is Ownable, Originator, TokenReceiverInterface { /* CONSTRUCTOR */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - constructor(Starport SP_, address strategist_, uint256 fee_, address owner) { + constructor(Starport SP_, address strategist_, address owner) { _initializeOwner(owner); strategist = strategist_; emit StrategistTransferred(strategist_); - strategistFee = fee_; SP = SP_; _DOMAIN_SEPARATOR = keccak256( abi.encode( @@ -147,10 +145,11 @@ contract StrategistOriginator is Ownable, Originator, TokenReceiverInterface { if (msg.sender != strategist && msg.sender != owner()) { revert NotAuthorized(); } + uint256 counter; unchecked { - _counter += 1 + uint256(blockhash(block.number - 1) >> 0x80); + counter = _counter += 1 + uint256(blockhash(block.number - 1) >> 0x80); } - emit CounterUpdated(_counter); + emit CounterUpdated(counter); } /** @@ -163,8 +162,8 @@ contract StrategistOriginator is Ownable, Originator, TokenReceiverInterface { _validateOffer(params, details); Starport.Loan memory loan = Starport.Loan({ - start: uint256(0), // Set in the loan manager - originator: address(0), // Set in the loan manager + start: uint256(0), // Set in Starport + originator: address(0), // Set in Starport custodian: details.custodian, issuer: details.issuer, borrower: params.borrower, @@ -174,7 +173,8 @@ contract StrategistOriginator is Ownable, Originator, TokenReceiverInterface { }); CaveatEnforcer.SignedCaveats memory le; - SP.originate(new AdditionalTransfer[](0), params.borrowerCaveat, le, loan); + AdditionalTransfer[] memory at; + SP.originate(at, params.borrowerCaveat, le, loan); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ @@ -190,14 +190,6 @@ contract StrategistOriginator is Ownable, Originator, TokenReceiverInterface { return abi.encodePacked(bytes1(0x19), bytes1(0x01), _DOMAIN_SEPARATOR, hash); } - /** - * @dev Returns the strategist and fee - * @return strategist address and fee - */ - - function getStrategistData() public view virtual returns (address, uint256) { - return (strategist, strategistFee); - } /** * @dev Returns the nonce of the contract @@ -274,7 +266,7 @@ contract StrategistOriginator is Ownable, Originator, TokenReceiverInterface { } function withdraw(SpentItem[] memory transfers, address recipient) external onlyOwner { - StarportLib.transferSpentItemsSelf(transfers, address(this), recipient); + StarportLib.transferSpentItemsSelf(transfers, recipient); } // PUBLIC FUNCTIONS diff --git a/src/pricing/BasePricing.sol b/src/pricing/BasePricing.sol index 7a1590d6..189445dd 100644 --- a/src/pricing/BasePricing.sol +++ b/src/pricing/BasePricing.sol @@ -76,9 +76,8 @@ abstract contract BasePricing is Pricing { Details memory details = abi.decode(loan.terms.pricingData, (Details)); if (details.carryRate > 0 && loan.issuer != loan.originator) { carryConsideration = new SpentItem[](loan.debt.length); - } else { - carryConsideration = new SpentItem[](0); } + repayConsideration = new SpentItem[](loan.debt.length); uint256 i = 0; diff --git a/src/settlement/DutchAuctionSettlement.sol b/src/settlement/DutchAuctionSettlement.sol index 2835f614..ead92d13 100644 --- a/src/settlement/DutchAuctionSettlement.sol +++ b/src/settlement/DutchAuctionSettlement.sol @@ -92,7 +92,9 @@ abstract contract DutchAuctionSettlement is Settlement, AmountDeriver { // @inheritdoc Validation function validate(Starport.Loan calldata loan) external view virtual override returns (bytes4) { Details memory details = abi.decode(loan.terms.settlementData, (Details)); - return (details.startingPrice > details.endingPrice) ? Validation.validate.selector : bytes4(0xFFFFFFFF); + return (details.startingPrice > details.endingPrice && details.window != 0) + ? Validation.validate.selector + : bytes4(0xFFFFFFFF); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ @@ -123,7 +125,7 @@ abstract contract DutchAuctionSettlement is Settlement, AmountDeriver { } // DutchAuction has failed, allow lender to redeem if (start + details.window < block.timestamp) { - return (new ReceivedItem[](0), loan.issuer); + return (consideration, loan.issuer); } uint256 settlementPrice = _locateCurrentAmount({ diff --git a/test/StarportTest.sol b/test/StarportTest.sol index 6c9e7561..5598fa11 100644 --- a/test/StarportTest.sol +++ b/test/StarportTest.sol @@ -186,7 +186,7 @@ contract StarportTest is BaseOrderTest, Stargate { SP = new Starport(address(consideration), Stargate(address(this))); custodian = new Custodian(SP, address(consideration)); - SO = new StrategistOriginator(SP, strategist.addr, 1e16, address(this)); + SO = new StrategistOriginator(SP, strategist.addr, address(this)); pricing = new SimpleInterestPricing(SP); settlement = new FixedTermDutchAuctionSettlement(SP); status = new FixedTermStatus(); diff --git a/test/unit-testing/TestCustodian.sol b/test/unit-testing/TestCustodian.sol index 7c9ffaf7..7643d7bb 100644 --- a/test/unit-testing/TestCustodian.sol +++ b/test/unit-testing/TestCustodian.sol @@ -106,7 +106,7 @@ contract TestCustodian is StarportTest, DeepEq, MockCall { function testTokenURI() public { string memory expected = string( abi.encodePacked( - "https://astaria.xyz/loans/", LibString.toString(uint256(keccak256(abi.encode(activeLoan)))) + "https://astaria.xyz/metadata/loan/", LibString.toString(uint256(keccak256(abi.encode(activeLoan)))) ) ); assertEq(custodian.tokenURI(uint256(keccak256(abi.encode(activeLoan)))), expected); diff --git a/test/unit-testing/TestStarport.sol b/test/unit-testing/TestStarport.sol index 5edc16db..0f4ca3c0 100644 --- a/test/unit-testing/TestStarport.sol +++ b/test/unit-testing/TestStarport.sol @@ -176,9 +176,7 @@ contract MockExoticPricing is Pricing { } contract MockOriginator is StrategistOriginator { - constructor(Starport SP_, address strategist_, uint256 fee_) - StrategistOriginator(SP_, strategist_, fee_, msg.sender) - {} + constructor(Starport SP_, address strategist_) StrategistOriginator(SP_, strategist_, msg.sender) {} function terms(bytes calldata) public view returns (Starport.Terms memory) { return Starport.Terms({ @@ -196,8 +194,8 @@ contract MockOriginator is StrategistOriginator { _validateOffer(params, details); Starport.Loan memory loan = Starport.Loan({ - start: uint256(0), // are set in the loan manager - originator: address(0), // are set in the loan manager + start: uint256(0), // are set in Starport + originator: address(0), // are set in Starport custodian: details.custodian, issuer: details.issuer, borrower: params.borrower, diff --git a/test/unit-testing/TestStrategistOriginator.sol b/test/unit-testing/TestStrategistOriginator.sol index 0ba9bc33..f980d40d 100644 --- a/test/unit-testing/TestStrategistOriginator.sol +++ b/test/unit-testing/TestStrategistOriginator.sol @@ -41,13 +41,6 @@ contract TestStrategistOriginator is StarportTest, DeepEq { ); } - function testGetStrategistData() public { - StrategistOriginator SOO = new StrategistOriginator(SP, strategist.addr, 1e17, address(this)); - (address activeStrategist, uint256 strategistFee) = SOO.getStrategistData(); - assert(activeStrategist == strategist.addr); - assert(strategistFee == 1e17); - } - function testIncrementCounterAsStrategist() public { uint256 newCounter = SO.getCounter() + 1 + uint256(blockhash(block.timestamp - 1) >> 0x80); vm.expectEmit();