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

Feat/caveat test rebase #46

Merged
merged 7 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
224 changes: 121 additions & 103 deletions .gas-snapshot

Large diffs are not rendered by default.

46 changes: 19 additions & 27 deletions src/LoanManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ import {SignatureCheckerLib} from "solady/src/utils/SignatureCheckerLib.sol";
import {CaveatEnforcer} from "starport-core/enforcers/CaveatEnforcer.sol";
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(LoanManager.Loan calldata loan) external;
}

contract LoanManager is Ownable, ERC721 {
contract LoanManager is Ownable, ERC721, PausableNonReentrant {
androolloyd marked this conversation as resolved.
Show resolved Hide resolved
using FixedPointMathLib for uint256;

using {StarPortLib.toReceivedItems} for SpentItem[];
Expand All @@ -69,7 +70,6 @@ contract LoanManager is Ownable, ERC721 {
bytes32 public constant INTENT_ORIGINATION_TYPEHASH =
keccak256("Origination(bytes32 hash,bytes32 salt,bytes32 caveatHash");
bytes32 public constant VERSION = keccak256("0");
bool public paused;
address public feeTo;
uint88 public defaultFeeRake;
mapping(address => mapping(bytes32 => bool)) public invalidHashes;
Expand Down Expand Up @@ -118,8 +118,6 @@ contract LoanManager is Ownable, ERC721 {

event Close(uint256 loanId);
event Open(uint256 loanId, LoanManager.Loan loan);
event Paused();
event UnPaused();

error InvalidRefinance();
error InvalidCustodian();
Expand All @@ -138,7 +136,6 @@ contract LoanManager is Ownable, ERC721 {
error UnauthorizedAdditionalTransferIncluded();
error InvalidCaveatSigner();
error MalformedRefinance();
error IsPaused();

constructor(ConsiderationInterface seaport_) {
address custodian = address(new Custodian(this, seaport_));
Expand Down Expand Up @@ -188,34 +185,21 @@ contract LoanManager is Ownable, ERC721 {
revert CannotTransferLoans();
}

function pause() external onlyOwner {
paused = true;
emit Paused();
}

function unPause() external onlyOwner {
paused = false;
emit UnPaused();
}

function originate(
AdditionalTransfer[] calldata additionalTransfers,
CaveatEnforcer.CaveatWithApproval calldata borrowerCaveat,
CaveatEnforcer.CaveatWithApproval calldata lenderCaveat,
LoanManager.Loan memory loan
) external payable {
if (paused) {
revert IsPaused();
}
) external payable pausableNonReentrant {
//cache the addresses
address borrower = loan.borrower;
address issuer = loan.issuer;
address feeRecipient = feeTo;
if (msg.sender != loan.borrower && !(approvals[borrower][msg.sender] == ApprovalType.BORROWER)) {
if (msg.sender != borrower && approvals[borrower][msg.sender] != ApprovalType.BORROWER) {
_validateAndEnforceCaveats(borrowerCaveat, borrower, additionalTransfers, loan);
}

if (msg.sender != issuer && !(approvals[issuer][msg.sender] == ApprovalType.LENDER)) {
if (msg.sender != issuer && approvals[issuer][msg.sender] != ApprovalType.LENDER) {
_validateAndEnforceCaveats(lenderCaveat, issuer, additionalTransfers, loan);
}

Expand Down Expand Up @@ -246,10 +230,7 @@ contract LoanManager is Ownable, ERC721 {
CaveatEnforcer.CaveatWithApproval calldata lenderCaveat,
LoanManager.Loan memory loan,
bytes calldata pricingData
) external {
if (paused) {
revert IsPaused();
}
) external pausableNonReentrant {
(
SpentItem[] memory considerationPayment,
SpentItem[] memory carryPayment,
Expand All @@ -260,13 +241,16 @@ contract LoanManager is Ownable, ERC721 {
loan = applyRefinanceConsiderationToLoan(loan, considerationPayment, carryPayment, pricingData);

_transferSpentItems(considerationPayment, lender, loan.issuer);
_transferSpentItems(carryPayment, lender, loan.originator);

if (carryPayment.length > 0) {
_transferSpentItems(carryPayment, lender, loan.originator);
}

loan.issuer = lender;
loan.originator = address(0);
loan.start = 0;

if (msg.sender != loan.issuer && !(approvals[loan.issuer][msg.sender] == ApprovalType.LENDER)) {
if (msg.sender != loan.issuer && approvals[loan.issuer][msg.sender] != ApprovalType.LENDER) {
androolloyd marked this conversation as resolved.
Show resolved Hide resolved
_validateAndEnforceCaveats(lenderCaveat, loan.issuer, additionalTransfers, loan);
}

Expand Down Expand Up @@ -469,6 +453,14 @@ contract LoanManager is Ownable, ERC721 {
);
}

function incrementCaveatNonce() external {
++caveatNonces[msg.sender];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in my change i did the seaport style nonce increment, but unsure if we care, also we need an event to both so that we can index them/invalidte things

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seaport style sounds good to me. Yeah probably should add the salt event to validateSalt as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok can just adopt my methods then they have events and the seaport style nonce update, will add events to the invalidate caveat salt

}

function invalidateCaveatSalt(bytes32 salt) external {
invalidHashes[msg.sender][salt] = true;
}

/**
* @dev the erc721 name of the contract
* @return The name of the contract as a string
Expand Down
67 changes: 67 additions & 0 deletions src/lib/PausableNonReentrant.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {Ownable} from "solady/src/auth/Ownable.sol";

abstract contract PausableNonReentrant is Ownable {
uint256 private constant _UNLOCKED = 0x1;
uint256 private constant _LOCKED = 0x2;
uint256 private constant _PAUSED = 0x3;

uint256 private _state = _UNLOCKED;

event Paused();
event Unpaused();

error IsPaused();
error IsLocked();
error NotPaused();

modifier pausableNonReentrant() {
assembly {
//If locked or paused, handle revert cases
if gt(sload(_state.slot), _UNLOCKED) {
if gt(sload(_state.slot), _LOCKED) {
//Revert IsPaused
mstore(0, 0x1309a563)
revert(0x1c, 0x04)
}
//Revert IsLocked
mstore(0, 0xcaa30f55)
revert(0x1c, 0x04)
}
sstore(_state.slot, _LOCKED)
}
_;
assembly {
sstore(_state.slot, _UNLOCKED)
}
}

function pause() external onlyOwner {
assembly {
//If locked, prevent owner from overriding state
if eq(sload(_state.slot), _LOCKED) {
//Revert IsLocked
mstore(0, 0xcaa30f55)
revert(0x1c, 0x04)
}
sstore(_state.slot, _PAUSED)
}
emit Paused();
}

function unpause() external onlyOwner {
assembly {
//If not paused, prevent owner from overriding state
if lt(sload(_state.slot), _PAUSED) {
//Revert NotPaused
mstore(0, 0x6cd60201)
revert(0x1c, 0x04)
}
sstore(_state.slot, _UNLOCKED)
}
emit Unpaused();
}

function paused() external view returns (bool) {
return _state == _PAUSED;
}
}
17 changes: 16 additions & 1 deletion test/StarPortTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,21 @@ contract StarPortTest is BaseOrderTest {
}
}

function getBorrowerSignedCaveat(
BorrowerEnforcer.Details memory details,
Account memory signer,
bytes32 salt,
address enforcer
) public view returns (CaveatEnforcer.CaveatWithApproval memory caveatApproval) {
caveatApproval.caveat = new CaveatEnforcer.Caveat[](1);
caveatApproval.salt = salt;
caveatApproval.caveat[0] =
CaveatEnforcer.Caveat({enforcer: enforcer, deadline: block.timestamp + 1 days, data: abi.encode(details)});
bytes32 hash = LM.hashCaveatWithSaltAndNonce(signer.addr, salt, caveatApproval.caveat);

(caveatApproval.v, caveatApproval.r, caveatApproval.s) = vm.sign(signer.key, hash);
}

function getLenderSignedCaveat(
LenderEnforcer.Details memory details,
Account memory signer,
Expand Down Expand Up @@ -498,7 +513,7 @@ contract StarPortTest is BaseOrderTest {
}

function getRefinanceCaveat(LoanManager.Loan memory loan, bytes memory pricingData, address fulfiller)
external
public
returns (LoanManager.Loan memory)
{
(SpentItem[] memory considerationPayment, SpentItem[] memory carryPayment,) =
Expand Down
Loading