Skip to content

Commit

Permalink
refactor interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
SevenSwen committed Feb 2, 2023
1 parent 7de37b3 commit c37e11b
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 105 deletions.
33 changes: 0 additions & 33 deletions contracts/OrderMixin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,6 @@ abstract contract OrderMixin is IOrderMixin, EIP712, PredicateHelper {
using CalldataLib for CalldataLib.Address;
using CalldataLib for bytes;

error UnknownOrder();
error AccessDenied();
error AlreadyFilled();
error PermitLengthTooLow();
error ZeroTargetIsForbidden();
error RemainingAmountIsZero();
error PrivateOrder();
error BadSignature();
error ReentrancyDetected();
error PredicateIsNotTrue();
error OnlyOneAmountShouldBeZero();
error TakingAmountTooHigh();
error MakingAmountTooLow();
error SwapWithZeroAmount();
error TransferFromMakerToTakerFailed();
error TransferFromTakerToMakerFailed();
error TakingAmountIncreased();
error SimulationResults(bool success, bytes res);

/// @notice Emitted every time order gets filled, including partial fills
event OrderFilled(
address indexed maker,
bytes32 orderHash,
uint256 remaining
);

/// @notice Emitted when order gets cancelled
event OrderCanceled(
address indexed maker,
bytes32 orderHash,
uint256 remainingRaw
);

uint256 private constant _RAW_CALL_GAS_LIMIT = 5000;
uint256 private constant _ORDER_DOES_NOT_EXIST = 0;
uint256 private constant _ORDER_FILLED = 1;
Expand Down
83 changes: 11 additions & 72 deletions contracts/OrderRFQMixin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,17 @@ import "@1inch/solidity-utils/contracts/OnlyWethReceiver.sol";

import "./helpers/AmountCalculator.sol";
import "./interfaces/IInteractionNotificationReceiver.sol";
import "./interfaces/IOrderRFQMixin.sol";
import "./libraries/Errors.sol";
import "./OrderRFQLib.sol";
import "hardhat/console.sol";

/// @title RFQ Limit Order mixin
abstract contract OrderRFQMixin is EIP712, OnlyWethReceiver {
abstract contract OrderRFQMixin is IOrderRFQMixin, EIP712, OnlyWethReceiver {
using SafeERC20 for IERC20;
using OrderRFQLib for OrderRFQLib.OrderRFQ;
using CalldataLib for CalldataLib.Address;
using CalldataLib for bytes;

error RFQZeroTargetIsForbidden();
error RFQPrivateOrder();
error RFQBadSignature();
error OrderExpired();
error MakingAmountExceeded();
error TakingAmountExceeded();
error RFQSwapWithZeroAmount();
error InvalidatedOrder();

/**
* @notice Emitted when RFQ gets filled
* @param orderHash Hash of the order
* @param makingAmount Amount of the maker asset that was transferred from maker to taker
*/
event OrderFilledRFQ(
bytes32 orderHash,
uint256 makingAmount
);

uint256 private constant _RAW_CALL_GAS_LIMIT = 5000;
uint256 private constant _MAKER_AMOUNT_FLAG = 1 << 255;
uint256 private constant _SIGNER_SMART_CONTRACT_HINT = 1 << 254;
Expand All @@ -60,37 +41,28 @@ abstract contract OrderRFQMixin is EIP712, OnlyWethReceiver {
}

/**
* @notice Returns bitmask for double-spend invalidators based on lowest byte of order.info and filled quotes
* @param maker Maker address
* @param slot Slot number to return bitmask for
* @return result Each bit represents whether corresponding was already invalidated
* @notice See {IOrderRFQMixin-invalidatorForOrderRFQ}.
*/
function invalidatorForOrderRFQ(address maker, uint256 slot) external view returns(uint256 /* result */) {
return _invalidator[maker][slot];
}

/**
* @notice Cancels order's quote
* @param orderInfo Order info (only order id in lowest 64 bits is used)
* @notice See {IOrderRFQMixin-cancelOrderRFQ}.
*/
function cancelOrderRFQ(uint256 orderInfo) external {
_invalidateOrder(msg.sender, orderInfo, 0);
}

/// @notice Cancels multiple order's quotes
/**
* @notice See {IOrderRFQMixin-cancelOrderRFQ}.
*/
function cancelOrderRFQ(uint256 orderInfo, uint256 additionalMask) external {
_invalidateOrder(msg.sender, orderInfo, additionalMask);
}

/**
* @notice Fills order's quote, fully or partially (whichever is possible)
* @param order Order quote to fill
* @param signature Signature to confirm quote ownership
* @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets.
* @param flagsAndAmount Fill configuration flags with amount packed in one slot
* @return filledMakingAmount Actual amount transferred from maker to taker
* @return filledTakingAmount Actual amount transferred from taker to maker
* @return orderHash Hash of the filled order
* @notice See {IOrderRFQMixin-fillOrderRFQ}.
*/
function fillOrderRFQ(
OrderRFQLib.OrderRFQ calldata order,
Expand All @@ -102,20 +74,7 @@ abstract contract OrderRFQMixin is EIP712, OnlyWethReceiver {
}

/**
* @notice Fills order's quote, fully or partially, with compact signature
* @param order Order quote to fill
* @param r R component of signature
* @param vs VS component of signature
* @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets.
* @param flagsAndAmount Fill configuration flags with amount packed in one slot
* - Bits 0-251 contain the amount to fill
* - Bit 252 is used to indicate whether weth should be unwrapped to eth
* - Bit 253 is used to indicate whether signature is 64-bit (0) or 65-bit (1)
* - Bit 254 is used to indicate whether smart contract (1) signed the order or not (0)
* - Bit 255 is used to indicate whether maker (1) or taker amount (0) is given in the amount parameter
* @return filledMakingAmount Actual amount transferred from maker to taker
* @return filledTakingAmount Actual amount transferred from taker to maker
* @return orderHash Hash of the filled order
* @notice See {IOrderRFQMixin-fillOrderRFQCompact}.
*/
function fillOrderRFQCompact(
OrderRFQLib.OrderRFQ calldata order,
Expand All @@ -140,19 +99,7 @@ abstract contract OrderRFQMixin is EIP712, OnlyWethReceiver {
}

/**
* @notice Same as `fillOrderRFQTo` but calls permit first.
* It allows to approve token spending and make a swap in one transaction.
* Also allows to specify funds destination instead of `msg.sender`
* @param order Order quote to fill
* @param signature Signature to confirm quote ownership
* @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets.
* @param flagsAndAmount Fill configuration flags with amount packed in one slot
* @param target Address that will receive swap funds
* @param permit Should contain abi-encoded calldata for `IERC20Permit.permit` call
* @return filledMakingAmount Actual amount transferred from maker to taker
* @return filledTakingAmount Actual amount transferred from taker to maker
* @return orderHash Hash of the filled order
* @dev See tests for examples
* @notice See {IOrderRFQMixin-fillOrderRFQToWithPermit}.
*/
function fillOrderRFQToWithPermit(
OrderRFQLib.OrderRFQ calldata order,
Expand All @@ -162,20 +109,12 @@ abstract contract OrderRFQMixin is EIP712, OnlyWethReceiver {
address target,
bytes calldata permit
) external returns(uint256 /* filledMakingAmount */, uint256 /* filledTakingAmount */, bytes32 /* orderHash */) {
console.log("interaction.length:", interaction.length);
IERC20(order.takerAsset.get()).safePermit(permit);
return fillOrderRFQTo(order, signature, interaction, flagsAndAmount, target);
}

/**
* @notice Same as `fillOrderRFQ` but allows to specify funds destination instead of `msg.sender`
* @param order Order quote to fill
* @param signature Signature to confirm quote ownership
* @param flagsAndAmount Fill configuration flags with amount packed in one slot
* @param target Address that will receive swap funds
* @return filledMakingAmount Actual amount transferred from maker to taker
* @return filledTakingAmount Actual amount transferred from taker to maker
* @return orderHash Hash of the filled order
* @notice See {IOrderRFQMixin-fillOrderRFQTo}.
*/
function fillOrderRFQTo(
OrderRFQLib.OrderRFQ calldata order,
Expand Down
33 changes: 33 additions & 0 deletions contracts/interfaces/IOrderMixin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ pragma solidity 0.8.17;
import "../OrderLib.sol";

interface IOrderMixin {
error UnknownOrder();
error AccessDenied();
error AlreadyFilled();
error PermitLengthTooLow();
error ZeroTargetIsForbidden();
error RemainingAmountIsZero();
error PrivateOrder();
error BadSignature();
error ReentrancyDetected();
error PredicateIsNotTrue();
error OnlyOneAmountShouldBeZero();
error TakingAmountTooHigh();
error MakingAmountTooLow();
error SwapWithZeroAmount();
error TransferFromMakerToTakerFailed();
error TransferFromTakerToMakerFailed();
error TakingAmountIncreased();
error SimulationResults(bool success, bytes res);

/// @notice Emitted every time order gets filled, including partial fills
event OrderFilled(
address indexed maker,
bytes32 orderHash,
uint256 remaining
);

/// @notice Emitted when order gets cancelled
event OrderCanceled(
address indexed maker,
bytes32 orderHash,
uint256 remainingRaw
);

/**
* @notice Returns unfilled amount for order. Throws if order does not exist
* @param orderHash Order's hash. Can be obtained by the `hashOrder` function
Expand Down
125 changes: 125 additions & 0 deletions contracts/interfaces/IOrderRFQMixin.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

import "../OrderRFQLib.sol";

interface IOrderRFQMixin {
error RFQZeroTargetIsForbidden();
error RFQPrivateOrder();
error RFQBadSignature();
error OrderExpired();
error MakingAmountExceeded();
error TakingAmountExceeded();
error RFQSwapWithZeroAmount();
error InvalidatedOrder();

/**
* @notice Emitted when RFQ gets filled
* @param orderHash Hash of the order
* @param makingAmount Amount of the maker asset that was transferred from maker to taker
*/
event OrderFilledRFQ(
bytes32 orderHash,
uint256 makingAmount
);

/* @notice Returns bitmask for double-spend invalidators based on lowest byte of order.info and filled quotes
* @param maker Maker address
* @param slot Slot number to return bitmask for
* @return result Each bit represents whether corresponding was already invalidated
*/
function invalidatorForOrderRFQ(address maker, uint256 slot) external view returns(uint256);

/**
* @notice Cancels order's quote
* @param orderInfo Order info (only order id in lowest 64 bits is used)
*/
function cancelOrderRFQ(uint256 orderInfo) external;

/// @notice Cancels multiple order's quotes
function cancelOrderRFQ(uint256 orderInfo, uint256 additionalMask) external;

/**
* @notice Fills order's quote, fully or partially (whichever is possible)
* @param order Order quote to fill
* @param signature Signature to confirm quote ownership
* @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets.
* @param flagsAndAmount Fill configuration flags with amount packed in one slot
* @return filledMakingAmount Actual amount transferred from maker to taker
* @return filledTakingAmount Actual amount transferred from taker to maker
* @return orderHash Hash of the filled order
*/
function fillOrderRFQ(
OrderRFQLib.OrderRFQ calldata order,
bytes calldata signature,
bytes calldata interaction,
uint256 flagsAndAmount
) external payable returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash);

/**
* @notice Fills order's quote, fully or partially, with compact signature
* @param order Order quote to fill
* @param r R component of signature
* @param vs VS component of signature
* @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets.
* @param flagsAndAmount Fill configuration flags with amount packed in one slot
* - Bits 0-251 contain the amount to fill
* - Bit 252 is used to indicate whether weth should be unwrapped to eth
* - Bit 253 is used to indicate whether signature is 64-bit (0) or 65-bit (1)
* - Bit 254 is used to indicate whether smart contract (1) signed the order or not (0)
* - Bit 255 is used to indicate whether maker (1) or taker amount (0) is given in the amount parameter
* @return filledMakingAmount Actual amount transferred from maker to taker
* @return filledTakingAmount Actual amount transferred from taker to maker
* @return orderHash Hash of the filled order
*/
function fillOrderRFQCompact(
OrderRFQLib.OrderRFQ calldata order,
bytes32 r,
bytes32 vs,
bytes calldata interaction,
uint256 flagsAndAmount
) external payable returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash);

/**
* @notice Same as `fillOrderRFQTo` but calls permit first.
* It allows to approve token spending and make a swap in one transaction.
* Also allows to specify funds destination instead of `msg.sender`
* @param order Order quote to fill
* @param signature Signature to confirm quote ownership
* @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets.
* @param flagsAndAmount Fill configuration flags with amount packed in one slot
* @param target Address that will receive swap funds
* @param permit Should contain abi-encoded calldata for `IERC20Permit.permit` call
* @return filledMakingAmount Actual amount transferred from maker to taker
* @return filledTakingAmount Actual amount transferred from taker to maker
* @return orderHash Hash of the filled order
* @dev See tests for examples
*/
function fillOrderRFQToWithPermit(
OrderRFQLib.OrderRFQ calldata order,
bytes calldata signature,
bytes calldata interaction,
uint256 flagsAndAmount,
address target,
bytes calldata permit
) external returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash);

/**
* @notice Same as `fillOrderRFQ` but allows to specify funds destination instead of `msg.sender`
* @param order Order quote to fill
* @param signature Signature to confirm quote ownership
* @param flagsAndAmount Fill configuration flags with amount packed in one slot
* @param target Address that will receive swap funds
* @return filledMakingAmount Actual amount transferred from maker to taker
* @return filledTakingAmount Actual amount transferred from taker to maker
* @return orderHash Hash of the filled order
*/
function fillOrderRFQTo(
OrderRFQLib.OrderRFQ calldata order,
bytes calldata signature,
bytes calldata interaction,
uint256 flagsAndAmount,
address target
) external payable returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash);
}

0 comments on commit c37e11b

Please sign in to comment.