Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test custodian #23

Merged
merged 2 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 37 additions & 33 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
EnforcerTest:testCollateralEnforcer() (gas: 959475)
EnforcerTest:testFailCollateralEnforcerDifferentCollateral() (gas: 842116)
EnforcerTest:testFailRateEnforcerMaxCarryRate() (gas: 797272)
EnforcerTest:testFailRateEnforcerMaxRate() (gas: 797222)
EnforcerTest:testFailRateEnforcerMaxRateAndMaxCarryRate() (gas: 797087)
EnforcerTest:testRateEnforcerBasic() (gas: 916734)
EnforcerTest:testTermEnforcerBasic() (gas: 988996)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecall() (gas: 978416)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 889991)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 923967)
TestCustodian:testCustodySelector() (gas: 7084)
TestCustodian:testGenerateOrder() (gas: 165936)
TestCustodian:testGetBorrower() (gas: 70626)
TestCustodian:testOnlySeaport() (gas: 17842)
TestCustodian:testPreviewOrder() (gas: 207)
TestCustodian:testRatifyOrder() (gas: 164)
TestCustodian:testSafeTransferReceive() (gas: 158751)
TestCustodian:testSeaportMetadata() (gas: 8518)
TestCustodian:testSupportsInterface() (gas: 5664)
TestExoticLoans:testSwap() (gas: 1356417)
EnforcerTest:testCollateralEnforcer() (gas: 973177)
EnforcerTest:testFailCollateralEnforcerDifferentCollateral() (gas: 855101)
EnforcerTest:testFailRateEnforcerMaxCarryRate() (gas: 810244)
EnforcerTest:testFailRateEnforcerMaxRate() (gas: 810194)
EnforcerTest:testFailRateEnforcerMaxRateAndMaxCarryRate() (gas: 810059)
EnforcerTest:testRateEnforcerBasic() (gas: 930425)
EnforcerTest:testTermEnforcerBasic() (gas: 1002689)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecall() (gas: 988282)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLender() (gas: 906210)
TestAstariaV1Loan:testNewLoanERC721CollateralDefaultTermsRecallLiquidation() (gas: 952988)
TestCustodian:testCustodySelector() (gas: 7152)
TestCustodian:testGenerateOrderRepay() (gas: 174157)
TestCustodian:testGenerateOrderRepayNotBorrower() (gas: 102146)
TestCustodian:testGenerateOrderSettlement() (gas: 125008)
TestCustodian:testGenerateOrderSettlementUnauthorized() (gas: 100145)
TestCustodian:testGetBorrower() (gas: 75840)
TestCustodian:testOnlySeaport() (gas: 17931)
TestCustodian:testPreviewOrderNoActiveLoan() (gas: 229)
TestCustodian:testPreviewOrderRepay() (gas: 224706)
TestCustodian:testPreviewOrderSettlement() (gas: 152470)
TestCustodian:testRatifyOrder() (gas: 188716)
TestCustodian:testSafeTransferReceive() (gas: 159061)
TestCustodian:testSeaportMetadata() (gas: 8519)
TestCustodian:testSupportsInterface() (gas: 5791)
TestExoticLoans:testSwap() (gas: 1167541)
TestLoanCombinations:testLoan20For721SimpleInterestDutchFixedRepay() (gas: 252)
TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 512554)
TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 736003)
TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 510525)
TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 721961)
TestLoanManager:testGenerateOrder() (gas: 773998)
TestLoanManager:testGenerateOrderInvalidSender() (gas: 13012)
TestLoanManager:testSupportsInterface() (gas: 6959)
TestNewLoan:testBuyNowPayLater() (gas: 1142014)
TestNewLoan:testNewLoanERC721CollateralDefaultTerms2():((uint256,address,address,address,address,(uint8,address,uint256,uint256)[],(uint8,address,uint256,uint256)[],(address,bytes,address,bytes,address,bytes))) (gas: 987827)
TestNewLoan:testNewLoanERC721CollateralDefaultTermsRefinance() (gas: 648642)
TestNewLoan:testNewLoanERC721CollateralDefaultTermsWithMerkleProof():((uint256,address,address,address,address,(uint8,address,uint256,uint256)[],(uint8,address,uint256,uint256)[],(address,bytes,address,bytes,address,bytes))) (gas: 581561)
TestNewLoan:testSettleLoan() (gas: 1260082)
TestRepayLoan:testRepayLoan() (gas: 719171)
TestLoanCombinations:testLoan20for20SimpleInterestDutchFixedRepay() (gas: 521951)
TestLoanCombinations:testLoan721for20SimpleInterestDutchFixedRepay() (gas: 753642)
TestLoanCombinations:testLoanAstariaSettlementRepay() (gas: 519386)
TestLoanCombinations:testLoanSimpleInterestEnglishFixed() (gas: 740159)
TestLoanManager:testGenerateOrder() (gas: 1009691)
TestLoanManager:testGenerateOrderInvalidSender() (gas: 13075)
TestLoanManager:testSupportsInterface() (gas: 7003)
TestNewLoan:testBuyNowPayLater() (gas: 1154993)
TestNewLoan:testNewLoanERC721CollateralDefaultTerms2():((uint256,address,address,address,address,(uint8,address,uint256,uint256)[],(uint8,address,uint256,uint256)[],(address,bytes,address,bytes,address,bytes))) (gas: 1001549)
TestNewLoan:testNewLoanERC721CollateralDefaultTermsRefinance() (gas: 658024)
TestNewLoan:testSettleLoan() (gas: 1282926)
TestRepayLoan:testRepayLoan() (gas: 736801)
TestStarLiteUtils:testEncodeReceivedWithRecipient() (gas: 17955)
TestStarLiteUtils:testSpentToReceived() (gas: 17796)
1 change: 0 additions & 1 deletion src/ConduitHelper.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pragma solidity =0.8.17;


