Compare commits
5 Commits
@0x/contra
...
phil/mkr-4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2baaa2b2db | ||
|
|
71292a14ae | ||
|
|
46b3d5b1ab | ||
|
|
b4cf5d5711 | ||
|
|
f69b19faca |
@@ -20,22 +20,17 @@
|
|||||||
pragma solidity ^0.6.5;
|
pragma solidity ^0.6.5;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
import '@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol';
|
||||||
import "../libs/LibSignature.sol";
|
import '../libs/LibSignature.sol';
|
||||||
import "../libs/LibNativeOrder.sol";
|
import '../libs/LibNativeOrder.sol';
|
||||||
import "./INativeOrdersEvents.sol";
|
import './INativeOrdersEvents.sol';
|
||||||
|
|
||||||
|
|
||||||
/// @dev Feature for interacting with limit orders.
|
/// @dev Feature for interacting with limit orders.
|
||||||
interface INativeOrdersFeature is
|
interface INativeOrdersFeature is INativeOrdersEvents {
|
||||||
INativeOrdersEvents
|
|
||||||
{
|
|
||||||
|
|
||||||
/// @dev Transfers protocol fees from the `FeeCollector` pools into
|
/// @dev Transfers protocol fees from the `FeeCollector` pools into
|
||||||
/// the staking contract.
|
/// the staking contract.
|
||||||
/// @param poolIds Staking pool IDs
|
/// @param poolIds Staking pool IDs
|
||||||
function transferProtocolFeesForPools(bytes32[] calldata poolIds)
|
function transferProtocolFeesForPools(bytes32[] calldata poolIds) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Fill a limit order. The taker and sender will be the caller.
|
/// @dev Fill a limit order. The taker and sender will be the caller.
|
||||||
/// @param order The limit order. ETH protocol fees can be
|
/// @param order The limit order. ETH protocol fees can be
|
||||||
@@ -49,10 +44,7 @@ interface INativeOrdersFeature is
|
|||||||
LibNativeOrder.LimitOrder calldata order,
|
LibNativeOrder.LimitOrder calldata order,
|
||||||
LibSignature.Signature calldata signature,
|
LibSignature.Signature calldata signature,
|
||||||
uint128 takerTokenFillAmount
|
uint128 takerTokenFillAmount
|
||||||
)
|
) external payable returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||||
external
|
|
||||||
payable
|
|
||||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
|
||||||
|
|
||||||
/// @dev Fill an RFQ order for up to `takerTokenFillAmount` taker tokens.
|
/// @dev Fill an RFQ order for up to `takerTokenFillAmount` taker tokens.
|
||||||
/// The taker will be the caller.
|
/// The taker will be the caller.
|
||||||
@@ -65,9 +57,7 @@ interface INativeOrdersFeature is
|
|||||||
LibNativeOrder.RfqOrder calldata order,
|
LibNativeOrder.RfqOrder calldata order,
|
||||||
LibSignature.Signature calldata signature,
|
LibSignature.Signature calldata signature,
|
||||||
uint128 takerTokenFillAmount
|
uint128 takerTokenFillAmount
|
||||||
)
|
) external returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||||
external
|
|
||||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
|
||||||
|
|
||||||
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
|
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
|
||||||
/// The taker will be the caller. ETH protocol fees can be
|
/// The taker will be the caller. ETH protocol fees can be
|
||||||
@@ -81,10 +71,7 @@ interface INativeOrdersFeature is
|
|||||||
LibNativeOrder.LimitOrder calldata order,
|
LibNativeOrder.LimitOrder calldata order,
|
||||||
LibSignature.Signature calldata signature,
|
LibSignature.Signature calldata signature,
|
||||||
uint128 takerTokenFillAmount
|
uint128 takerTokenFillAmount
|
||||||
)
|
) external payable returns (uint128 makerTokenFilledAmount);
|
||||||
external
|
|
||||||
payable
|
|
||||||
returns (uint128 makerTokenFilledAmount);
|
|
||||||
|
|
||||||
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
|
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
|
||||||
/// The taker will be the caller.
|
/// The taker will be the caller.
|
||||||
@@ -96,9 +83,7 @@ interface INativeOrdersFeature is
|
|||||||
LibNativeOrder.RfqOrder calldata order,
|
LibNativeOrder.RfqOrder calldata order,
|
||||||
LibSignature.Signature calldata signature,
|
LibSignature.Signature calldata signature,
|
||||||
uint128 takerTokenFillAmount
|
uint128 takerTokenFillAmount
|
||||||
)
|
) external returns (uint128 makerTokenFilledAmount);
|
||||||
external
|
|
||||||
returns (uint128 makerTokenFilledAmount);
|
|
||||||
|
|
||||||
/// @dev Fill a limit order. Internal variant. ETH protocol fees can be
|
/// @dev Fill a limit order. Internal variant. ETH protocol fees can be
|
||||||
/// attached to this call. Any unspent ETH will be refunded to
|
/// attached to this call. Any unspent ETH will be refunded to
|
||||||
@@ -116,10 +101,7 @@ interface INativeOrdersFeature is
|
|||||||
uint128 takerTokenFillAmount,
|
uint128 takerTokenFillAmount,
|
||||||
address taker,
|
address taker,
|
||||||
address sender
|
address sender
|
||||||
)
|
) external payable returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||||
external
|
|
||||||
payable
|
|
||||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
|
||||||
|
|
||||||
/// @dev Fill an RFQ order. Internal variant.
|
/// @dev Fill an RFQ order. Internal variant.
|
||||||
/// @param order The RFQ order.
|
/// @param order The RFQ order.
|
||||||
@@ -138,40 +120,33 @@ interface INativeOrdersFeature is
|
|||||||
address taker,
|
address taker,
|
||||||
bool useSelfBalance,
|
bool useSelfBalance,
|
||||||
address recipient
|
address recipient
|
||||||
)
|
) external returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||||
external
|
|
||||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
|
||||||
|
|
||||||
/// @dev Cancel a single limit order. The caller must be the maker or a valid order signer.
|
/// @dev Cancel a single limit order. The caller must be the maker or a valid order signer.
|
||||||
/// Silently succeeds if the order has already been cancelled.
|
/// Silently succeeds if the order has already been cancelled.
|
||||||
/// @param order The limit order.
|
/// @param order The limit order.
|
||||||
function cancelLimitOrder(LibNativeOrder.LimitOrder calldata order)
|
function cancelLimitOrder(LibNativeOrder.LimitOrder calldata order) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel a single RFQ order. The caller must be the maker or a valid order signer.
|
/// @dev Cancel a single RFQ order. The caller must be the maker or a valid order signer.
|
||||||
/// Silently succeeds if the order has already been cancelled.
|
/// Silently succeeds if the order has already been cancelled.
|
||||||
/// @param order The RFQ order.
|
/// @param order The RFQ order.
|
||||||
function cancelRfqOrder(LibNativeOrder.RfqOrder calldata order)
|
function cancelRfqOrder(LibNativeOrder.RfqOrder calldata order) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Mark what tx.origin addresses are allowed to fill an order that
|
/// @dev Mark what tx.origin addresses are allowed to fill an order that
|
||||||
/// specifies the message sender as its txOrigin.
|
/// specifies the message sender as its txOrigin.
|
||||||
/// @param origins An array of origin addresses to update.
|
/// @param origins An array of origin addresses to update.
|
||||||
/// @param allowed True to register, false to unregister.
|
/// @param allowed True to register, false to unregister.
|
||||||
function registerAllowedRfqOrigins(address[] memory origins, bool allowed)
|
function registerAllowedRfqOrigins(address[] memory origins, bool allowed) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel multiple limit orders. The caller must be the maker or a valid order signer.
|
/// @dev Cancel multiple limit orders. The caller must be the maker or a valid order signer.
|
||||||
/// Silently succeeds if the order has already been cancelled.
|
/// Silently succeeds if the order has already been cancelled.
|
||||||
/// @param orders The limit orders.
|
/// @param orders The limit orders.
|
||||||
function batchCancelLimitOrders(LibNativeOrder.LimitOrder[] calldata orders)
|
function batchCancelLimitOrders(LibNativeOrder.LimitOrder[] calldata orders) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel multiple RFQ orders. The caller must be the maker or a valid order signer.
|
/// @dev Cancel multiple RFQ orders. The caller must be the maker or a valid order signer.
|
||||||
/// Silently succeeds if the order has already been cancelled.
|
/// Silently succeeds if the order has already been cancelled.
|
||||||
/// @param orders The RFQ orders.
|
/// @param orders The RFQ orders.
|
||||||
function batchCancelRfqOrders(LibNativeOrder.RfqOrder[] calldata orders)
|
function batchCancelRfqOrders(LibNativeOrder.RfqOrder[] calldata orders) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel all limit orders for a given maker and pair with a salt less
|
/// @dev Cancel all limit orders for a given maker and pair with a salt less
|
||||||
/// than the value provided. The caller must be the maker. Subsequent
|
/// than the value provided. The caller must be the maker. Subsequent
|
||||||
@@ -184,8 +159,7 @@ interface INativeOrdersFeature is
|
|||||||
IERC20TokenV06 makerToken,
|
IERC20TokenV06 makerToken,
|
||||||
IERC20TokenV06 takerToken,
|
IERC20TokenV06 takerToken,
|
||||||
uint256 minValidSalt
|
uint256 minValidSalt
|
||||||
)
|
) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel all limit orders for a given maker and pair with a salt less
|
/// @dev Cancel all limit orders for a given maker and pair with a salt less
|
||||||
/// than the value provided. The caller must be a signer registered to the maker.
|
/// than the value provided. The caller must be a signer registered to the maker.
|
||||||
@@ -200,8 +174,7 @@ interface INativeOrdersFeature is
|
|||||||
IERC20TokenV06 makerToken,
|
IERC20TokenV06 makerToken,
|
||||||
IERC20TokenV06 takerToken,
|
IERC20TokenV06 takerToken,
|
||||||
uint256 minValidSalt
|
uint256 minValidSalt
|
||||||
)
|
) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel all limit orders for a given maker and pairs with salts less
|
/// @dev Cancel all limit orders for a given maker and pairs with salts less
|
||||||
/// than the values provided. The caller must be the maker. Subsequent
|
/// than the values provided. The caller must be the maker. Subsequent
|
||||||
@@ -214,8 +187,7 @@ interface INativeOrdersFeature is
|
|||||||
IERC20TokenV06[] calldata makerTokens,
|
IERC20TokenV06[] calldata makerTokens,
|
||||||
IERC20TokenV06[] calldata takerTokens,
|
IERC20TokenV06[] calldata takerTokens,
|
||||||
uint256[] calldata minValidSalts
|
uint256[] calldata minValidSalts
|
||||||
)
|
) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel all limit orders for a given maker and pairs with salts less
|
/// @dev Cancel all limit orders for a given maker and pairs with salts less
|
||||||
/// than the values provided. The caller must be a signer registered to the maker.
|
/// than the values provided. The caller must be a signer registered to the maker.
|
||||||
@@ -230,8 +202,7 @@ interface INativeOrdersFeature is
|
|||||||
IERC20TokenV06[] memory makerTokens,
|
IERC20TokenV06[] memory makerTokens,
|
||||||
IERC20TokenV06[] memory takerTokens,
|
IERC20TokenV06[] memory takerTokens,
|
||||||
uint256[] memory minValidSalts
|
uint256[] memory minValidSalts
|
||||||
)
|
) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel all RFQ orders for a given maker and pair with a salt less
|
/// @dev Cancel all RFQ orders for a given maker and pair with a salt less
|
||||||
/// than the value provided. The caller must be the maker. Subsequent
|
/// than the value provided. The caller must be the maker. Subsequent
|
||||||
@@ -244,8 +215,7 @@ interface INativeOrdersFeature is
|
|||||||
IERC20TokenV06 makerToken,
|
IERC20TokenV06 makerToken,
|
||||||
IERC20TokenV06 takerToken,
|
IERC20TokenV06 takerToken,
|
||||||
uint256 minValidSalt
|
uint256 minValidSalt
|
||||||
)
|
) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel all RFQ orders for a given maker and pair with a salt less
|
/// @dev Cancel all RFQ orders for a given maker and pair with a salt less
|
||||||
/// than the value provided. The caller must be a signer registered to the maker.
|
/// than the value provided. The caller must be a signer registered to the maker.
|
||||||
@@ -260,8 +230,7 @@ interface INativeOrdersFeature is
|
|||||||
IERC20TokenV06 makerToken,
|
IERC20TokenV06 makerToken,
|
||||||
IERC20TokenV06 takerToken,
|
IERC20TokenV06 takerToken,
|
||||||
uint256 minValidSalt
|
uint256 minValidSalt
|
||||||
)
|
) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel all RFQ orders for a given maker and pairs with salts less
|
/// @dev Cancel all RFQ orders for a given maker and pairs with salts less
|
||||||
/// than the values provided. The caller must be the maker. Subsequent
|
/// than the values provided. The caller must be the maker. Subsequent
|
||||||
@@ -274,8 +243,7 @@ interface INativeOrdersFeature is
|
|||||||
IERC20TokenV06[] calldata makerTokens,
|
IERC20TokenV06[] calldata makerTokens,
|
||||||
IERC20TokenV06[] calldata takerTokens,
|
IERC20TokenV06[] calldata takerTokens,
|
||||||
uint256[] calldata minValidSalts
|
uint256[] calldata minValidSalts
|
||||||
)
|
) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Cancel all RFQ orders for a given maker and pairs with salts less
|
/// @dev Cancel all RFQ orders for a given maker and pairs with salts less
|
||||||
/// than the values provided. The caller must be a signer registered to the maker.
|
/// than the values provided. The caller must be a signer registered to the maker.
|
||||||
@@ -290,8 +258,7 @@ interface INativeOrdersFeature is
|
|||||||
IERC20TokenV06[] memory makerTokens,
|
IERC20TokenV06[] memory makerTokens,
|
||||||
IERC20TokenV06[] memory takerTokens,
|
IERC20TokenV06[] memory takerTokens,
|
||||||
uint256[] memory minValidSalts
|
uint256[] memory minValidSalts
|
||||||
)
|
) external;
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev Get the order info for a limit order.
|
/// @dev Get the order info for a limit order.
|
||||||
/// @param order The limit order.
|
/// @param order The limit order.
|
||||||
@@ -312,26 +279,17 @@ interface INativeOrdersFeature is
|
|||||||
/// @dev Get the canonical hash of a limit order.
|
/// @dev Get the canonical hash of a limit order.
|
||||||
/// @param order The limit order.
|
/// @param order The limit order.
|
||||||
/// @return orderHash The order hash.
|
/// @return orderHash The order hash.
|
||||||
function getLimitOrderHash(LibNativeOrder.LimitOrder calldata order)
|
function getLimitOrderHash(LibNativeOrder.LimitOrder calldata order) external view returns (bytes32 orderHash);
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (bytes32 orderHash);
|
|
||||||
|
|
||||||
/// @dev Get the canonical hash of an RFQ order.
|
/// @dev Get the canonical hash of an RFQ order.
|
||||||
/// @param order The RFQ order.
|
/// @param order The RFQ order.
|
||||||
/// @return orderHash The order hash.
|
/// @return orderHash The order hash.
|
||||||
function getRfqOrderHash(LibNativeOrder.RfqOrder calldata order)
|
function getRfqOrderHash(LibNativeOrder.RfqOrder calldata order) external view returns (bytes32 orderHash);
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (bytes32 orderHash);
|
|
||||||
|
|
||||||
/// @dev Get the protocol fee multiplier. This should be multiplied by the
|
/// @dev Get the protocol fee multiplier. This should be multiplied by the
|
||||||
/// gas price to arrive at the required protocol fee to fill a native order.
|
/// gas price to arrive at the required protocol fee to fill a native order.
|
||||||
/// @return multiplier The protocol fee multiplier.
|
/// @return multiplier The protocol fee multiplier.
|
||||||
function getProtocolFeeMultiplier()
|
function getProtocolFeeMultiplier() external view returns (uint32 multiplier);
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (uint32 multiplier);
|
|
||||||
|
|
||||||
/// @dev Get order info, fillable amount, and signature validity for a limit order.
|
/// @dev Get order info, fillable amount, and signature validity for a limit order.
|
||||||
/// Fillable amount is determined using balances and allowances of the maker.
|
/// Fillable amount is determined using balances and allowances of the maker.
|
||||||
@@ -361,10 +319,7 @@ interface INativeOrdersFeature is
|
|||||||
/// @return actualFillableTakerTokenAmount How much of the order is fillable
|
/// @return actualFillableTakerTokenAmount How much of the order is fillable
|
||||||
/// based on maker funds, in taker tokens.
|
/// based on maker funds, in taker tokens.
|
||||||
/// @return isSignatureValid Whether the signature is valid.
|
/// @return isSignatureValid Whether the signature is valid.
|
||||||
function getRfqOrderRelevantState(
|
function getRfqOrderRelevantState(LibNativeOrder.RfqOrder calldata order, LibSignature.Signature calldata signature)
|
||||||
LibNativeOrder.RfqOrder calldata order,
|
|
||||||
LibSignature.Signature calldata signature
|
|
||||||
)
|
|
||||||
external
|
external
|
||||||
view
|
view
|
||||||
returns (
|
returns (
|
||||||
@@ -419,20 +374,10 @@ interface INativeOrdersFeature is
|
|||||||
/// This allows one to sign on behalf of a contract that calls this function
|
/// This allows one to sign on behalf of a contract that calls this function
|
||||||
/// @param signer The address from which you plan to generate signatures
|
/// @param signer The address from which you plan to generate signatures
|
||||||
/// @param allowed True to register, false to unregister.
|
/// @param allowed True to register, false to unregister.
|
||||||
function registerAllowedOrderSigner(
|
function registerAllowedOrderSigner(address signer, bool allowed) external;
|
||||||
address signer,
|
|
||||||
bool allowed
|
|
||||||
)
|
|
||||||
external;
|
|
||||||
|
|
||||||
/// @dev checks if a given address is registered to sign on behalf of a maker address
|
/// @dev checks if a given address is registered to sign on behalf of a maker address
|
||||||
/// @param maker The maker address encoded in an order (can be a contract)
|
/// @param maker The maker address encoded in an order (can be a contract)
|
||||||
/// @param signer The address that is providing a signature
|
/// @param signer The address that is providing a signature
|
||||||
function isValidOrderSigner(
|
function isValidOrderSigner(address maker, address signer) external view returns (bool isAllowed);
|
||||||
address maker,
|
|
||||||
address signer
|
|
||||||
)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (bool isAllowed);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,23 +20,22 @@
|
|||||||
pragma solidity ^0.6.5;
|
pragma solidity ^0.6.5;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
import '@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol';
|
||||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
import '@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol';
|
||||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
import '@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol';
|
||||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
import '@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol';
|
||||||
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
|
import '@0x/contracts-utils/contracts/src/v06/LibMathV06.sol';
|
||||||
import "../errors/LibTransformERC20RichErrors.sol";
|
import '../errors/LibTransformERC20RichErrors.sol';
|
||||||
import "../features/interfaces/INativeOrdersFeature.sol";
|
import '../features/interfaces/INativeOrdersFeature.sol';
|
||||||
import "../features/libs/LibNativeOrder.sol";
|
import '../features/libs/LibNativeOrder.sol';
|
||||||
import "./bridges/IBridgeAdapter.sol";
|
import './bridges/IBridgeAdapter.sol';
|
||||||
import "./Transformer.sol";
|
import './Transformer.sol';
|
||||||
import "./LibERC20Transformer.sol";
|
import './LibERC20Transformer.sol';
|
||||||
|
import '../IZeroEx.sol';
|
||||||
|
|
||||||
/// @dev A transformer that fills an ERC20 market sell/buy quote.
|
/// @dev A transformer that fills an ERC20 market sell/buy quote.
|
||||||
/// This transformer shortcuts bridge orders and fills them directly
|
/// This transformer shortcuts bridge orders and fills them directly
|
||||||
contract FillQuoteTransformer is
|
contract FillQuoteTransformer is Transformer {
|
||||||
Transformer
|
|
||||||
{
|
|
||||||
using LibERC20TokenV06 for IERC20TokenV06;
|
using LibERC20TokenV06 for IERC20TokenV06;
|
||||||
using LibERC20Transformer for IERC20TokenV06;
|
using LibERC20Transformer for IERC20TokenV06;
|
||||||
using LibSafeMathV06 for uint256;
|
using LibSafeMathV06 for uint256;
|
||||||
@@ -52,7 +51,8 @@ contract FillQuoteTransformer is
|
|||||||
enum OrderType {
|
enum OrderType {
|
||||||
Bridge,
|
Bridge,
|
||||||
Limit,
|
Limit,
|
||||||
Rfq
|
Rfq,
|
||||||
|
Otc
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LimitOrderInfo {
|
struct LimitOrderInfo {
|
||||||
@@ -69,6 +69,13 @@ contract FillQuoteTransformer is
|
|||||||
uint256 maxTakerTokenFillAmount;
|
uint256 maxTakerTokenFillAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct OtcOrderInfo {
|
||||||
|
LibNativeOrder.OtcOrder order;
|
||||||
|
LibSignature.Signature signature;
|
||||||
|
// Maximum taker token amount of this limit order to fill.
|
||||||
|
uint256 maxTakerTokenFillAmount;
|
||||||
|
}
|
||||||
|
|
||||||
/// @dev Transform data to ABI-encode and pass into `transform()`.
|
/// @dev Transform data to ABI-encode and pass into `transform()`.
|
||||||
struct TransformData {
|
struct TransformData {
|
||||||
// Whether we are performing a market sell or buy.
|
// Whether we are performing a market sell or buy.
|
||||||
@@ -79,26 +86,24 @@ contract FillQuoteTransformer is
|
|||||||
// The token being bought.
|
// The token being bought.
|
||||||
// This should be an actual token, not the ETH pseudo-token.
|
// This should be an actual token, not the ETH pseudo-token.
|
||||||
IERC20TokenV06 buyToken;
|
IERC20TokenV06 buyToken;
|
||||||
|
|
||||||
// External liquidity bridge orders. Sorted by fill sequence.
|
// External liquidity bridge orders. Sorted by fill sequence.
|
||||||
IBridgeAdapter.BridgeOrder[] bridgeOrders;
|
IBridgeAdapter.BridgeOrder[] bridgeOrders;
|
||||||
// Native limit orders. Sorted by fill sequence.
|
// Native limit orders. Sorted by fill sequence.
|
||||||
LimitOrderInfo[] limitOrders;
|
LimitOrderInfo[] limitOrders;
|
||||||
// Native RFQ orders. Sorted by fill sequence.
|
// Native RFQ orders. Sorted by fill sequence.
|
||||||
RfqOrderInfo[] rfqOrders;
|
RfqOrderInfo[] rfqOrders;
|
||||||
|
// Otc orders.
|
||||||
|
OtcOrderInfo[] otcOrders;
|
||||||
// The sequence to fill the orders in. Each item will fill the next
|
// The sequence to fill the orders in. Each item will fill the next
|
||||||
// order of that type in either `bridgeOrders`, `limitOrders`,
|
// order of that type in either `bridgeOrders`, `limitOrders`,
|
||||||
// or `rfqOrders.`
|
// `rfqOrders`, or `otcOrders.`
|
||||||
OrderType[] fillSequence;
|
OrderType[] fillSequence;
|
||||||
|
|
||||||
// Amount of `sellToken` to sell or `buyToken` to buy.
|
// Amount of `sellToken` to sell or `buyToken` to buy.
|
||||||
// For sells, setting the high-bit indicates that
|
// For sells, setting the high-bit indicates that
|
||||||
// `sellAmount & LOW_BITS` should be treated as a `1e18` fraction of
|
// `sellAmount & LOW_BITS` should be treated as a `1e18` fraction of
|
||||||
// the current balance of `sellToken`, where
|
// the current balance of `sellToken`, where
|
||||||
// `1e18+ == 100%` and `0.5e18 == 50%`, etc.
|
// `1e18+ == 100%` and `0.5e18 == 50%`, etc.
|
||||||
uint256 fillAmount;
|
uint256 fillAmount;
|
||||||
|
|
||||||
// Who to transfer unused protocol fees to.
|
// Who to transfer unused protocol fees to.
|
||||||
// May be a valid address or one of:
|
// May be a valid address or one of:
|
||||||
// `address(0)`: Stay in flash wallet.
|
// `address(0)`: Stay in flash wallet.
|
||||||
@@ -123,7 +128,7 @@ contract FillQuoteTransformer is
|
|||||||
uint256 soldAmount;
|
uint256 soldAmount;
|
||||||
uint256 protocolFee;
|
uint256 protocolFee;
|
||||||
uint256 takerTokenBalanceRemaining;
|
uint256 takerTokenBalanceRemaining;
|
||||||
uint256[3] currentIndices;
|
uint256[4] currentIndices;
|
||||||
OrderType currentOrderType;
|
OrderType currentOrderType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +138,7 @@ contract FillQuoteTransformer is
|
|||||||
event ProtocolFeeUnfunded(bytes32 orderHash);
|
event ProtocolFeeUnfunded(bytes32 orderHash);
|
||||||
|
|
||||||
/// @dev The highest bit of a uint256 value.
|
/// @dev The highest bit of a uint256 value.
|
||||||
uint256 private constant HIGH_BIT = 2 ** 255;
|
uint256 private constant HIGH_BIT = 2**255;
|
||||||
/// @dev Mask of the lower 255 bits of a uint256 value.
|
/// @dev Mask of the lower 255 bits of a uint256 value.
|
||||||
uint256 private constant LOWER_255_BITS = HIGH_BIT - 1;
|
uint256 private constant LOWER_255_BITS = HIGH_BIT - 1;
|
||||||
/// @dev If `refundReceiver` is set to this address, unpsent
|
/// @dev If `refundReceiver` is set to this address, unpsent
|
||||||
@@ -147,15 +152,12 @@ contract FillQuoteTransformer is
|
|||||||
IBridgeAdapter public immutable bridgeAdapter;
|
IBridgeAdapter public immutable bridgeAdapter;
|
||||||
|
|
||||||
/// @dev The exchange proxy contract.
|
/// @dev The exchange proxy contract.
|
||||||
INativeOrdersFeature public immutable zeroEx;
|
IZeroEx public immutable zeroEx;
|
||||||
|
|
||||||
/// @dev Create this contract.
|
/// @dev Create this contract.
|
||||||
/// @param bridgeAdapter_ The bridge adapter contract.
|
/// @param bridgeAdapter_ The bridge adapter contract.
|
||||||
/// @param zeroEx_ The Exchange Proxy contract.
|
/// @param zeroEx_ The Exchange Proxy contract.
|
||||||
constructor(IBridgeAdapter bridgeAdapter_, INativeOrdersFeature zeroEx_)
|
constructor(IBridgeAdapter bridgeAdapter_, IZeroEx zeroEx_) public Transformer() {
|
||||||
public
|
|
||||||
Transformer()
|
|
||||||
{
|
|
||||||
bridgeAdapter = bridgeAdapter_;
|
bridgeAdapter = bridgeAdapter_;
|
||||||
zeroEx = zeroEx_;
|
zeroEx = zeroEx_;
|
||||||
}
|
}
|
||||||
@@ -165,30 +167,27 @@ contract FillQuoteTransformer is
|
|||||||
/// to this call. `buyToken` and excess ETH will be transferred back to the caller.
|
/// to this call. `buyToken` and excess ETH will be transferred back to the caller.
|
||||||
/// @param context Context information.
|
/// @param context Context information.
|
||||||
/// @return magicBytes The success bytes (`LibERC20Transformer.TRANSFORMER_SUCCESS`).
|
/// @return magicBytes The success bytes (`LibERC20Transformer.TRANSFORMER_SUCCESS`).
|
||||||
function transform(TransformContext calldata context)
|
function transform(TransformContext calldata context) external override returns (bytes4 magicBytes) {
|
||||||
external
|
|
||||||
override
|
|
||||||
returns (bytes4 magicBytes)
|
|
||||||
{
|
|
||||||
TransformData memory data = abi.decode(context.data, (TransformData));
|
TransformData memory data = abi.decode(context.data, (TransformData));
|
||||||
FillState memory state;
|
FillState memory state;
|
||||||
|
|
||||||
// Validate data fields.
|
// Validate data fields.
|
||||||
if (data.sellToken.isTokenETH() || data.buyToken.isTokenETH()) {
|
if (data.sellToken.isTokenETH() || data.buyToken.isTokenETH()) {
|
||||||
LibTransformERC20RichErrors.InvalidTransformDataError(
|
LibTransformERC20RichErrors
|
||||||
LibTransformERC20RichErrors.InvalidTransformDataErrorCode.INVALID_TOKENS,
|
.InvalidTransformDataError(
|
||||||
context.data
|
LibTransformERC20RichErrors.InvalidTransformDataErrorCode.INVALID_TOKENS,
|
||||||
).rrevert();
|
context.data
|
||||||
|
)
|
||||||
|
.rrevert();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.bridgeOrders.length
|
if (data.bridgeOrders.length + data.limitOrders.length + data.rfqOrders.length != data.fillSequence.length) {
|
||||||
+ data.limitOrders.length
|
LibTransformERC20RichErrors
|
||||||
+ data.rfqOrders.length != data.fillSequence.length
|
.InvalidTransformDataError(
|
||||||
) {
|
LibTransformERC20RichErrors.InvalidTransformDataErrorCode.INVALID_ARRAY_LENGTH,
|
||||||
LibTransformERC20RichErrors.InvalidTransformDataError(
|
context.data
|
||||||
LibTransformERC20RichErrors.InvalidTransformDataErrorCode.INVALID_ARRAY_LENGTH,
|
)
|
||||||
context.data
|
.rrevert();
|
||||||
).rrevert();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.takerTokenBalanceRemaining = data.sellToken.getTokenBalanceOf(address(this));
|
state.takerTokenBalanceRemaining = data.sellToken.getTokenBalanceOf(address(this));
|
||||||
@@ -202,8 +201,7 @@ contract FillQuoteTransformer is
|
|||||||
data.sellToken.approveIfBelow(address(zeroEx), data.fillAmount);
|
data.sellToken.approveIfBelow(address(zeroEx), data.fillAmount);
|
||||||
// Compute the protocol fee if a limit order is present.
|
// Compute the protocol fee if a limit order is present.
|
||||||
if (data.limitOrders.length != 0) {
|
if (data.limitOrders.length != 0) {
|
||||||
state.protocolFee = uint256(zeroEx.getProtocolFeeMultiplier())
|
state.protocolFee = uint256(zeroEx.getProtocolFeeMultiplier()).safeMul(tx.gasprice);
|
||||||
.safeMul(tx.gasprice);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,10 +212,14 @@ contract FillQuoteTransformer is
|
|||||||
// Check if we've hit our targets.
|
// Check if we've hit our targets.
|
||||||
if (data.side == Side.Sell) {
|
if (data.side == Side.Sell) {
|
||||||
// Market sell check.
|
// Market sell check.
|
||||||
if (state.soldAmount >= data.fillAmount) { break; }
|
if (state.soldAmount >= data.fillAmount) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Market buy check.
|
// Market buy check.
|
||||||
if (state.boughtAmount >= data.fillAmount) { break; }
|
if (state.boughtAmount >= data.fillAmount) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.currentOrderType = OrderType(data.fillSequence[i]);
|
state.currentOrderType = OrderType(data.fillSequence[i]);
|
||||||
@@ -230,19 +232,17 @@ contract FillQuoteTransformer is
|
|||||||
results = _fillLimitOrder(data.limitOrders[orderIndex], data, state);
|
results = _fillLimitOrder(data.limitOrders[orderIndex], data, state);
|
||||||
} else if (state.currentOrderType == OrderType.Rfq) {
|
} else if (state.currentOrderType == OrderType.Rfq) {
|
||||||
results = _fillRfqOrder(data.rfqOrders[orderIndex], data, state);
|
results = _fillRfqOrder(data.rfqOrders[orderIndex], data, state);
|
||||||
|
} else if (state.currentOrderType == OrderType.Otc) {
|
||||||
|
results = _fillOtcOrder(data.otcOrders[orderIndex], data, state);
|
||||||
} else {
|
} else {
|
||||||
revert("INVALID_ORDER_TYPE");
|
revert('INVALID_ORDER_TYPE');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accumulate totals.
|
// Accumulate totals.
|
||||||
state.soldAmount = state.soldAmount
|
state.soldAmount = state.soldAmount.safeAdd(results.takerTokenSoldAmount);
|
||||||
.safeAdd(results.takerTokenSoldAmount);
|
state.boughtAmount = state.boughtAmount.safeAdd(results.makerTokenBoughtAmount);
|
||||||
state.boughtAmount = state.boughtAmount
|
state.ethRemaining = state.ethRemaining.safeSub(results.protocolFeePaid);
|
||||||
.safeAdd(results.makerTokenBoughtAmount);
|
state.takerTokenBalanceRemaining = state.takerTokenBalanceRemaining.safeSub(results.takerTokenSoldAmount);
|
||||||
state.ethRemaining = state.ethRemaining
|
|
||||||
.safeSub(results.protocolFeePaid);
|
|
||||||
state.takerTokenBalanceRemaining = state.takerTokenBalanceRemaining
|
|
||||||
.safeSub(results.takerTokenSoldAmount);
|
|
||||||
state.currentIndices[uint256(state.currentOrderType)]++;
|
state.currentIndices[uint256(state.currentOrderType)]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,21 +251,15 @@ contract FillQuoteTransformer is
|
|||||||
// Market sell check.
|
// Market sell check.
|
||||||
if (state.soldAmount < data.fillAmount) {
|
if (state.soldAmount < data.fillAmount) {
|
||||||
LibTransformERC20RichErrors
|
LibTransformERC20RichErrors
|
||||||
.IncompleteFillSellQuoteError(
|
.IncompleteFillSellQuoteError(address(data.sellToken), state.soldAmount, data.fillAmount)
|
||||||
address(data.sellToken),
|
.rrevert();
|
||||||
state.soldAmount,
|
|
||||||
data.fillAmount
|
|
||||||
).rrevert();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Market buy check.
|
// Market buy check.
|
||||||
if (state.boughtAmount < data.fillAmount) {
|
if (state.boughtAmount < data.fillAmount) {
|
||||||
LibTransformERC20RichErrors
|
LibTransformERC20RichErrors
|
||||||
.IncompleteFillBuyQuoteError(
|
.IncompleteFillBuyQuoteError(address(data.buyToken), state.boughtAmount, data.fillAmount)
|
||||||
address(data.buyToken),
|
.rrevert();
|
||||||
state.boughtAmount,
|
|
||||||
data.fillAmount
|
|
||||||
).rrevert();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,13 +267,13 @@ contract FillQuoteTransformer is
|
|||||||
if (state.ethRemaining > 0 && data.refundReceiver != address(0)) {
|
if (state.ethRemaining > 0 && data.refundReceiver != address(0)) {
|
||||||
bool transferSuccess;
|
bool transferSuccess;
|
||||||
if (data.refundReceiver == REFUND_RECEIVER_RECIPIENT) {
|
if (data.refundReceiver == REFUND_RECEIVER_RECIPIENT) {
|
||||||
(transferSuccess,) = context.recipient.call{value: state.ethRemaining}("");
|
(transferSuccess, ) = context.recipient.call{ value: state.ethRemaining }('');
|
||||||
} else if (data.refundReceiver == REFUND_RECEIVER_SENDER) {
|
} else if (data.refundReceiver == REFUND_RECEIVER_SENDER) {
|
||||||
(transferSuccess,) = context.sender.call{value: state.ethRemaining}("");
|
(transferSuccess, ) = context.sender.call{ value: state.ethRemaining }('');
|
||||||
} else {
|
} else {
|
||||||
(transferSuccess,) = data.refundReceiver.call{value: state.ethRemaining}("");
|
(transferSuccess, ) = data.refundReceiver.call{ value: state.ethRemaining }('');
|
||||||
}
|
}
|
||||||
require(transferSuccess, "FillQuoteTransformer/ETHER_TRANSFER_FALIED");
|
require(transferSuccess, 'FillQuoteTransformer/ETHER_TRANSFER_FALIED');
|
||||||
}
|
}
|
||||||
return LibERC20Transformer.TRANSFORMER_SUCCESS;
|
return LibERC20Transformer.TRANSFORMER_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -289,10 +283,7 @@ contract FillQuoteTransformer is
|
|||||||
IBridgeAdapter.BridgeOrder memory order,
|
IBridgeAdapter.BridgeOrder memory order,
|
||||||
TransformData memory data,
|
TransformData memory data,
|
||||||
FillState memory state
|
FillState memory state
|
||||||
)
|
) private returns (FillOrderResults memory results) {
|
||||||
private
|
|
||||||
returns (FillOrderResults memory results)
|
|
||||||
{
|
|
||||||
uint256 takerTokenFillAmount = _computeTakerTokenFillAmount(
|
uint256 takerTokenFillAmount = _computeTakerTokenFillAmount(
|
||||||
data,
|
data,
|
||||||
state,
|
state,
|
||||||
@@ -321,10 +312,7 @@ contract FillQuoteTransformer is
|
|||||||
LimitOrderInfo memory orderInfo,
|
LimitOrderInfo memory orderInfo,
|
||||||
TransformData memory data,
|
TransformData memory data,
|
||||||
FillState memory state
|
FillState memory state
|
||||||
)
|
) private returns (FillOrderResults memory results) {
|
||||||
private
|
|
||||||
returns (FillOrderResults memory results)
|
|
||||||
{
|
|
||||||
uint256 takerTokenFillAmount = LibSafeMathV06.min256(
|
uint256 takerTokenFillAmount = LibSafeMathV06.min256(
|
||||||
_computeTakerTokenFillAmount(
|
_computeTakerTokenFillAmount(
|
||||||
data,
|
data,
|
||||||
@@ -344,22 +332,21 @@ contract FillQuoteTransformer is
|
|||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
zeroEx.fillLimitOrder
|
zeroEx.fillLimitOrder{ value: state.protocolFee }(
|
||||||
{value: state.protocolFee}
|
orderInfo.order,
|
||||||
(
|
orderInfo.signature,
|
||||||
orderInfo.order,
|
takerTokenFillAmount.safeDowncastToUint128()
|
||||||
orderInfo.signature,
|
)
|
||||||
takerTokenFillAmount.safeDowncastToUint128()
|
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) {
|
||||||
)
|
|
||||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
|
|
||||||
{
|
|
||||||
if (orderInfo.order.takerTokenFeeAmount > 0) {
|
if (orderInfo.order.takerTokenFeeAmount > 0) {
|
||||||
takerTokenFilledAmount = takerTokenFilledAmount.safeAdd128(
|
takerTokenFilledAmount = takerTokenFilledAmount.safeAdd128(
|
||||||
LibMathV06.getPartialAmountFloor(
|
LibMathV06
|
||||||
takerTokenFilledAmount,
|
.getPartialAmountFloor(
|
||||||
orderInfo.order.takerAmount,
|
takerTokenFilledAmount,
|
||||||
orderInfo.order.takerTokenFeeAmount
|
orderInfo.order.takerAmount,
|
||||||
).safeDowncastToUint128()
|
orderInfo.order.takerTokenFeeAmount
|
||||||
|
)
|
||||||
|
.safeDowncastToUint128()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
results.takerTokenSoldAmount = takerTokenFilledAmount;
|
results.takerTokenSoldAmount = takerTokenFilledAmount;
|
||||||
@@ -373,30 +360,34 @@ contract FillQuoteTransformer is
|
|||||||
RfqOrderInfo memory orderInfo,
|
RfqOrderInfo memory orderInfo,
|
||||||
TransformData memory data,
|
TransformData memory data,
|
||||||
FillState memory state
|
FillState memory state
|
||||||
)
|
) private returns (FillOrderResults memory results) {
|
||||||
private
|
|
||||||
returns (FillOrderResults memory results)
|
|
||||||
{
|
|
||||||
uint256 takerTokenFillAmount = LibSafeMathV06.min256(
|
uint256 takerTokenFillAmount = LibSafeMathV06.min256(
|
||||||
_computeTakerTokenFillAmount(
|
_computeTakerTokenFillAmount(data, state, orderInfo.order.takerAmount, orderInfo.order.makerAmount, 0),
|
||||||
data,
|
|
||||||
state,
|
|
||||||
orderInfo.order.takerAmount,
|
|
||||||
orderInfo.order.makerAmount,
|
|
||||||
0
|
|
||||||
),
|
|
||||||
orderInfo.maxTakerTokenFillAmount
|
orderInfo.maxTakerTokenFillAmount
|
||||||
);
|
);
|
||||||
|
|
||||||
try
|
try
|
||||||
zeroEx.fillRfqOrder
|
zeroEx.fillRfqOrder(orderInfo.order, orderInfo.signature, takerTokenFillAmount.safeDowncastToUint128())
|
||||||
(
|
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) {
|
||||||
orderInfo.order,
|
results.takerTokenSoldAmount = takerTokenFilledAmount;
|
||||||
orderInfo.signature,
|
results.makerTokenBoughtAmount = makerTokenFilledAmount;
|
||||||
takerTokenFillAmount.safeDowncastToUint128()
|
} catch {}
|
||||||
)
|
}
|
||||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
|
|
||||||
{
|
// Fill a single OTC order.
|
||||||
|
function _fillOtcOrder(
|
||||||
|
OtcOrderInfo memory orderInfo,
|
||||||
|
TransformData memory data,
|
||||||
|
FillState memory state
|
||||||
|
) private returns (FillOrderResults memory results) {
|
||||||
|
uint256 takerTokenFillAmount = LibSafeMathV06.min256(
|
||||||
|
_computeTakerTokenFillAmount(data, state, orderInfo.order.takerAmount, orderInfo.order.makerAmount, 0),
|
||||||
|
orderInfo.maxTakerTokenFillAmount
|
||||||
|
);
|
||||||
|
|
||||||
|
try
|
||||||
|
zeroEx.fillOtcOrder(orderInfo.order, orderInfo.signature, takerTokenFillAmount.safeDowncastToUint128())
|
||||||
|
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) {
|
||||||
results.takerTokenSoldAmount = takerTokenFilledAmount;
|
results.takerTokenSoldAmount = takerTokenFilledAmount;
|
||||||
results.makerTokenBoughtAmount = makerTokenFilledAmount;
|
results.makerTokenBoughtAmount = makerTokenFilledAmount;
|
||||||
} catch {}
|
} catch {}
|
||||||
@@ -409,11 +400,7 @@ contract FillQuoteTransformer is
|
|||||||
uint256 orderTakerAmount,
|
uint256 orderTakerAmount,
|
||||||
uint256 orderMakerAmount,
|
uint256 orderMakerAmount,
|
||||||
uint256 orderTakerTokenFeeAmount
|
uint256 orderTakerTokenFeeAmount
|
||||||
)
|
) private pure returns (uint256 takerTokenFillAmount) {
|
||||||
private
|
|
||||||
pure
|
|
||||||
returns (uint256 takerTokenFillAmount)
|
|
||||||
{
|
|
||||||
if (data.side == Side.Sell) {
|
if (data.side == Side.Sell) {
|
||||||
takerTokenFillAmount = data.fillAmount.safeSub(state.soldAmount);
|
takerTokenFillAmount = data.fillAmount.safeSub(state.soldAmount);
|
||||||
if (orderTakerTokenFeeAmount != 0) {
|
if (orderTakerTokenFeeAmount != 0) {
|
||||||
@@ -423,34 +410,31 @@ contract FillQuoteTransformer is
|
|||||||
orderTakerAmount
|
orderTakerAmount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else { // Buy
|
} else {
|
||||||
|
// Buy
|
||||||
takerTokenFillAmount = LibMathV06.getPartialAmountCeil(
|
takerTokenFillAmount = LibMathV06.getPartialAmountCeil(
|
||||||
data.fillAmount.safeSub(state.boughtAmount),
|
data.fillAmount.safeSub(state.boughtAmount),
|
||||||
orderMakerAmount,
|
orderMakerAmount,
|
||||||
orderTakerAmount
|
orderTakerAmount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return LibSafeMathV06.min256(
|
return
|
||||||
LibSafeMathV06.min256(takerTokenFillAmount, orderTakerAmount),
|
LibSafeMathV06.min256(
|
||||||
state.takerTokenBalanceRemaining
|
LibSafeMathV06.min256(takerTokenFillAmount, orderTakerAmount),
|
||||||
);
|
state.takerTokenBalanceRemaining
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert possible proportional values to absolute quantities.
|
// Convert possible proportional values to absolute quantities.
|
||||||
function _normalizeFillAmount(uint256 rawAmount, uint256 balance)
|
function _normalizeFillAmount(uint256 rawAmount, uint256 balance) private pure returns (uint256 normalized) {
|
||||||
private
|
|
||||||
pure
|
|
||||||
returns (uint256 normalized)
|
|
||||||
{
|
|
||||||
if ((rawAmount & HIGH_BIT) == HIGH_BIT) {
|
if ((rawAmount & HIGH_BIT) == HIGH_BIT) {
|
||||||
// If the high bit of `rawAmount` is set then the lower 255 bits
|
// If the high bit of `rawAmount` is set then the lower 255 bits
|
||||||
// specify a fraction of `balance`.
|
// specify a fraction of `balance`.
|
||||||
return LibSafeMathV06.min256(
|
return
|
||||||
balance
|
LibSafeMathV06.min256(
|
||||||
* LibSafeMathV06.min256(rawAmount & LOWER_255_BITS, 1e18)
|
(balance * LibSafeMathV06.min256(rawAmount & LOWER_255_BITS, 1e18)) / 1e18,
|
||||||
/ 1e18,
|
balance
|
||||||
balance
|
);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return rawAmount;
|
return rawAmount;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.5.0",
|
"@0x/base-contract": "^6.5.0",
|
||||||
|
"@0x/contracts-utils": "^4.8.12",
|
||||||
"@0x/protocol-utils": "^11.13.0",
|
"@0x/protocol-utils": "^11.13.0",
|
||||||
"@0x/subproviders": "^6.6.5",
|
"@0x/subproviders": "^6.6.5",
|
||||||
"@0x/types": "^3.3.6",
|
"@0x/types": "^3.3.6",
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import {
|
|||||||
FillQuoteTransformerSide as Side,
|
FillQuoteTransformerSide as Side,
|
||||||
LimitOrder,
|
LimitOrder,
|
||||||
LimitOrderFields,
|
LimitOrderFields,
|
||||||
|
OtcOrder,
|
||||||
|
OtcOrderFields,
|
||||||
RfqOrder,
|
RfqOrder,
|
||||||
RfqOrderFields,
|
RfqOrderFields,
|
||||||
Signature,
|
Signature,
|
||||||
@@ -26,10 +28,11 @@ import * as _ from 'lodash';
|
|||||||
|
|
||||||
import { artifacts } from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
import { TestFillQuoteTransformerBridgeContract } from '../generated-wrappers/test_fill_quote_transformer_bridge';
|
import { TestFillQuoteTransformerBridgeContract } from '../generated-wrappers/test_fill_quote_transformer_bridge';
|
||||||
import { getRandomLimitOrder, getRandomRfqOrder } from '../utils/orders';
|
import { getRandomLimitOrder, getRandomRfqOrder, getRandomOtcOrder } from '../utils/orders';
|
||||||
import {
|
import {
|
||||||
BridgeAdapterContract,
|
BridgeAdapterContract,
|
||||||
FillQuoteTransformerContract,
|
FillQuoteTransformerContract,
|
||||||
|
OtcOrdersFeatureContract,
|
||||||
TestFillQuoteTransformerExchangeContract,
|
TestFillQuoteTransformerExchangeContract,
|
||||||
TestFillQuoteTransformerHostContract,
|
TestFillQuoteTransformerHostContract,
|
||||||
TestMintableERC20TokenContract,
|
TestMintableERC20TokenContract,
|
||||||
@@ -71,6 +74,15 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
|||||||
artifacts,
|
artifacts,
|
||||||
NULL_ADDRESS,
|
NULL_ADDRESS,
|
||||||
);
|
);
|
||||||
|
const otcOrder = await OtcOrdersFeatureContract.deployFrom0xArtifactAsync(
|
||||||
|
artifacts.OtcOrdersFeature,
|
||||||
|
env.provider,
|
||||||
|
env.txDefaults,
|
||||||
|
artifacts,
|
||||||
|
NULL_ADDRESS,
|
||||||
|
NULL_ADDRESS, // weth
|
||||||
|
);
|
||||||
|
|
||||||
transformer = await FillQuoteTransformerContract.deployFrom0xArtifactAsync(
|
transformer = await FillQuoteTransformerContract.deployFrom0xArtifactAsync(
|
||||||
artifacts.FillQuoteTransformer,
|
artifacts.FillQuoteTransformer,
|
||||||
env.provider,
|
env.provider,
|
||||||
@@ -78,6 +90,7 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
|||||||
artifacts,
|
artifacts,
|
||||||
bridgeAdapter.address,
|
bridgeAdapter.address,
|
||||||
exchange.address,
|
exchange.address,
|
||||||
|
otcOrder.address
|
||||||
);
|
);
|
||||||
host = await TestFillQuoteTransformerHostContract.deployFrom0xArtifactAsync(
|
host = await TestFillQuoteTransformerHostContract.deployFrom0xArtifactAsync(
|
||||||
artifacts.TestFillQuoteTransformerHost,
|
artifacts.TestFillQuoteTransformerHost,
|
||||||
@@ -141,6 +154,18 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createOTCBridgeOrder(fields: Partial<OtcOrderFields> = {}): OtcOrder {
|
||||||
|
return getRandomOtcOrder({
|
||||||
|
makerToken: makerToken.address,
|
||||||
|
takerToken: takerToken.address,
|
||||||
|
makerAmount: getRandomInteger('0.1e18', '1e18'),
|
||||||
|
takerAmount: getRandomInteger('0.1e18', '1e18'),
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
...fields,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function createOrderSignature(preFilledTakerAmount: Numberish = 0): Signature {
|
function createOrderSignature(preFilledTakerAmount: Numberish = 0): Signature {
|
||||||
return {
|
return {
|
||||||
// The r field of the signature is the pre-filled amount.
|
// The r field of the signature is the pre-filled amount.
|
||||||
@@ -271,6 +296,24 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fillOtcOrder(oi: FillQuoteTransformerRfqOrderInfo): FillOrderResults {
|
||||||
|
const preFilledTakerAmount = orderSignatureToPreFilledTakerAmount(oi.signature);
|
||||||
|
if (preFilledTakerAmount.gte(oi.order.takerAmount) || preFilledTakerAmount.eq(REVERT_AMOUNT)) {
|
||||||
|
return EMPTY_FILL_ORDER_RESULTS;
|
||||||
|
}
|
||||||
|
const takerTokenFillAmount = BigNumber.min(
|
||||||
|
computeTakerTokenFillAmount(oi.order.takerAmount, oi.order.makerAmount),
|
||||||
|
oi.order.takerAmount.minus(preFilledTakerAmount),
|
||||||
|
oi.maxTakerTokenFillAmount,
|
||||||
|
);
|
||||||
|
const fillRatio = takerTokenFillAmount.div(oi.order.takerAmount);
|
||||||
|
return {
|
||||||
|
...EMPTY_FILL_ORDER_RESULTS,
|
||||||
|
takerTokenSoldAmount: takerTokenFillAmount,
|
||||||
|
makerTokenBoughtAmount: fillRatio.times(oi.order.makerAmount).integerValue(BigNumber.ROUND_DOWN),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// tslint:disable-next-line: prefer-for-of
|
// tslint:disable-next-line: prefer-for-of
|
||||||
for (let i = 0; i < data.fillSequence.length; ++i) {
|
for (let i = 0; i < data.fillSequence.length; ++i) {
|
||||||
const orderType = data.fillSequence[i];
|
const orderType = data.fillSequence[i];
|
||||||
|
|||||||
@@ -60,9 +60,10 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/assert": "^3.0.34",
|
"@0x/assert": "^3.0.34",
|
||||||
"@0x/base-contract": "^6.5.0",
|
"@0x/base-contract": "^6.5.0",
|
||||||
"@0x/contract-addresses": "^6.14.0",
|
"@0x/contract-addresses": "^6.16.0",
|
||||||
"@0x/contract-wrappers": "^13.20.2",
|
"@0x/contract-wrappers": "^13.20.4",
|
||||||
"@0x/contracts-erc20": "^3.3.30",
|
"@0x/contracts-erc20": "^3.3.32",
|
||||||
|
"@0x/contracts-test-utils": "^5.4.23",
|
||||||
"@0x/contracts-zero-ex": "^0.33.0",
|
"@0x/contracts-zero-ex": "^0.33.0",
|
||||||
"@0x/dev-utils": "^4.2.14",
|
"@0x/dev-utils": "^4.2.14",
|
||||||
"@0x/json-schemas": "^6.4.4",
|
"@0x/json-schemas": "^6.4.4",
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import {
|
|||||||
FinalUniswapV3FillData,
|
FinalUniswapV3FillData,
|
||||||
LiquidityProviderFillData,
|
LiquidityProviderFillData,
|
||||||
MooniswapFillData,
|
MooniswapFillData,
|
||||||
|
NativeOtcOrderFillData,
|
||||||
NativeRfqOrderFillData,
|
NativeRfqOrderFillData,
|
||||||
OptimizedMarketBridgeOrder,
|
OptimizedMarketBridgeOrder,
|
||||||
OptimizedMarketOrder,
|
OptimizedMarketOrder,
|
||||||
@@ -377,7 +378,66 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
gasOverhead: ZERO_AMOUNT,
|
gasOverhead: ZERO_AMOUNT,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
// select for all chains OtcOrders exists on
|
||||||
|
[ChainId.Mainnet].includes(this.chainId) &&
|
||||||
|
quote.orders.length == 1 &&
|
||||||
|
quote.orders.every(o => o.type === FillQuoteTransformerOrderType.Otc) &&
|
||||||
|
!requiresTransformERC20(optsWithDefaults)
|
||||||
|
) {
|
||||||
|
|
||||||
|
const otcOrdersData = quote.orders.map(o => o.fillData as NativeOtcOrderFillData);
|
||||||
|
const fillAmountPerOrder = (() => {
|
||||||
|
// Don't think order taker amounts are clipped to actual sell amount
|
||||||
|
// (the last one might be too large) so figure them out manually.
|
||||||
|
let remaining = sellAmount;
|
||||||
|
const fillAmounts = [];
|
||||||
|
for (const o of quote.orders) {
|
||||||
|
const fillAmount = BigNumber.min(o.takerAmount, remaining);
|
||||||
|
fillAmounts.push(fillAmount);
|
||||||
|
remaining = remaining.minus(fillAmount);
|
||||||
|
}
|
||||||
|
return fillAmounts;
|
||||||
|
})();
|
||||||
|
|
||||||
|
// grab the amount to fill on each OtcOrder (if more than 1)
|
||||||
|
let calldata;
|
||||||
|
|
||||||
|
if(isFromETH){
|
||||||
|
calldata = this._exchangeProxy.fillOtcOrderWithEth(
|
||||||
|
otcOrdersData[0].order, otcOrdersData[0].signature
|
||||||
|
).getABIEncodedTransactionData();
|
||||||
|
}
|
||||||
|
if(isToETH){
|
||||||
|
calldata = this._exchangeProxy.fillOtcOrderForEth(
|
||||||
|
otcOrdersData[0].order, otcOrdersData[0].signature, fillAmountPerOrder[0]
|
||||||
|
).getABIEncodedTransactionData();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
calldata = this._exchangeProxy.fillOtcOrder(
|
||||||
|
otcOrdersData[0].order, otcOrdersData[0].signature, fillAmountPerOrder[0]
|
||||||
|
).getABIEncodedTransactionData();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.chainId === ChainId.Mainnet &&
|
||||||
|
isMultiplexBatchFillCompatible(quote, optsWithDefaults)) {
|
||||||
|
// return {
|
||||||
|
// calldataHexString: this._encodeMultiplexBatchFillCalldata(
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
}
|
||||||
|
|
||||||
|
// if isToETH
|
||||||
|
// encode for fillOtcOrderForEth
|
||||||
|
// if isFromETH
|
||||||
|
// encode for fillOtcOrderWithEth
|
||||||
|
// else
|
||||||
|
// fillOtcOrder
|
||||||
|
// contracts/zero-ex/contracts/src/features/OtcOrdersFeature.sol
|
||||||
|
|
||||||
|
// if more than 1 OTCOrder, bail and use the BatchMultiPlex encode below
|
||||||
|
}
|
||||||
if (this.chainId === ChainId.Mainnet && isMultiplexBatchFillCompatible(quote, optsWithDefaults)) {
|
if (this.chainId === ChainId.Mainnet && isMultiplexBatchFillCompatible(quote, optsWithDefaults)) {
|
||||||
return {
|
return {
|
||||||
calldataHexString: this._encodeMultiplexBatchFillCalldata(
|
calldataHexString: this._encodeMultiplexBatchFillCalldata(
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
LimitOrderFields,
|
LimitOrderFields,
|
||||||
RfqOrder,
|
RfqOrder,
|
||||||
RfqOrderFields,
|
RfqOrderFields,
|
||||||
|
OtcOrderFields,
|
||||||
Signature,
|
Signature,
|
||||||
} from '@0x/protocol-utils';
|
} from '@0x/protocol-utils';
|
||||||
import { TakerRequestQueryParamsUnnested, V4SignedRfqOrder } from '@0x/quote-server';
|
import { TakerRequestQueryParamsUnnested, V4SignedRfqOrder } from '@0x/quote-server';
|
||||||
@@ -34,11 +35,11 @@ export interface OrderPrunerOpts {
|
|||||||
|
|
||||||
export interface SignedOrder<T> {
|
export interface SignedOrder<T> {
|
||||||
order: T;
|
order: T;
|
||||||
type: FillQuoteTransformerOrderType.Limit | FillQuoteTransformerOrderType.Rfq;
|
type: FillQuoteTransformerOrderType.Limit | FillQuoteTransformerOrderType.Rfq | FillQuoteTransformerOrderType.Otc;
|
||||||
signature: Signature;
|
signature: Signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SignedNativeOrder = SignedOrder<LimitOrderFields> | SignedOrder<RfqOrderFields>;
|
export type SignedNativeOrder = SignedOrder<LimitOrderFields> | SignedOrder<RfqOrderFields> | SignedOrder<OtcOrderFields>;
|
||||||
export type NativeOrderWithFillableAmounts = SignedNativeOrder & NativeOrderFillableAmountFields;
|
export type NativeOrderWithFillableAmounts = SignedNativeOrder & NativeOrderFillableAmountFields;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { RfqOrder, Signature } from '@0x/protocol-utils';
|
import { OtcOrder, RfqOrder, Signature } from '@0x/protocol-utils';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
|
|
||||||
import { AltRfqMakerAssetOfferings } from '../types';
|
import { AltRfqMakerAssetOfferings } from '../types';
|
||||||
@@ -43,6 +43,48 @@ export interface RfqClientV1QuoteResponse {
|
|||||||
quotes: RfqClientV1Quote[];
|
quotes: RfqClientV1Quote[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RfqClientV2PriceRequest {
|
||||||
|
assetFillAmount: BigNumber;
|
||||||
|
chainId: number;
|
||||||
|
comparisonPrice: BigNumber | undefined;
|
||||||
|
integratorId: string;
|
||||||
|
intentOnFilling: boolean;
|
||||||
|
makerToken: string;
|
||||||
|
marketOperation: 'Sell' | 'Buy';
|
||||||
|
takerAddress: string;
|
||||||
|
takerToken: string;
|
||||||
|
txOrigin: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RfqClientV2QuoteRequest extends RfqClientV2PriceRequest {}
|
||||||
|
|
||||||
|
export interface RfqClientV2Price {
|
||||||
|
expiry: BigNumber;
|
||||||
|
maker: string;
|
||||||
|
makerAmount: BigNumber;
|
||||||
|
makerToken: string;
|
||||||
|
makerUri: string;
|
||||||
|
takerAmount: BigNumber;
|
||||||
|
takerToken: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RfqClientV2PriceResponse {
|
||||||
|
prices: RfqClientV2Price[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RfqClientV2Quote {
|
||||||
|
makerUri: string;
|
||||||
|
order: OtcOrder;
|
||||||
|
signature: Signature;
|
||||||
|
fillableMakerAmount: BigNumber;
|
||||||
|
fillableTakerAmount: BigNumber;
|
||||||
|
fillableTakerFeeAmount: BigNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RfqClientV2QuoteResponse {
|
||||||
|
quotes: RfqClientV2Quote[];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IRfqClient is an interface that defines how to connect with an Rfq system.
|
* IRfqClient is an interface that defines how to connect with an Rfq system.
|
||||||
*/
|
*/
|
||||||
@@ -56,4 +98,14 @@ export interface IRfqClient {
|
|||||||
* Fetches a list of "firm quotes" or signed quotes from a remote Rfq server.
|
* Fetches a list of "firm quotes" or signed quotes from a remote Rfq server.
|
||||||
*/
|
*/
|
||||||
getV1QuotesAsync(request: RfqClientV1QuoteRequest): Promise<RfqClientV1QuoteResponse>;
|
getV1QuotesAsync(request: RfqClientV1QuoteRequest): Promise<RfqClientV1QuoteResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a list of "v2 indicative quotes" or prices from a remote Rfq server
|
||||||
|
*/
|
||||||
|
getV2PricesAsync(request: RfqClientV2PriceRequest): Promise<RfqClientV2PriceResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a list of "v2 firm quotes" or signed quotes from a remote Rfq server.
|
||||||
|
*/
|
||||||
|
getV2QuotesAsync(request: RfqClientV2QuoteRequest): Promise<RfqClientV2QuoteResponse>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -641,6 +641,7 @@ export const OPTIMISM_TOKENS = {
|
|||||||
WBTC: '0x68f180fcce6836688e9084f035309e29bf0a2095',
|
WBTC: '0x68f180fcce6836688e9084f035309e29bf0a2095',
|
||||||
nETH: '0x809dc529f07651bd43a172e8db6f4a7a0d771036',
|
nETH: '0x809dc529f07651bd43a172e8db6f4a7a0d771036',
|
||||||
sWETH: '0x121ab82b49b2bc4c7901ca46b8277962b4350204',
|
sWETH: '0x121ab82b49b2bc4c7901ca46b8277962b4350204',
|
||||||
|
nUSD: '0x67C10C397dD0Ba417329543c1a40eb48AAa7cd00',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_POOLS = {
|
export const CURVE_POOLS = {
|
||||||
@@ -770,6 +771,7 @@ export const SYNAPSE_MAINNET_POOLS = {
|
|||||||
|
|
||||||
export const SYNAPSE_OPTIMISM_POOLS = {
|
export const SYNAPSE_OPTIMISM_POOLS = {
|
||||||
nETHLP: '0xe27bff97ce92c3e1ff7aa9f86781fdd6d48f5ee9',
|
nETHLP: '0xe27bff97ce92c3e1ff7aa9f86781fdd6d48f5ee9',
|
||||||
|
nUSDLP: '0xF44938b0125A6662f9536281aD2CD6c499F22004',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SYNAPSE_BSC_POOLS = {
|
export const SYNAPSE_BSC_POOLS = {
|
||||||
@@ -783,6 +785,7 @@ export const SYNAPSE_POLYGON_POOLS = {
|
|||||||
export const SYNAPSE_FANTOM_POOLS = {
|
export const SYNAPSE_FANTOM_POOLS = {
|
||||||
nUSDLP: '0x2913e812cf0dcca30fb28e6cac3d2dcff4497688',
|
nUSDLP: '0x2913e812cf0dcca30fb28e6cac3d2dcff4497688',
|
||||||
nETHLP: '0x8d9ba570d6cb60c7e3e0f31343efe75ab8e65fb1',
|
nETHLP: '0x8d9ba570d6cb60c7e3e0f31343efe75ab8e65fb1',
|
||||||
|
fUSDTLP: '0x85662fd123280827e11c59973ac9fcbe838dc3b4',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SYNAPSE_AVALANCHE_POOLS = {
|
export const SYNAPSE_AVALANCHE_POOLS = {
|
||||||
@@ -1654,6 +1657,24 @@ export const SYNAPSE_FANTOM_INFOS: { [name: string]: CurveInfo } = {
|
|||||||
metaTokens: undefined,
|
metaTokens: undefined,
|
||||||
gasSchedule: 140e3,
|
gasSchedule: 140e3,
|
||||||
},
|
},
|
||||||
|
[SYNAPSE_FANTOM_POOLS.fUSDTLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_FANTOM_POOLS.fUSDTLP,
|
||||||
|
tokens: [FANTOM_TOKENS.USDC, FANTOM_TOKENS.fUSDT, FANTOM_TOKENS.nUSD],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
|
[SYNAPSE_FANTOM_POOLS.nETHLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_FANTOM_POOLS.nETHLP,
|
||||||
|
tokens: [FANTOM_TOKENS.WETH, FANTOM_TOKENS.nETH],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SYNAPSE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
export const SYNAPSE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
||||||
@@ -1678,6 +1699,15 @@ export const SYNAPSE_OPTIMISM_INFOS: { [name: string]: CurveInfo } = {
|
|||||||
metaTokens: undefined,
|
metaTokens: undefined,
|
||||||
gasSchedule: 140e3,
|
gasSchedule: 140e3,
|
||||||
},
|
},
|
||||||
|
[SYNAPSE_OPTIMISM_POOLS.nUSDLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_OPTIMISM_POOLS.nUSDLP,
|
||||||
|
tokens: [OPTIMISM_TOKENS.nUSD, OPTIMISM_TOKENS.USDC],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SYNAPSE_POLYGON_INFOS: { [name: string]: CurveInfo } = {
|
export const SYNAPSE_POLYGON_INFOS: { [name: string]: CurveInfo } = {
|
||||||
|
|||||||
@@ -747,6 +747,26 @@ export class MarketOperationUtils {
|
|||||||
wholeOrderPrice,
|
wholeOrderPrice,
|
||||||
rfqt,
|
rfqt,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const otcQuotes = await rfqt.rfqClient?.getV2QuotesAsync({
|
||||||
|
assetFillAmount: amount,
|
||||||
|
chainId: this._sampler.chainId,
|
||||||
|
integratorId: rfqt.integrator.integratorId,
|
||||||
|
intentOnFilling: rfqt.intentOnFilling,
|
||||||
|
makerToken,
|
||||||
|
marketOperation: side,
|
||||||
|
takerAddress: rfqt.takerAddress,
|
||||||
|
takerToken,
|
||||||
|
txOrigin: rfqt.txOrigin,
|
||||||
|
});
|
||||||
|
const otcQuotesWithFillableAmounts: NativeOrderWithFillableAmounts[] =
|
||||||
|
otcQuotes === undefined
|
||||||
|
? []
|
||||||
|
: otcQuotes.quotes.map(q => ({
|
||||||
|
...q,
|
||||||
|
type: FillQuoteTransformerOrderType.Otc,
|
||||||
|
}));
|
||||||
|
|
||||||
const deltaTime = new Date().getTime() - timeStart;
|
const deltaTime = new Date().getTime() - timeStart;
|
||||||
DEFAULT_INFO_LOGGER({
|
DEFAULT_INFO_LOGGER({
|
||||||
rfqQuoteType: 'firm',
|
rfqQuoteType: 'firm',
|
||||||
@@ -777,6 +797,7 @@ export class MarketOperationUtils {
|
|||||||
);
|
);
|
||||||
marketSideLiquidity.quotes.nativeOrders = [
|
marketSideLiquidity.quotes.nativeOrders = [
|
||||||
...quotesWithOrderFillableAmounts,
|
...quotesWithOrderFillableAmounts,
|
||||||
|
...otcQuotesWithFillableAmounts,
|
||||||
...marketSideLiquidity.quotes.nativeOrders,
|
...marketSideLiquidity.quotes.nativeOrders,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
FillQuoteTransformerLimitOrderInfo,
|
FillQuoteTransformerLimitOrderInfo,
|
||||||
FillQuoteTransformerOrderType,
|
FillQuoteTransformerOrderType,
|
||||||
FillQuoteTransformerRfqOrderInfo,
|
FillQuoteTransformerRfqOrderInfo,
|
||||||
|
FillQuoteTransformerOtcOrderInfo
|
||||||
} from '@0x/protocol-utils';
|
} from '@0x/protocol-utils';
|
||||||
import { MarketOperation } from '@0x/types';
|
import { MarketOperation } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
@@ -195,7 +196,9 @@ export interface FillData {}
|
|||||||
// `FillData` for native fills. Represents a single native order
|
// `FillData` for native fills. Represents a single native order
|
||||||
export type NativeRfqOrderFillData = FillQuoteTransformerRfqOrderInfo;
|
export type NativeRfqOrderFillData = FillQuoteTransformerRfqOrderInfo;
|
||||||
export type NativeLimitOrderFillData = FillQuoteTransformerLimitOrderInfo;
|
export type NativeLimitOrderFillData = FillQuoteTransformerLimitOrderInfo;
|
||||||
export type NativeFillData = NativeRfqOrderFillData | NativeLimitOrderFillData;
|
export type NativeOtcOrderFillData = FillQuoteTransformerOtcOrderInfo;
|
||||||
|
export type NativeFillData = NativeRfqOrderFillData | NativeLimitOrderFillData | NativeOtcOrderFillData;
|
||||||
|
|
||||||
|
|
||||||
// Represents an individual DEX sample from the sampler contract
|
// Represents an individual DEX sample from the sampler contract
|
||||||
export interface DexSample<TFillData extends FillData = FillData> {
|
export interface DexSample<TFillData extends FillData = FillData> {
|
||||||
@@ -454,13 +457,19 @@ export interface OptimizedRfqOrder extends OptimizedMarketOrderBase<NativeRfqOrd
|
|||||||
fillData: NativeRfqOrderFillData;
|
fillData: NativeRfqOrderFillData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OptimizedOtcOrder extends OptimizedMarketOrderBase<NativeOtcOrderFillData> {
|
||||||
|
type: FillQuoteTransformerOrderType.Otc;
|
||||||
|
fillData: NativeOtcOrderFillData;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimized orders to fill.
|
* Optimized orders to fill.
|
||||||
*/
|
*/
|
||||||
export type OptimizedMarketOrder =
|
export type OptimizedMarketOrder =
|
||||||
| OptimizedMarketBridgeOrder<FillData>
|
| OptimizedMarketBridgeOrder<FillData>
|
||||||
| OptimizedMarketOrderBase<NativeLimitOrderFillData>
|
| OptimizedMarketOrderBase<NativeLimitOrderFillData>
|
||||||
| OptimizedMarketOrderBase<NativeRfqOrderFillData>;
|
| OptimizedMarketOrderBase<NativeRfqOrderFillData>
|
||||||
|
| OptimizedMarketOrderBase<NativeOtcOrderFillData>;
|
||||||
|
|
||||||
export interface GetMarketOrdersRfqOpts extends RfqRequestOpts {
|
export interface GetMarketOrdersRfqOpts extends RfqRequestOpts {
|
||||||
rfqClient?: IRfqClient;
|
rfqClient?: IRfqClient;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
NativeCollapsedFill,
|
NativeCollapsedFill,
|
||||||
NativeFillData,
|
NativeFillData,
|
||||||
NativeLimitOrderFillData,
|
NativeLimitOrderFillData,
|
||||||
|
NativeOtcOrderFillData,
|
||||||
NativeRfqOrderFillData,
|
NativeRfqOrderFillData,
|
||||||
RawQuotes,
|
RawQuotes,
|
||||||
} from './market_operation_utils/types';
|
} from './market_operation_utils/types';
|
||||||
@@ -353,7 +354,7 @@ function _isNativeOrderFromCollapsedFill(cf: CollapsedFill): cf is NativeCollaps
|
|||||||
*/
|
*/
|
||||||
export function nativeOrderToReportEntry(
|
export function nativeOrderToReportEntry(
|
||||||
type: FillQuoteTransformerOrderType,
|
type: FillQuoteTransformerOrderType,
|
||||||
fillData: NativeLimitOrderFillData | NativeRfqOrderFillData,
|
fillData: NativeLimitOrderFillData | NativeRfqOrderFillData | NativeOtcOrderFillData,
|
||||||
fillableAmount: BigNumber,
|
fillableAmount: BigNumber,
|
||||||
comparisonPrice?: BigNumber | undefined,
|
comparisonPrice?: BigNumber | undefined,
|
||||||
quoteRequestor?: QuoteRequestor,
|
quoteRequestor?: QuoteRequestor,
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/assert": "^3.0.34",
|
"@0x/assert": "^3.0.34",
|
||||||
"@0x/contract-addresses": "^6.14.0",
|
"@0x/contract-addresses": "^6.16.0",
|
||||||
"@0x/contract-wrappers": "^13.20.2",
|
"@0x/contract-wrappers": "^13.20.2",
|
||||||
"@0x/json-schemas": "^6.4.4",
|
"@0x/json-schemas": "^6.4.4",
|
||||||
"@0x/subproviders": "^6.6.5",
|
"@0x/subproviders": "^6.6.5",
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export type LimitOrderFields = typeof LIMIT_ORDER_DEFAULT_VALUES;
|
|||||||
export type RfqOrderFields = typeof RFQ_ORDER_DEFAULT_VALUES;
|
export type RfqOrderFields = typeof RFQ_ORDER_DEFAULT_VALUES;
|
||||||
export type OtcOrderFields = typeof OTC_ORDER_DEFAULT_VALUES;
|
export type OtcOrderFields = typeof OTC_ORDER_DEFAULT_VALUES;
|
||||||
export type BridgeOrderFields = typeof BRIDGE_ORDER_DEFAULT_VALUES;
|
export type BridgeOrderFields = typeof BRIDGE_ORDER_DEFAULT_VALUES;
|
||||||
export type NativeOrder = RfqOrder | LimitOrder;
|
export type NativeOrder = RfqOrder | LimitOrder | OtcOrder;
|
||||||
|
|
||||||
export enum OrderStatus {
|
export enum OrderStatus {
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { AbiEncoder, BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils';
|
import { AbiEncoder, BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils';
|
||||||
import * as ethjs from 'ethereumjs-util';
|
import * as ethjs from 'ethereumjs-util';
|
||||||
|
|
||||||
import { LimitOrder, LimitOrderFields, RfqOrder, RfqOrderFields } from './orders';
|
import { LimitOrder, LimitOrderFields, RfqOrder, RfqOrderFields, OtcOrder, OtcOrderFields } from './orders';
|
||||||
import { Signature, SIGNATURE_ABI } from './signature_utils';
|
import { Signature, SIGNATURE_ABI } from './signature_utils';
|
||||||
|
|
||||||
const BRIDGE_ORDER_ABI_COMPONENTS = [
|
const BRIDGE_ORDER_ABI_COMPONENTS = [
|
||||||
@@ -39,6 +39,20 @@ const RFQ_ORDER_INFO_ABI_COMPONENTS = [
|
|||||||
{ name: 'maxTakerTokenFillAmount', type: 'uint256' },
|
{ name: 'maxTakerTokenFillAmount', type: 'uint256' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const OTC_ORDER_INFO_ABI_COMPONENTS = [
|
||||||
|
{
|
||||||
|
name: 'order',
|
||||||
|
type: 'tuple',
|
||||||
|
components: OtcOrder.STRUCT_ABI,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'signature',
|
||||||
|
type: 'tuple',
|
||||||
|
components: SIGNATURE_ABI,
|
||||||
|
},
|
||||||
|
{ name: 'maxTakerTokenFillAmount', type: 'uint256' },
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ABI encoder for `FillQuoteTransformer.TransformData`
|
* ABI encoder for `FillQuoteTransformer.TransformData`
|
||||||
*/
|
*/
|
||||||
@@ -65,6 +79,11 @@ export const fillQuoteTransformerDataEncoder = AbiEncoder.create([
|
|||||||
type: 'tuple[]',
|
type: 'tuple[]',
|
||||||
components: RFQ_ORDER_INFO_ABI_COMPONENTS,
|
components: RFQ_ORDER_INFO_ABI_COMPONENTS,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'otcOrders',
|
||||||
|
type: 'tuple[]',
|
||||||
|
components: OTC_ORDER_INFO_ABI_COMPONENTS,
|
||||||
|
},
|
||||||
{ name: 'fillSequence', type: 'uint8[]' },
|
{ name: 'fillSequence', type: 'uint8[]' },
|
||||||
{ name: 'fillAmount', type: 'uint256' },
|
{ name: 'fillAmount', type: 'uint256' },
|
||||||
{ name: 'refundReceiver', type: 'address' },
|
{ name: 'refundReceiver', type: 'address' },
|
||||||
@@ -87,6 +106,7 @@ export enum FillQuoteTransformerOrderType {
|
|||||||
Bridge,
|
Bridge,
|
||||||
Limit,
|
Limit,
|
||||||
Rfq,
|
Rfq,
|
||||||
|
Otc,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -170,6 +190,11 @@ export type FillQuoteTransformerLimitOrderInfo = FillQuoteTransformerNativeOrder
|
|||||||
*/
|
*/
|
||||||
export type FillQuoteTransformerRfqOrderInfo = FillQuoteTransformerNativeOrderInfo<RfqOrderFields>;
|
export type FillQuoteTransformerRfqOrderInfo = FillQuoteTransformerNativeOrderInfo<RfqOrderFields>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `FillQuoteTransformer.OtcOrderInfo`
|
||||||
|
*/
|
||||||
|
export type FillQuoteTransformerOtcOrderInfo = FillQuoteTransformerNativeOrderInfo<OtcOrderFields>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ABI-encode a `FillQuoteTransformer.TransformData` type.
|
* ABI-encode a `FillQuoteTransformer.TransformData` type.
|
||||||
*/
|
*/
|
||||||
@@ -177,6 +202,8 @@ export function encodeFillQuoteTransformerData(data: FillQuoteTransformerData):
|
|||||||
return fillQuoteTransformerDataEncoder.encode([data]);
|
return fillQuoteTransformerDataEncoder.encode([data]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ABI-decode a `FillQuoteTransformer.TransformData` type.
|
* ABI-decode a `FillQuoteTransformer.TransformData` type.
|
||||||
*/
|
*/
|
||||||
@@ -184,6 +211,7 @@ export function decodeFillQuoteTransformerData(encoded: string): FillQuoteTransf
|
|||||||
return fillQuoteTransformerDataEncoder.decode(encoded).data;
|
return fillQuoteTransformerDataEncoder.decode(encoded).data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ABI encoder for `WethTransformer.TransformData`
|
* ABI encoder for `WethTransformer.TransformData`
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { BigNumber } from '@0x/utils';
|
|||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import * as ethjs from 'ethereumjs-util';
|
import * as ethjs from 'ethereumjs-util';
|
||||||
|
|
||||||
import { LimitOrder, RfqOrder } from '../src/orders';
|
import { LimitOrder, OtcOrder, RfqOrder } from '../src/orders';
|
||||||
import { SignatureType } from '../src/signature_utils';
|
import { SignatureType } from '../src/signature_utils';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
@@ -145,4 +145,64 @@ describe('orders', () => {
|
|||||||
expect(actual).to.deep.eq(expected);
|
expect(actual).to.deep.eq(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('OtcOrder', () => {
|
||||||
|
const order = new OtcOrder({
|
||||||
|
makerToken: '0x349e8d89e8b37214d9ce3949fc5754152c525bc3',
|
||||||
|
takerToken: '0x83c62b2e67dea0df2a27be0def7a22bd7102642c',
|
||||||
|
makerAmount: new BigNumber(1234),
|
||||||
|
takerAmount: new BigNumber(5678),
|
||||||
|
maker: '0x8d5e5b5b5d187bdce2e0143eb6b3cc44eef3c0cb',
|
||||||
|
taker: '0x615312fb74c31303eab07dea520019bb23f4c6c2',
|
||||||
|
txOrigin: '0x70f2d6c7acd257a6700d745b76c602ceefeb8e20',
|
||||||
|
expiryAndNonce: new BigNumber(1001),
|
||||||
|
chainId: 8008,
|
||||||
|
verifyingContract: '0x6701704d2421c64ee9aa93ec7f96ede81c4be77d',
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get the struct hash', () => {
|
||||||
|
const actual = order.getStructHash();
|
||||||
|
// const expected = '0x995b6261fa93cd5acd5121f404305f8e9f9c388723f3e53fb05bd5eb534b4899';
|
||||||
|
// expect(actual).to.eq(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get the EIP712 hash', () => {
|
||||||
|
const actual = order.getHash();
|
||||||
|
// const expected = '0xb4c40524740dcc4030a62b6d9afe740f6ca24508e59ef0c5bd99d5649a430885';
|
||||||
|
// expect(actual).to.deep.eq(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get an EthSign signature with a provider', async () => {
|
||||||
|
const actual = await order.clone({ maker: providerMaker }).getSignatureWithProviderAsync(provider);
|
||||||
|
// const expected = {
|
||||||
|
// signatureType: SignatureType.EthSign,
|
||||||
|
// r: '0xed555259efe38e2d679f7bc18385e51ce158576ced6c11630f67ba37b3e59a29',
|
||||||
|
// s: '0x769211cf3e86b254e3755e1dcf459f5b362ca1c42ec3cf08841d90cb44f2a8e4',
|
||||||
|
// v: 27,
|
||||||
|
// };
|
||||||
|
// expect(actual).to.deep.eq(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get an EthSign signature with a private key', () => {
|
||||||
|
const actual = order.clone({ maker: keyMaker }).getSignatureWithKey(key);
|
||||||
|
// const expected = {
|
||||||
|
// signatureType: SignatureType.EthSign,
|
||||||
|
// r: '0xba231f67168d6d1fd2b83e0a3a6b1663ec493b98a8dbe34689c8e8171972522f',
|
||||||
|
// s: '0x47023a5f73b5f638e9a138de26b35e59847680bee78af0c8251de532e7c39d8b',
|
||||||
|
// v: 28,
|
||||||
|
// };
|
||||||
|
// expect(actual).to.deep.eq(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get an EIP712 signature with a private key', () => {
|
||||||
|
const actual = order.clone({ maker: keyMaker }).getSignatureWithKey(key, SignatureType.EIP712);
|
||||||
|
// const expected = {
|
||||||
|
// signatureType: SignatureType.EIP712,
|
||||||
|
// r: '0x824d70ae7cccea382ddd51f773f9745abb928dadbccebbd090ca371d7b8fb741',
|
||||||
|
// s: '0x7557a009f7cfa207d19a8fd42950458340de718a7b35522051cde6f75ad42cba',
|
||||||
|
// v: 27,
|
||||||
|
// };
|
||||||
|
// expect(actual).to.deep.eq(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
78
yarn.lock
78
yarn.lock
@@ -732,6 +732,26 @@
|
|||||||
js-sha3 "^0.7.0"
|
js-sha3 "^0.7.0"
|
||||||
uuid "^3.3.2"
|
uuid "^3.3.2"
|
||||||
|
|
||||||
|
"@0x/contract-addresses@^6.16.0":
|
||||||
|
version "6.16.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@0x/contract-addresses/-/contract-addresses-6.16.0.tgz#dc8dc4c5319f7eee40e10ccb462a254b6eb03b14"
|
||||||
|
integrity sha512-Gsc/9EttCUtemiJR5/U1JPezxVUtlQ3pq6rPkc7YJL0isK0AwYIrQm82b6Z8wyg9bPMs9dkONc806nnUehY5pQ==
|
||||||
|
|
||||||
|
"@0x/contract-wrappers@^13.20.4":
|
||||||
|
version "13.20.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@0x/contract-wrappers/-/contract-wrappers-13.20.4.tgz#e77e6bc4be2c0288fe6846cf7408a1694567e7e2"
|
||||||
|
integrity sha512-kbaYHjjgx1MN2+JRipmo6crl8p4lZpFyVFFp2ULtcEFBEzi0UIEMxo7SXCEguMe/yOY7NGGuLUMJ3Zd3IEjCxA==
|
||||||
|
dependencies:
|
||||||
|
"@0x/assert" "^3.0.34"
|
||||||
|
"@0x/base-contract" "^6.5.0"
|
||||||
|
"@0x/contract-addresses" "^6.16.0"
|
||||||
|
"@0x/json-schemas" "^6.4.4"
|
||||||
|
"@0x/types" "^3.3.6"
|
||||||
|
"@0x/utils" "^6.5.3"
|
||||||
|
"@0x/web3-wrapper" "^7.6.5"
|
||||||
|
ethereum-types "^3.7.0"
|
||||||
|
ethers "~4.0.4"
|
||||||
|
|
||||||
"@0x/contracts-asset-proxy@^3.7.19":
|
"@0x/contracts-asset-proxy@^3.7.19":
|
||||||
version "3.7.19"
|
version "3.7.19"
|
||||||
resolved "https://registry.yarnpkg.com/@0x/contracts-asset-proxy/-/contracts-asset-proxy-3.7.19.tgz#ee621a233f4d77b439c74c5b8d70db2e1ed001c4"
|
resolved "https://registry.yarnpkg.com/@0x/contracts-asset-proxy/-/contracts-asset-proxy-3.7.19.tgz#ee621a233f4d77b439c74c5b8d70db2e1ed001c4"
|
||||||
@@ -783,6 +803,14 @@
|
|||||||
"@0x/web3-wrapper" "^7.5.3"
|
"@0x/web3-wrapper" "^7.5.3"
|
||||||
lodash "^4.17.11"
|
lodash "^4.17.11"
|
||||||
|
|
||||||
|
"@0x/contracts-erc20@^3.3.32":
|
||||||
|
version "3.3.32"
|
||||||
|
resolved "https://registry.yarnpkg.com/@0x/contracts-erc20/-/contracts-erc20-3.3.32.tgz#e389594fe66722f4ad05ef9f5ebc581f35ea3fb2"
|
||||||
|
integrity sha512-SK2vAyXxDU4HsEB0rjC2/NQJadournmw7VksofY1GxbGYdHPcp2VHdGAbbncCGRW56DByS89RVphH9JIsy5Fhg==
|
||||||
|
dependencies:
|
||||||
|
"@0x/base-contract" "^6.5.0"
|
||||||
|
ethers "~4.0.4"
|
||||||
|
|
||||||
"@0x/contracts-erc721@^3.1.37":
|
"@0x/contracts-erc721@^3.1.37":
|
||||||
version "3.1.37"
|
version "3.1.37"
|
||||||
resolved "https://registry.yarnpkg.com/@0x/contracts-erc721/-/contracts-erc721-3.1.37.tgz#d7d356737e3d2752cf49be385237fbf7d0c5745c"
|
resolved "https://registry.yarnpkg.com/@0x/contracts-erc721/-/contracts-erc721-3.1.37.tgz#d7d356737e3d2752cf49be385237fbf7d0c5745c"
|
||||||
@@ -867,6 +895,55 @@
|
|||||||
ethereum-types "^3.5.0"
|
ethereum-types "^3.5.0"
|
||||||
ethereumjs-util "^7.0.10"
|
ethereumjs-util "^7.0.10"
|
||||||
|
|
||||||
|
"@0x/contracts-test-utils@^5.4.23":
|
||||||
|
version "5.4.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/@0x/contracts-test-utils/-/contracts-test-utils-5.4.23.tgz#515e120646cbba6644fa7c67b3259736b6c88601"
|
||||||
|
integrity sha512-cmLalK8MV3OEzbLq9Jyfc0a13//rR6bVQXtbYCNwb/ygqsP6HOCPQ24T6PLS6JyGb/nPCl2TRrrZ9TDgNb2uOA==
|
||||||
|
dependencies:
|
||||||
|
"@0x/assert" "^3.0.34"
|
||||||
|
"@0x/base-contract" "^6.5.0"
|
||||||
|
"@0x/contract-addresses" "^6.16.0"
|
||||||
|
"@0x/dev-utils" "^4.2.14"
|
||||||
|
"@0x/json-schemas" "^6.4.4"
|
||||||
|
"@0x/order-utils" "^10.4.28"
|
||||||
|
"@0x/sol-coverage" "^4.0.45"
|
||||||
|
"@0x/sol-profiler" "^4.1.35"
|
||||||
|
"@0x/sol-trace" "^3.0.45"
|
||||||
|
"@0x/subproviders" "^6.6.5"
|
||||||
|
"@0x/types" "^3.3.6"
|
||||||
|
"@0x/typescript-typings" "^5.3.1"
|
||||||
|
"@0x/utils" "^6.5.3"
|
||||||
|
"@0x/web3-wrapper" "^7.6.5"
|
||||||
|
"@types/bn.js" "^4.11.0"
|
||||||
|
"@types/js-combinatorics" "^0.5.29"
|
||||||
|
"@types/lodash" "4.14.104"
|
||||||
|
"@types/mocha" "^5.2.7"
|
||||||
|
"@types/node" "12.12.54"
|
||||||
|
bn.js "^4.11.8"
|
||||||
|
chai "^4.0.1"
|
||||||
|
chai-as-promised "^7.1.0"
|
||||||
|
chai-bignumber "^3.0.0"
|
||||||
|
decimal.js "^10.2.0"
|
||||||
|
dirty-chai "^2.0.1"
|
||||||
|
ethereum-types "^3.7.0"
|
||||||
|
ethereumjs-util "^7.0.10"
|
||||||
|
ethers "~4.0.4"
|
||||||
|
js-combinatorics "^0.5.3"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
make-promises-safe "^1.1.0"
|
||||||
|
mocha "^6.2.0"
|
||||||
|
|
||||||
|
"@0x/contracts-utils@^4.8.12":
|
||||||
|
version "4.8.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@0x/contracts-utils/-/contracts-utils-4.8.12.tgz#849c2f2f9368a4041c2e2d0c0c0c9716a13383ca"
|
||||||
|
integrity sha512-CWKBAFcs4dyD33McswwJEsoFwldJc0onLFQyLLpd2rAOlwoWxW6QuvGmtE5LOXOXsTy11kDJTO68dQylIN6Qlw==
|
||||||
|
dependencies:
|
||||||
|
"@0x/base-contract" "^6.5.0"
|
||||||
|
"@0x/typescript-typings" "^5.3.1"
|
||||||
|
"@0x/utils" "^6.5.3"
|
||||||
|
bn.js "^4.11.8"
|
||||||
|
ethereum-types "^3.7.0"
|
||||||
|
|
||||||
"@0x/dev-utils@^4.2.14":
|
"@0x/dev-utils@^4.2.14":
|
||||||
version "4.2.14"
|
version "4.2.14"
|
||||||
resolved "https://registry.yarnpkg.com/@0x/dev-utils/-/dev-utils-4.2.14.tgz#2b15b3247ccaf111d8d42689907b603537b0a86c"
|
resolved "https://registry.yarnpkg.com/@0x/dev-utils/-/dev-utils-4.2.14.tgz#2b15b3247ccaf111d8d42689907b603537b0a86c"
|
||||||
@@ -3796,6 +3873,7 @@ bigi@1.4.2, bigi@^1.1.0:
|
|||||||
bignumber.js@7.2.1, bignumber.js@^9.0.0, bignumber.js@^9.0.2, bignumber.js@~4.1.0, bignumber.js@~9.0.0, bignumber.js@~9.0.2:
|
bignumber.js@7.2.1, bignumber.js@^9.0.0, bignumber.js@^9.0.2, bignumber.js@~4.1.0, bignumber.js@~9.0.0, bignumber.js@~9.0.2:
|
||||||
version "9.0.2"
|
version "9.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673"
|
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673"
|
||||||
|
integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==
|
||||||
|
|
||||||
binary-extensions@^2.0.0:
|
binary-extensions@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user