Skip to content

Commit

Permalink
Feat/caveat test rebase (#46)
Browse files Browse the repository at this point in the history
* WIP

* Feat/ast 1952 v1 handler testing (#41)

* update getAuctionStart to be a public helper, make an internal version that is more optimized(less calls/decoding), add tests

* coverage testing for AstariaV1Settlement handler complete

* coverage testing for AstariaV1Settlement handler complete

* fix test name

* feat/AST 1952 v1 handler testing (#43)

* update getAuctionStart to be a public helper, make an internal version that is more optimized(less calls/decoding), add tests

* coverage testing for AstariaV1Settlement handler complete

* coverage testing for AstariaV1Settlement handler complete

* fix test name

* Astaria V1 Hook testing complete(-withdraw), Conduit Helper Removed, ConduitTransfer => AdditionalTransfer

* remove commented code

* final comment removal

* feat/V1 hook updates (#44)

* update getAuctionStart to be a public helper, make an internal version that is more optimized(less calls/decoding), add tests

* coverage testing for AstariaV1Settlement handler complete

* coverage testing for AstariaV1Settlement handler complete

* fix test name

* Astaria V1 Hook testing complete(-withdraw), Conduit Helper Removed, ConduitTransfer => AdditionalTransfer

* remove commented code

* final comment removal

* additional tests for v1 hook as well as some cleanup/fixes

* update snaphot

* working caveat testing and reentrancy guard

* remove ownable and change loan.issuer to lender

---------

Co-authored-by: androolloyd <[email protected]>
  • Loading branch information
0xgregthedev and androolloyd authored Nov 3, 2023
1 parent 90411a2 commit 675328b
Show file tree
Hide file tree
Showing 8 changed files with 590 additions and 140 deletions.
224 changes: 121 additions & 103 deletions .gas-snapshot

Large diffs are not rendered by default.

50 changes: 21 additions & 29 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 ERC721, PausableNonReentrant {
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,18 +241,21 @@ 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)) {
_validateAndEnforceCaveats(lenderCaveat, loan.issuer, additionalTransfers, loan);
if (msg.sender != lender && approvals[lender][msg.sender] != ApprovalType.LENDER) {
_validateAndEnforceCaveats(lenderCaveat, lender, additionalTransfers, loan);
}

if (additionalTransfers.length > 0) {
_validateAdditionalTransfers(loan.borrower, loan.issuer, msg.sender, additionalTransfers);
_validateAdditionalTransfers(loan.borrower, lender, msg.sender, additionalTransfers);
StarPortLib.transferAdditionalTransfers(additionalTransfers);
}

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

function incrementCaveatNonce() external {
++caveatNonces[msg.sender];
}

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

0 comments on commit 675328b

Please sign in to comment.