import {ItemType, OfferItem, Schema, SpentItem, ReceivedItem} from "seaport-types/src/lib/ConsiderationStructs.sol";

import {ConduitTransfer, ConduitItemType} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
Expand Down
18 changes: 10 additions & 8 deletions src/Custodian.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ contract Custodian is ContractOffererInterface, TokenReceiverInterface, ConduitH
event RepayApproval(address borrower, address repayer, bool approved);
event SeaportCompatibleContractDeployed();

error InvalidSender();
error NotSeaport();
error InvalidRepayer();
error InvalidFulfiller();
error InvalidHandler();

constructor(LoanManager LM_, address seaport_) {
Expand Down Expand Up @@ -86,7 +88,7 @@ contract Custodian is ContractOffererInterface, TokenReceiverInterface, ConduitH

modifier onlySeaport() {
if (msg.sender != address(seaport)) {
revert InvalidSender();
revert NotSeaport();
}
_;
}
Expand Down Expand Up @@ -253,7 +255,7 @@ contract Custodian is ContractOffererInterface, TokenReceiverInterface, ConduitH
if (SettlementHook(loan.terms.hook).isActive(loan)) {
address borrower = getBorrower(loan);
if (fulfiller != borrower && !repayApproval[borrower][fulfiller]) {
revert InvalidSender();
revert InvalidRepayer();
}

(ReceivedItem[] memory paymentConsiderations, ReceivedItem[] memory carryFeeConsideration) =
Expand All @@ -267,19 +269,19 @@ contract Custodian is ContractOffererInterface, TokenReceiverInterface, ConduitH
_settleLoan(loan);
}
} else {
address restricted;
address authorized;
//add in originator fee
if (withEffects) {
_beforeSettlementHandlerHook(loan);
(consideration, restricted) = SettlementHandler(loan.terms.handler).getSettlement(loan);
(consideration, authorized) = SettlementHandler(loan.terms.handler).getSettlement(loan);
_afterSettlementHandlerHook(loan);
} else {
(consideration, restricted) = SettlementHandler(loan.terms.handler).getSettlement(loan);
(consideration, authorized) = SettlementHandler(loan.terms.handler).getSettlement(loan);
}

//TODO: remove and revert in get settlement if needed
if (restricted != address(0) && fulfiller != restricted) {
revert InvalidSender();
if (authorized != address(0) && fulfiller != authorized) {
revert InvalidFulfiller();
}
}

Expand Down
21 changes: 12 additions & 9 deletions src/originators/Originator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,17 @@ abstract contract Originator is Ownable {
INITIALIZED,
CLOSED
}

error InvalidDebt();
error InvalidOffer();

struct Response {
LoanManager.Terms terms;
address issuer;
}

event StrategistTransferred(address newStrategist);

mapping(bytes32 => bool) public usedHashes;

struct Request {
Expand All @@ -56,7 +60,7 @@ abstract contract Originator is Ownable {
}

struct Details {
// uint16 offerType;
// uint16 offerType;
address custodian;
address conduit;
address issuer;
Expand Down Expand Up @@ -170,19 +174,18 @@ abstract contract Originator is Ownable {
return abi.decode(details, (Details)).offer.terms;
}

function execute(Request calldata params)
external
virtual
onlyLoanManager
returns (Response memory response)
{
function execute(Request calldata params) external virtual onlyLoanManager returns (Response memory response) {
Details memory details = abi.decode(params.details, (Details));
_validateOffer(params, details);
_execute(params, details);
response = _buildResponse(params, details);
}

function _buildResponse(Request calldata params, Details memory details) internal virtual returns (Response memory response) {
function _buildResponse(Request calldata params, Details memory details)
internal
virtual
returns (Response memory response)
{
response = Response({terms: details.offer.terms, issuer: details.issuer});
}

Expand Down Expand Up @@ -242,7 +245,7 @@ abstract contract Originator is Ownable {

if (
ConduitInterface(details.conduit).execute(_packageTransfers(request.debt, request.receiver, details.issuer))
!= ConduitInterface.execute.selector
!= ConduitInterface.execute.selector
) {
revert ConduitTransferError();
}
Expand Down
100 changes: 92 additions & 8 deletions test/TestCustodian.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import "./StarPortTest.sol";
import {DeepEq} from "test/utils/DeepEq.sol";
import {MockCall} from "test/utils/MockCall.sol";
import "forge-std/Test.sol";

contract TestCustodian is StarPortTest {
contract TestCustodian is StarPortTest, DeepEq, MockCall {
using Cast for *;

LoanManager.Loan public activeLoan;
Expand Down Expand Up @@ -49,10 +52,10 @@ contract TestCustodian is StarPortTest {
}

function testOnlySeaport() public {
vm.expectRevert(abi.encodeWithSelector(Custodian.InvalidSender.selector));
vm.expectRevert(abi.encodeWithSelector(Custodian.NotSeaport.selector));
custodian.ratifyOrder(new SpentItem[](0), new ReceivedItem[](0), new bytes(0), new bytes32[](0), uint256(0));

vm.expectRevert(abi.encodeWithSelector(Custodian.InvalidSender.selector));
vm.expectRevert(abi.encodeWithSelector(Custodian.NotSeaport.selector));
custodian.generateOrder(address(this), new SpentItem[](0), new SpentItem[](0), new bytes(0));
}

Expand Down Expand Up @@ -80,8 +83,8 @@ contract TestCustodian is StarPortTest {
custodian.getSeaportMetadata();
}

function testGetBorrower() public view {
custodian.getBorrower(activeLoan.toMemory());
function testGetBorrower() public {
assertEq(custodian.getBorrower(activeLoan.toMemory()), activeLoan.borrower);
}

function testCustodySelector() public {
Expand All @@ -91,12 +94,93 @@ contract TestCustodian is StarPortTest {
);
}

function testGenerateOrder() public {
//TODO: add assertions
function testGenerateOrderRepay() public {
vm.prank(seaportAddr);
custodian.generateOrder(activeLoan.borrower, new SpentItem[](0), debt, abi.encode(activeLoan));
}

function testRatifyOrder() public {}
function testGenerateOrderRepayNotBorrower() public {
vm.prank(seaportAddr);
vm.expectRevert(abi.encodeWithSelector(Custodian.InvalidRepayer.selector));
custodian.generateOrder(alice, new SpentItem[](0), debt, abi.encode(activeLoan));
}

function testGenerateOrderSettlement() public {
vm.startPrank(seaportAddr);
mockHookCall(activeLoan.terms.hook, false);

mockHandlerCall(activeLoan.terms.handler, new ReceivedItem[](0), address(0));

(SpentItem[] memory offer, ReceivedItem[] memory consideration) =
custodian.generateOrder(alice, new SpentItem[](0), debt, abi.encode(activeLoan));

vm.stopPrank();

assertEq(consideration.length, 0);
}

function testGenerateOrderSettlementUnauthorized() public {
vm.prank(seaportAddr);
mockHookCall(activeLoan.terms.hook, false);
mockHandlerCall(activeLoan.terms.handler, new ReceivedItem[](0), lender.addr);

vm.expectRevert(abi.encodeWithSelector(Custodian.InvalidFulfiller.selector));
custodian.generateOrder(borrower.addr, new SpentItem[](0), debt, abi.encode(activeLoan));
}

//TODO: add assertions
function testRatifyOrder() public {
vm.startPrank(seaportAddr);
bytes memory context = abi.encode(activeLoan);

(SpentItem[] memory offer, ReceivedItem[] memory consideration) =
custodian.generateOrder(activeLoan.borrower, new SpentItem[](0), debt, context);

custodian.ratifyOrder(offer, consideration, context, new bytes32[](0), 0);

vm.stopPrank();
}

function testPreviewOrderRepay() public {
vm.prank(seaportAddr);

mockHookCall(activeLoan.terms.hook, true);
mockHandlerCall(activeLoan.terms.handler, new ReceivedItem[](0), address(0));

(SpentItem[] memory expectedOffer, ReceivedItem[] memory expectedConsideration) =
custodian.generateOrder(activeLoan.borrower, new SpentItem[](0), debt, abi.encode(activeLoan));

mockHookCall(activeLoan.terms.hook, true);
mockHandlerCall(activeLoan.terms.handler, new ReceivedItem[](0), address(0));

(SpentItem[] memory receivedOffer, ReceivedItem[] memory receivedCosideration) = custodian.previewOrder(
activeLoan.borrower, activeLoan.borrower, new SpentItem[](0), debt, abi.encode(activeLoan)
);

_deepEq(receivedOffer, expectedOffer);
_deepEq(receivedCosideration, expectedConsideration);
}

function testPreviewOrderSettlement() public {
vm.prank(seaportAddr);

mockHookCall(activeLoan.terms.hook, false);
mockHandlerCall(activeLoan.terms.handler, new ReceivedItem[](0), address(0));

(SpentItem[] memory expectedOffer, ReceivedItem[] memory expectedConsideration) =
custodian.generateOrder(alice, new SpentItem[](0), debt, abi.encode(activeLoan));

mockHookCall(activeLoan.terms.hook, false);
mockHandlerCall(activeLoan.terms.handler, new ReceivedItem[](0), address(0));

(SpentItem[] memory receivedOffer, ReceivedItem[] memory receivedCosideration) =
custodian.previewOrder(alice, alice, new SpentItem[](0), debt, abi.encode(activeLoan));

_deepEq(receivedOffer, expectedOffer);
_deepEq(receivedCosideration, expectedConsideration);
}

function testPreviewOrder() public {}
//TODO: should revert
function testPreviewOrderNoActiveLoan() public {}
}
24 changes: 12 additions & 12 deletions test/TestExoticLoans.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ contract SwapHandler is SettlementHandler {
}

function getSettlement(LoanManager.Loan calldata loan)
public
view
override
returns (ReceivedItem[] memory consideration, address restricted)
public
view
override
returns (ReceivedItem[] memory consideration, address restricted)
{
return (new ReceivedItem[](0), address(0));
}
Expand All @@ -76,19 +76,19 @@ contract SwapPricing is Pricing {
constructor(LoanManager LM_) Pricing(LM_) {}

function getPaymentConsideration(LoanManager.Loan memory loan)
public
view
override
returns (ReceivedItem[] memory, ReceivedItem[] memory)
public
view
override
returns (ReceivedItem[] memory, ReceivedItem[] memory)
{
return (new ReceivedItem[](0), new ReceivedItem[](0));
}

function isValidRefinance(LoanManager.Loan memory loan, bytes memory newPricingData, address caller)
external
view
override
returns (ReceivedItem[] memory, ReceivedItem[] memory, ReceivedItem[] memory)
external
view
override
returns (ReceivedItem[] memory, ReceivedItem[] memory, ReceivedItem[] memory)
{
return (new ReceivedItem[](0), new ReceivedItem[](0), new ReceivedItem[](0));
}
Expand Down
Loading