Compare commits
9 Commits
@0x/contra
...
phil/mkr-4
Author | SHA1 | Date | |
---|---|---|---|
|
2baaa2b2db | ||
|
71292a14ae | ||
|
46b3d5b1ab | ||
|
b4cf5d5711 | ||
|
f69b19faca | ||
|
2d16f83e37 | ||
|
4057bdab91 | ||
|
1cd10f0ac9 | ||
|
68f87b2432 |
@@ -20,22 +20,17 @@
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "../libs/LibSignature.sol";
|
||||
import "../libs/LibNativeOrder.sol";
|
||||
import "./INativeOrdersEvents.sol";
|
||||
|
||||
import '@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol';
|
||||
import '../libs/LibSignature.sol';
|
||||
import '../libs/LibNativeOrder.sol';
|
||||
import './INativeOrdersEvents.sol';
|
||||
|
||||
/// @dev Feature for interacting with limit orders.
|
||||
interface INativeOrdersFeature is
|
||||
INativeOrdersEvents
|
||||
{
|
||||
|
||||
interface INativeOrdersFeature is INativeOrdersEvents {
|
||||
/// @dev Transfers protocol fees from the `FeeCollector` pools into
|
||||
/// the staking contract.
|
||||
/// @param poolIds Staking pool IDs
|
||||
function transferProtocolFeesForPools(bytes32[] calldata poolIds)
|
||||
external;
|
||||
function transferProtocolFeesForPools(bytes32[] calldata poolIds) external;
|
||||
|
||||
/// @dev Fill a limit order. The taker and sender will be the caller.
|
||||
/// @param order The limit order. ETH protocol fees can be
|
||||
@@ -49,10 +44,7 @@ interface INativeOrdersFeature is
|
||||
LibNativeOrder.LimitOrder calldata order,
|
||||
LibSignature.Signature calldata signature,
|
||||
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.
|
||||
/// The taker will be the caller.
|
||||
@@ -65,9 +57,7 @@ interface INativeOrdersFeature is
|
||||
LibNativeOrder.RfqOrder calldata order,
|
||||
LibSignature.Signature calldata signature,
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||
) external returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||
|
||||
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
|
||||
/// The taker will be the caller. ETH protocol fees can be
|
||||
@@ -81,10 +71,7 @@ interface INativeOrdersFeature is
|
||||
LibNativeOrder.LimitOrder calldata order,
|
||||
LibSignature.Signature calldata signature,
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint128 makerTokenFilledAmount);
|
||||
) external payable returns (uint128 makerTokenFilledAmount);
|
||||
|
||||
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
|
||||
/// The taker will be the caller.
|
||||
@@ -96,9 +83,7 @@ interface INativeOrdersFeature is
|
||||
LibNativeOrder.RfqOrder calldata order,
|
||||
LibSignature.Signature calldata signature,
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
returns (uint128 makerTokenFilledAmount);
|
||||
) external returns (uint128 makerTokenFilledAmount);
|
||||
|
||||
/// @dev Fill a limit order. Internal variant. ETH protocol fees can be
|
||||
/// attached to this call. Any unspent ETH will be refunded to
|
||||
@@ -116,10 +101,7 @@ interface INativeOrdersFeature is
|
||||
uint128 takerTokenFillAmount,
|
||||
address taker,
|
||||
address sender
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||
) external payable returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||
|
||||
/// @dev Fill an RFQ order. Internal variant.
|
||||
/// @param order The RFQ order.
|
||||
@@ -138,40 +120,33 @@ interface INativeOrdersFeature is
|
||||
address taker,
|
||||
bool useSelfBalance,
|
||||
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.
|
||||
/// Silently succeeds if the order has already been cancelled.
|
||||
/// @param order The limit order.
|
||||
function cancelLimitOrder(LibNativeOrder.LimitOrder calldata order)
|
||||
external;
|
||||
function cancelLimitOrder(LibNativeOrder.LimitOrder calldata order) external;
|
||||
|
||||
/// @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.
|
||||
/// @param order The RFQ order.
|
||||
function cancelRfqOrder(LibNativeOrder.RfqOrder calldata order)
|
||||
external;
|
||||
function cancelRfqOrder(LibNativeOrder.RfqOrder calldata order) external;
|
||||
|
||||
/// @dev Mark what tx.origin addresses are allowed to fill an order that
|
||||
/// specifies the message sender as its txOrigin.
|
||||
/// @param origins An array of origin addresses to update.
|
||||
/// @param allowed True to register, false to unregister.
|
||||
function registerAllowedRfqOrigins(address[] memory origins, bool allowed)
|
||||
external;
|
||||
function registerAllowedRfqOrigins(address[] memory origins, bool allowed) external;
|
||||
|
||||
/// @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.
|
||||
/// @param orders The limit orders.
|
||||
function batchCancelLimitOrders(LibNativeOrder.LimitOrder[] calldata orders)
|
||||
external;
|
||||
function batchCancelLimitOrders(LibNativeOrder.LimitOrder[] calldata orders) external;
|
||||
|
||||
/// @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.
|
||||
/// @param orders The RFQ orders.
|
||||
function batchCancelRfqOrders(LibNativeOrder.RfqOrder[] calldata orders)
|
||||
external;
|
||||
function batchCancelRfqOrders(LibNativeOrder.RfqOrder[] calldata orders) external;
|
||||
|
||||
/// @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
|
||||
@@ -184,8 +159,7 @@ interface INativeOrdersFeature is
|
||||
IERC20TokenV06 makerToken,
|
||||
IERC20TokenV06 takerToken,
|
||||
uint256 minValidSalt
|
||||
)
|
||||
external;
|
||||
) external;
|
||||
|
||||
/// @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.
|
||||
@@ -200,8 +174,7 @@ interface INativeOrdersFeature is
|
||||
IERC20TokenV06 makerToken,
|
||||
IERC20TokenV06 takerToken,
|
||||
uint256 minValidSalt
|
||||
)
|
||||
external;
|
||||
) external;
|
||||
|
||||
/// @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
|
||||
@@ -214,8 +187,7 @@ interface INativeOrdersFeature is
|
||||
IERC20TokenV06[] calldata makerTokens,
|
||||
IERC20TokenV06[] calldata takerTokens,
|
||||
uint256[] calldata minValidSalts
|
||||
)
|
||||
external;
|
||||
) external;
|
||||
|
||||
/// @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.
|
||||
@@ -230,8 +202,7 @@ interface INativeOrdersFeature is
|
||||
IERC20TokenV06[] memory makerTokens,
|
||||
IERC20TokenV06[] memory takerTokens,
|
||||
uint256[] memory minValidSalts
|
||||
)
|
||||
external;
|
||||
) external;
|
||||
|
||||
/// @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
|
||||
@@ -244,8 +215,7 @@ interface INativeOrdersFeature is
|
||||
IERC20TokenV06 makerToken,
|
||||
IERC20TokenV06 takerToken,
|
||||
uint256 minValidSalt
|
||||
)
|
||||
external;
|
||||
) external;
|
||||
|
||||
/// @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.
|
||||
@@ -260,8 +230,7 @@ interface INativeOrdersFeature is
|
||||
IERC20TokenV06 makerToken,
|
||||
IERC20TokenV06 takerToken,
|
||||
uint256 minValidSalt
|
||||
)
|
||||
external;
|
||||
) external;
|
||||
|
||||
/// @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
|
||||
@@ -274,8 +243,7 @@ interface INativeOrdersFeature is
|
||||
IERC20TokenV06[] calldata makerTokens,
|
||||
IERC20TokenV06[] calldata takerTokens,
|
||||
uint256[] calldata minValidSalts
|
||||
)
|
||||
external;
|
||||
) external;
|
||||
|
||||
/// @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.
|
||||
@@ -290,8 +258,7 @@ interface INativeOrdersFeature is
|
||||
IERC20TokenV06[] memory makerTokens,
|
||||
IERC20TokenV06[] memory takerTokens,
|
||||
uint256[] memory minValidSalts
|
||||
)
|
||||
external;
|
||||
) external;
|
||||
|
||||
/// @dev Get the order info for a limit order.
|
||||
/// @param order The limit order.
|
||||
@@ -312,26 +279,17 @@ interface INativeOrdersFeature is
|
||||
/// @dev Get the canonical hash of a limit order.
|
||||
/// @param order The limit order.
|
||||
/// @return orderHash The order hash.
|
||||
function getLimitOrderHash(LibNativeOrder.LimitOrder calldata order)
|
||||
external
|
||||
view
|
||||
returns (bytes32 orderHash);
|
||||
function getLimitOrderHash(LibNativeOrder.LimitOrder calldata order) external view returns (bytes32 orderHash);
|
||||
|
||||
/// @dev Get the canonical hash of an RFQ order.
|
||||
/// @param order The RFQ order.
|
||||
/// @return orderHash The order hash.
|
||||
function getRfqOrderHash(LibNativeOrder.RfqOrder calldata order)
|
||||
external
|
||||
view
|
||||
returns (bytes32 orderHash);
|
||||
function getRfqOrderHash(LibNativeOrder.RfqOrder calldata order) external view returns (bytes32 orderHash);
|
||||
|
||||
/// @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.
|
||||
/// @return multiplier The protocol fee multiplier.
|
||||
function getProtocolFeeMultiplier()
|
||||
external
|
||||
view
|
||||
returns (uint32 multiplier);
|
||||
function getProtocolFeeMultiplier() external view returns (uint32 multiplier);
|
||||
|
||||
/// @dev Get order info, fillable amount, and signature validity for a limit order.
|
||||
/// 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
|
||||
/// based on maker funds, in taker tokens.
|
||||
/// @return isSignatureValid Whether the signature is valid.
|
||||
function getRfqOrderRelevantState(
|
||||
LibNativeOrder.RfqOrder calldata order,
|
||||
LibSignature.Signature calldata signature
|
||||
)
|
||||
function getRfqOrderRelevantState(LibNativeOrder.RfqOrder calldata order, LibSignature.Signature calldata signature)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
@@ -419,20 +374,10 @@ interface INativeOrdersFeature is
|
||||
/// 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 allowed True to register, false to unregister.
|
||||
function registerAllowedOrderSigner(
|
||||
address signer,
|
||||
bool allowed
|
||||
)
|
||||
external;
|
||||
function registerAllowedOrderSigner(address signer, bool allowed) external;
|
||||
|
||||
/// @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 signer The address that is providing a signature
|
||||
function isValidOrderSigner(
|
||||
address maker,
|
||||
address signer
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bool isAllowed);
|
||||
function isValidOrderSigner(address maker, address signer) external view returns (bool isAllowed);
|
||||
}
|
||||
|
@@ -20,23 +20,22 @@
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
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/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
|
||||
import "../errors/LibTransformERC20RichErrors.sol";
|
||||
import "../features/interfaces/INativeOrdersFeature.sol";
|
||||
import "../features/libs/LibNativeOrder.sol";
|
||||
import "./bridges/IBridgeAdapter.sol";
|
||||
import "./Transformer.sol";
|
||||
import "./LibERC20Transformer.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/LibERC20TokenV06.sol';
|
||||
import '@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol';
|
||||
import '@0x/contracts-utils/contracts/src/v06/LibMathV06.sol';
|
||||
import '../errors/LibTransformERC20RichErrors.sol';
|
||||
import '../features/interfaces/INativeOrdersFeature.sol';
|
||||
import '../features/libs/LibNativeOrder.sol';
|
||||
import './bridges/IBridgeAdapter.sol';
|
||||
import './Transformer.sol';
|
||||
import './LibERC20Transformer.sol';
|
||||
import '../IZeroEx.sol';
|
||||
|
||||
/// @dev A transformer that fills an ERC20 market sell/buy quote.
|
||||
/// This transformer shortcuts bridge orders and fills them directly
|
||||
contract FillQuoteTransformer is
|
||||
Transformer
|
||||
{
|
||||
contract FillQuoteTransformer is Transformer {
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
using LibERC20Transformer for IERC20TokenV06;
|
||||
using LibSafeMathV06 for uint256;
|
||||
@@ -52,7 +51,8 @@ contract FillQuoteTransformer is
|
||||
enum OrderType {
|
||||
Bridge,
|
||||
Limit,
|
||||
Rfq
|
||||
Rfq,
|
||||
Otc
|
||||
}
|
||||
|
||||
struct LimitOrderInfo {
|
||||
@@ -69,6 +69,13 @@ contract FillQuoteTransformer is
|
||||
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()`.
|
||||
struct TransformData {
|
||||
// Whether we are performing a market sell or buy.
|
||||
@@ -79,26 +86,24 @@ contract FillQuoteTransformer is
|
||||
// The token being bought.
|
||||
// This should be an actual token, not the ETH pseudo-token.
|
||||
IERC20TokenV06 buyToken;
|
||||
|
||||
// External liquidity bridge orders. Sorted by fill sequence.
|
||||
IBridgeAdapter.BridgeOrder[] bridgeOrders;
|
||||
// Native limit orders. Sorted by fill sequence.
|
||||
LimitOrderInfo[] limitOrders;
|
||||
// Native RFQ orders. Sorted by fill sequence.
|
||||
RfqOrderInfo[] rfqOrders;
|
||||
|
||||
// Otc orders.
|
||||
OtcOrderInfo[] otcOrders;
|
||||
// The sequence to fill the orders in. Each item will fill the next
|
||||
// order of that type in either `bridgeOrders`, `limitOrders`,
|
||||
// or `rfqOrders.`
|
||||
// `rfqOrders`, or `otcOrders.`
|
||||
OrderType[] fillSequence;
|
||||
|
||||
// Amount of `sellToken` to sell or `buyToken` to buy.
|
||||
// For sells, setting the high-bit indicates that
|
||||
// `sellAmount & LOW_BITS` should be treated as a `1e18` fraction of
|
||||
// the current balance of `sellToken`, where
|
||||
// `1e18+ == 100%` and `0.5e18 == 50%`, etc.
|
||||
uint256 fillAmount;
|
||||
|
||||
// Who to transfer unused protocol fees to.
|
||||
// May be a valid address or one of:
|
||||
// `address(0)`: Stay in flash wallet.
|
||||
@@ -123,7 +128,7 @@ contract FillQuoteTransformer is
|
||||
uint256 soldAmount;
|
||||
uint256 protocolFee;
|
||||
uint256 takerTokenBalanceRemaining;
|
||||
uint256[3] currentIndices;
|
||||
uint256[4] currentIndices;
|
||||
OrderType currentOrderType;
|
||||
}
|
||||
|
||||
@@ -133,7 +138,7 @@ contract FillQuoteTransformer is
|
||||
event ProtocolFeeUnfunded(bytes32 orderHash);
|
||||
|
||||
/// @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.
|
||||
uint256 private constant LOWER_255_BITS = HIGH_BIT - 1;
|
||||
/// @dev If `refundReceiver` is set to this address, unpsent
|
||||
@@ -147,15 +152,12 @@ contract FillQuoteTransformer is
|
||||
IBridgeAdapter public immutable bridgeAdapter;
|
||||
|
||||
/// @dev The exchange proxy contract.
|
||||
INativeOrdersFeature public immutable zeroEx;
|
||||
IZeroEx public immutable zeroEx;
|
||||
|
||||
/// @dev Create this contract.
|
||||
/// @param bridgeAdapter_ The bridge adapter contract.
|
||||
/// @param zeroEx_ The Exchange Proxy contract.
|
||||
constructor(IBridgeAdapter bridgeAdapter_, INativeOrdersFeature zeroEx_)
|
||||
public
|
||||
Transformer()
|
||||
{
|
||||
constructor(IBridgeAdapter bridgeAdapter_, IZeroEx zeroEx_) public Transformer() {
|
||||
bridgeAdapter = bridgeAdapter_;
|
||||
zeroEx = zeroEx_;
|
||||
}
|
||||
@@ -165,30 +167,27 @@ contract FillQuoteTransformer is
|
||||
/// to this call. `buyToken` and excess ETH will be transferred back to the caller.
|
||||
/// @param context Context information.
|
||||
/// @return magicBytes The success bytes (`LibERC20Transformer.TRANSFORMER_SUCCESS`).
|
||||
function transform(TransformContext calldata context)
|
||||
external
|
||||
override
|
||||
returns (bytes4 magicBytes)
|
||||
{
|
||||
function transform(TransformContext calldata context) external override returns (bytes4 magicBytes) {
|
||||
TransformData memory data = abi.decode(context.data, (TransformData));
|
||||
FillState memory state;
|
||||
|
||||
// Validate data fields.
|
||||
if (data.sellToken.isTokenETH() || data.buyToken.isTokenETH()) {
|
||||
LibTransformERC20RichErrors.InvalidTransformDataError(
|
||||
LibTransformERC20RichErrors.InvalidTransformDataErrorCode.INVALID_TOKENS,
|
||||
context.data
|
||||
).rrevert();
|
||||
LibTransformERC20RichErrors
|
||||
.InvalidTransformDataError(
|
||||
LibTransformERC20RichErrors.InvalidTransformDataErrorCode.INVALID_TOKENS,
|
||||
context.data
|
||||
)
|
||||
.rrevert();
|
||||
}
|
||||
|
||||
if (data.bridgeOrders.length
|
||||
+ data.limitOrders.length
|
||||
+ data.rfqOrders.length != data.fillSequence.length
|
||||
) {
|
||||
LibTransformERC20RichErrors.InvalidTransformDataError(
|
||||
LibTransformERC20RichErrors.InvalidTransformDataErrorCode.INVALID_ARRAY_LENGTH,
|
||||
context.data
|
||||
).rrevert();
|
||||
if (data.bridgeOrders.length + data.limitOrders.length + data.rfqOrders.length != data.fillSequence.length) {
|
||||
LibTransformERC20RichErrors
|
||||
.InvalidTransformDataError(
|
||||
LibTransformERC20RichErrors.InvalidTransformDataErrorCode.INVALID_ARRAY_LENGTH,
|
||||
context.data
|
||||
)
|
||||
.rrevert();
|
||||
}
|
||||
|
||||
state.takerTokenBalanceRemaining = data.sellToken.getTokenBalanceOf(address(this));
|
||||
@@ -202,8 +201,7 @@ contract FillQuoteTransformer is
|
||||
data.sellToken.approveIfBelow(address(zeroEx), data.fillAmount);
|
||||
// Compute the protocol fee if a limit order is present.
|
||||
if (data.limitOrders.length != 0) {
|
||||
state.protocolFee = uint256(zeroEx.getProtocolFeeMultiplier())
|
||||
.safeMul(tx.gasprice);
|
||||
state.protocolFee = uint256(zeroEx.getProtocolFeeMultiplier()).safeMul(tx.gasprice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,10 +212,14 @@ contract FillQuoteTransformer is
|
||||
// Check if we've hit our targets.
|
||||
if (data.side == Side.Sell) {
|
||||
// Market sell check.
|
||||
if (state.soldAmount >= data.fillAmount) { break; }
|
||||
if (state.soldAmount >= data.fillAmount) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Market buy check.
|
||||
if (state.boughtAmount >= data.fillAmount) { break; }
|
||||
if (state.boughtAmount >= data.fillAmount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
state.currentOrderType = OrderType(data.fillSequence[i]);
|
||||
@@ -230,19 +232,17 @@ contract FillQuoteTransformer is
|
||||
results = _fillLimitOrder(data.limitOrders[orderIndex], data, state);
|
||||
} else if (state.currentOrderType == OrderType.Rfq) {
|
||||
results = _fillRfqOrder(data.rfqOrders[orderIndex], data, state);
|
||||
} else if (state.currentOrderType == OrderType.Otc) {
|
||||
results = _fillOtcOrder(data.otcOrders[orderIndex], data, state);
|
||||
} else {
|
||||
revert("INVALID_ORDER_TYPE");
|
||||
revert('INVALID_ORDER_TYPE');
|
||||
}
|
||||
|
||||
// Accumulate totals.
|
||||
state.soldAmount = state.soldAmount
|
||||
.safeAdd(results.takerTokenSoldAmount);
|
||||
state.boughtAmount = state.boughtAmount
|
||||
.safeAdd(results.makerTokenBoughtAmount);
|
||||
state.ethRemaining = state.ethRemaining
|
||||
.safeSub(results.protocolFeePaid);
|
||||
state.takerTokenBalanceRemaining = state.takerTokenBalanceRemaining
|
||||
.safeSub(results.takerTokenSoldAmount);
|
||||
state.soldAmount = state.soldAmount.safeAdd(results.takerTokenSoldAmount);
|
||||
state.boughtAmount = state.boughtAmount.safeAdd(results.makerTokenBoughtAmount);
|
||||
state.ethRemaining = state.ethRemaining.safeSub(results.protocolFeePaid);
|
||||
state.takerTokenBalanceRemaining = state.takerTokenBalanceRemaining.safeSub(results.takerTokenSoldAmount);
|
||||
state.currentIndices[uint256(state.currentOrderType)]++;
|
||||
}
|
||||
|
||||
@@ -251,21 +251,15 @@ contract FillQuoteTransformer is
|
||||
// Market sell check.
|
||||
if (state.soldAmount < data.fillAmount) {
|
||||
LibTransformERC20RichErrors
|
||||
.IncompleteFillSellQuoteError(
|
||||
address(data.sellToken),
|
||||
state.soldAmount,
|
||||
data.fillAmount
|
||||
).rrevert();
|
||||
.IncompleteFillSellQuoteError(address(data.sellToken), state.soldAmount, data.fillAmount)
|
||||
.rrevert();
|
||||
}
|
||||
} else {
|
||||
// Market buy check.
|
||||
if (state.boughtAmount < data.fillAmount) {
|
||||
LibTransformERC20RichErrors
|
||||
.IncompleteFillBuyQuoteError(
|
||||
address(data.buyToken),
|
||||
state.boughtAmount,
|
||||
data.fillAmount
|
||||
).rrevert();
|
||||
.IncompleteFillBuyQuoteError(address(data.buyToken), state.boughtAmount, data.fillAmount)
|
||||
.rrevert();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,13 +267,13 @@ contract FillQuoteTransformer is
|
||||
if (state.ethRemaining > 0 && data.refundReceiver != address(0)) {
|
||||
bool transferSuccess;
|
||||
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) {
|
||||
(transferSuccess,) = context.sender.call{value: state.ethRemaining}("");
|
||||
(transferSuccess, ) = context.sender.call{ value: state.ethRemaining }('');
|
||||
} 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;
|
||||
}
|
||||
@@ -289,10 +283,7 @@ contract FillQuoteTransformer is
|
||||
IBridgeAdapter.BridgeOrder memory order,
|
||||
TransformData memory data,
|
||||
FillState memory state
|
||||
)
|
||||
private
|
||||
returns (FillOrderResults memory results)
|
||||
{
|
||||
) private returns (FillOrderResults memory results) {
|
||||
uint256 takerTokenFillAmount = _computeTakerTokenFillAmount(
|
||||
data,
|
||||
state,
|
||||
@@ -321,10 +312,7 @@ contract FillQuoteTransformer is
|
||||
LimitOrderInfo memory orderInfo,
|
||||
TransformData memory data,
|
||||
FillState memory state
|
||||
)
|
||||
private
|
||||
returns (FillOrderResults memory results)
|
||||
{
|
||||
) private returns (FillOrderResults memory results) {
|
||||
uint256 takerTokenFillAmount = LibSafeMathV06.min256(
|
||||
_computeTakerTokenFillAmount(
|
||||
data,
|
||||
@@ -344,22 +332,21 @@ contract FillQuoteTransformer is
|
||||
}
|
||||
|
||||
try
|
||||
zeroEx.fillLimitOrder
|
||||
{value: state.protocolFee}
|
||||
(
|
||||
orderInfo.order,
|
||||
orderInfo.signature,
|
||||
takerTokenFillAmount.safeDowncastToUint128()
|
||||
)
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
|
||||
{
|
||||
zeroEx.fillLimitOrder{ value: state.protocolFee }(
|
||||
orderInfo.order,
|
||||
orderInfo.signature,
|
||||
takerTokenFillAmount.safeDowncastToUint128()
|
||||
)
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) {
|
||||
if (orderInfo.order.takerTokenFeeAmount > 0) {
|
||||
takerTokenFilledAmount = takerTokenFilledAmount.safeAdd128(
|
||||
LibMathV06.getPartialAmountFloor(
|
||||
takerTokenFilledAmount,
|
||||
orderInfo.order.takerAmount,
|
||||
orderInfo.order.takerTokenFeeAmount
|
||||
).safeDowncastToUint128()
|
||||
LibMathV06
|
||||
.getPartialAmountFloor(
|
||||
takerTokenFilledAmount,
|
||||
orderInfo.order.takerAmount,
|
||||
orderInfo.order.takerTokenFeeAmount
|
||||
)
|
||||
.safeDowncastToUint128()
|
||||
);
|
||||
}
|
||||
results.takerTokenSoldAmount = takerTokenFilledAmount;
|
||||
@@ -373,30 +360,34 @@ contract FillQuoteTransformer is
|
||||
RfqOrderInfo memory orderInfo,
|
||||
TransformData memory data,
|
||||
FillState memory state
|
||||
)
|
||||
private
|
||||
returns (FillOrderResults memory results)
|
||||
{
|
||||
) private returns (FillOrderResults memory results) {
|
||||
uint256 takerTokenFillAmount = LibSafeMathV06.min256(
|
||||
_computeTakerTokenFillAmount(
|
||||
data,
|
||||
state,
|
||||
orderInfo.order.takerAmount,
|
||||
orderInfo.order.makerAmount,
|
||||
0
|
||||
),
|
||||
_computeTakerTokenFillAmount(data, state, orderInfo.order.takerAmount, orderInfo.order.makerAmount, 0),
|
||||
orderInfo.maxTakerTokenFillAmount
|
||||
);
|
||||
|
||||
try
|
||||
zeroEx.fillRfqOrder
|
||||
(
|
||||
orderInfo.order,
|
||||
orderInfo.signature,
|
||||
takerTokenFillAmount.safeDowncastToUint128()
|
||||
)
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
|
||||
{
|
||||
zeroEx.fillRfqOrder(orderInfo.order, orderInfo.signature, takerTokenFillAmount.safeDowncastToUint128())
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) {
|
||||
results.takerTokenSoldAmount = takerTokenFilledAmount;
|
||||
results.makerTokenBoughtAmount = makerTokenFilledAmount;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// 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.makerTokenBoughtAmount = makerTokenFilledAmount;
|
||||
} catch {}
|
||||
@@ -409,11 +400,7 @@ contract FillQuoteTransformer is
|
||||
uint256 orderTakerAmount,
|
||||
uint256 orderMakerAmount,
|
||||
uint256 orderTakerTokenFeeAmount
|
||||
)
|
||||
private
|
||||
pure
|
||||
returns (uint256 takerTokenFillAmount)
|
||||
{
|
||||
) private pure returns (uint256 takerTokenFillAmount) {
|
||||
if (data.side == Side.Sell) {
|
||||
takerTokenFillAmount = data.fillAmount.safeSub(state.soldAmount);
|
||||
if (orderTakerTokenFeeAmount != 0) {
|
||||
@@ -423,34 +410,31 @@ contract FillQuoteTransformer is
|
||||
orderTakerAmount
|
||||
);
|
||||
}
|
||||
} else { // Buy
|
||||
} else {
|
||||
// Buy
|
||||
takerTokenFillAmount = LibMathV06.getPartialAmountCeil(
|
||||
data.fillAmount.safeSub(state.boughtAmount),
|
||||
orderMakerAmount,
|
||||
orderTakerAmount
|
||||
);
|
||||
}
|
||||
return LibSafeMathV06.min256(
|
||||
LibSafeMathV06.min256(takerTokenFillAmount, orderTakerAmount),
|
||||
state.takerTokenBalanceRemaining
|
||||
);
|
||||
return
|
||||
LibSafeMathV06.min256(
|
||||
LibSafeMathV06.min256(takerTokenFillAmount, orderTakerAmount),
|
||||
state.takerTokenBalanceRemaining
|
||||
);
|
||||
}
|
||||
|
||||
// Convert possible proportional values to absolute quantities.
|
||||
function _normalizeFillAmount(uint256 rawAmount, uint256 balance)
|
||||
private
|
||||
pure
|
||||
returns (uint256 normalized)
|
||||
{
|
||||
function _normalizeFillAmount(uint256 rawAmount, uint256 balance) private pure returns (uint256 normalized) {
|
||||
if ((rawAmount & HIGH_BIT) == HIGH_BIT) {
|
||||
// If the high bit of `rawAmount` is set then the lower 255 bits
|
||||
// specify a fraction of `balance`.
|
||||
return LibSafeMathV06.min256(
|
||||
balance
|
||||
* LibSafeMathV06.min256(rawAmount & LOWER_255_BITS, 1e18)
|
||||
/ 1e18,
|
||||
balance
|
||||
);
|
||||
return
|
||||
LibSafeMathV06.min256(
|
||||
(balance * LibSafeMathV06.min256(rawAmount & LOWER_255_BITS, 1e18)) / 1e18,
|
||||
balance
|
||||
);
|
||||
}
|
||||
return rawAmount;
|
||||
}
|
||||
|
@@ -40,7 +40,6 @@ import "./mixins/MixinMakerPSM.sol";
|
||||
import "./mixins/MixinMooniswap.sol";
|
||||
import "./mixins/MixinMStable.sol";
|
||||
import "./mixins/MixinNerve.sol";
|
||||
import "./mixins/MixinOasis.sol";
|
||||
import "./mixins/MixinPlatypus.sol";
|
||||
import "./mixins/MixinShell.sol";
|
||||
import "./mixins/MixinUniswap.sol";
|
||||
@@ -68,7 +67,6 @@ contract BridgeAdapter is
|
||||
MixinMooniswap,
|
||||
MixinMStable,
|
||||
MixinNerve,
|
||||
MixinOasis,
|
||||
MixinPlatypus,
|
||||
MixinShell,
|
||||
MixinUniswap,
|
||||
@@ -94,7 +92,6 @@ contract BridgeAdapter is
|
||||
MixinMooniswap(weth)
|
||||
MixinMStable()
|
||||
MixinNerve()
|
||||
MixinOasis()
|
||||
MixinPlatypus()
|
||||
MixinShell()
|
||||
MixinUniswap(weth)
|
||||
@@ -187,13 +184,6 @@ contract BridgeAdapter is
|
||||
sellAmount,
|
||||
order.bridgeData
|
||||
);
|
||||
} else if (protocolId == BridgeProtocols.OASIS) {
|
||||
boughtAmount = _tradeOasis(
|
||||
sellToken,
|
||||
buyToken,
|
||||
sellAmount,
|
||||
order.bridgeData
|
||||
);
|
||||
} else if (protocolId == BridgeProtocols.SHELL) {
|
||||
boughtAmount = _tradeShell(
|
||||
sellToken,
|
||||
|
@@ -32,16 +32,16 @@ library BridgeProtocols {
|
||||
uint128 internal constant UNISWAPV2 = 2;
|
||||
uint128 internal constant UNISWAP = 3;
|
||||
uint128 internal constant BALANCER = 4;
|
||||
uint128 internal constant KYBER = 5;
|
||||
uint128 internal constant KYBER = 5; // Not used: deprecated.
|
||||
uint128 internal constant MOONISWAP = 6;
|
||||
uint128 internal constant MSTABLE = 7;
|
||||
uint128 internal constant OASIS = 8;
|
||||
uint128 internal constant OASIS = 8; // Not used: deprecated.
|
||||
uint128 internal constant SHELL = 9;
|
||||
uint128 internal constant DODO = 10;
|
||||
uint128 internal constant DODOV2 = 11;
|
||||
uint128 internal constant CRYPTOCOM = 12;
|
||||
uint128 internal constant BANCOR = 13;
|
||||
uint128 internal constant COFIX = 14;
|
||||
uint128 internal constant COFIX = 14; // Not used: deprecated.
|
||||
uint128 internal constant NERVE = 15;
|
||||
uint128 internal constant MAKERPSM = 16;
|
||||
uint128 internal constant BALANCERV2 = 17;
|
||||
|
@@ -1,92 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2020 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||
|
||||
|
||||
interface ICoFiXRouter {
|
||||
// msg.value = fee
|
||||
function swapExactTokensForETH(
|
||||
address token,
|
||||
uint amountIn,
|
||||
uint amountOutMin,
|
||||
address to,
|
||||
address rewardTo,
|
||||
uint deadline
|
||||
) external payable returns (uint _amountIn, uint _amountOut);
|
||||
|
||||
// msg.value = amountIn + fee
|
||||
function swapExactETHForTokens(
|
||||
address token,
|
||||
uint amountIn,
|
||||
uint amountOutMin,
|
||||
address to,
|
||||
address rewardTo,
|
||||
uint deadline
|
||||
) external payable returns (uint _amountIn, uint _amountOut);
|
||||
}
|
||||
|
||||
interface ICoFiXPair {
|
||||
|
||||
function swapWithExact(address outToken, address to)
|
||||
external
|
||||
payable
|
||||
returns (
|
||||
uint amountIn,
|
||||
uint amountOut,
|
||||
uint oracleFeeChange,
|
||||
uint256[4] memory tradeInfo
|
||||
);
|
||||
}
|
||||
|
||||
contract MixinCoFiX {
|
||||
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
|
||||
function _tradeCoFiX(
|
||||
IERC20TokenV06 sellToken,
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 sellAmount,
|
||||
bytes memory bridgeData
|
||||
)
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
(uint256 fee, ICoFiXPair pool) = abi.decode(bridgeData, (uint256, ICoFiXPair));
|
||||
// Transfer tokens into the pool
|
||||
LibERC20TokenV06.compatTransfer(
|
||||
sellToken,
|
||||
address(pool),
|
||||
sellAmount
|
||||
);
|
||||
// Call the swap exact with the tokens now in the pool
|
||||
// pay the NEST Oracle fee with ETH
|
||||
(/* In */, boughtAmount, , ) = pool.swapWithExact{value: fee}(
|
||||
address(buyToken),
|
||||
address(this)
|
||||
);
|
||||
|
||||
return boughtAmount;
|
||||
}
|
||||
}
|
@@ -1,124 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2020 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||
import "../IBridgeAdapter.sol";
|
||||
|
||||
interface IKyberNetworkProxy {
|
||||
|
||||
/// @dev Sells `sellTokenAddress` tokens for `buyTokenAddress` tokens
|
||||
/// using a hint for the reserve.
|
||||
/// @param sellToken Token to sell.
|
||||
/// @param sellAmount Amount of tokens to sell.
|
||||
/// @param buyToken Token to buy.
|
||||
/// @param recipientAddress Address to send bought tokens to.
|
||||
/// @param maxBuyTokenAmount A limit on the amount of tokens to buy.
|
||||
/// @param minConversionRate The minimal conversion rate. If actual rate
|
||||
/// is lower, trade is canceled.
|
||||
/// @param walletId The wallet ID to send part of the fees
|
||||
/// @param hint The hint for the selective inclusion (or exclusion) of reserves
|
||||
/// @return boughtAmount Amount of tokens bought.
|
||||
function tradeWithHint(
|
||||
IERC20TokenV06 sellToken,
|
||||
uint256 sellAmount,
|
||||
IERC20TokenV06 buyToken,
|
||||
address payable recipientAddress,
|
||||
uint256 maxBuyTokenAmount,
|
||||
uint256 minConversionRate,
|
||||
address payable walletId,
|
||||
bytes calldata hint
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint256 boughtAmount);
|
||||
}
|
||||
|
||||
contract MixinKyber {
|
||||
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
|
||||
/// @dev Address indicating the trade is using ETH
|
||||
IERC20TokenV06 private immutable KYBER_ETH_ADDRESS =
|
||||
IERC20TokenV06(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
|
||||
/// @dev Mainnet address of the WETH contract.
|
||||
IEtherTokenV06 private immutable WETH;
|
||||
|
||||
constructor(IEtherTokenV06 weth)
|
||||
public
|
||||
{
|
||||
WETH = weth;
|
||||
}
|
||||
|
||||
function _tradeKyber(
|
||||
IERC20TokenV06 sellToken,
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 sellAmount,
|
||||
bytes memory bridgeData
|
||||
)
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
(IKyberNetworkProxy kyber, bytes memory hint) =
|
||||
abi.decode(bridgeData, (IKyberNetworkProxy, bytes));
|
||||
|
||||
uint256 payableAmount = 0;
|
||||
if (sellToken != WETH) {
|
||||
// If the input token is not WETH, grant an allowance to the exchange
|
||||
// to spend them.
|
||||
sellToken.approveIfBelow(
|
||||
address(kyber),
|
||||
sellAmount
|
||||
);
|
||||
} else {
|
||||
// If the input token is WETH, unwrap it and attach it to the call.
|
||||
payableAmount = sellAmount;
|
||||
WETH.withdraw(payableAmount);
|
||||
}
|
||||
|
||||
// Try to sell all of this contract's input token balance through
|
||||
// `KyberNetworkProxy.trade()`.
|
||||
boughtAmount = kyber.tradeWithHint{ value: payableAmount }(
|
||||
// Input token.
|
||||
sellToken == WETH ? KYBER_ETH_ADDRESS : sellToken,
|
||||
// Sell amount.
|
||||
sellAmount,
|
||||
// Output token.
|
||||
buyToken == WETH ? KYBER_ETH_ADDRESS : buyToken,
|
||||
// Transfer to this contract
|
||||
address(uint160(address(this))),
|
||||
// Buy as much as possible.
|
||||
uint256(-1),
|
||||
// Lowest minimum conversion rate
|
||||
1,
|
||||
// No affiliate address.
|
||||
address(0),
|
||||
hint
|
||||
);
|
||||
// If receving ETH, wrap it to WETH.
|
||||
if (buyToken == WETH) {
|
||||
WETH.deposit{ value: boughtAmount }();
|
||||
}
|
||||
return boughtAmount;
|
||||
}
|
||||
}
|
@@ -1,76 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2020 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "../IBridgeAdapter.sol";
|
||||
|
||||
interface IOasis {
|
||||
|
||||
/// @dev Sell `sellAmount` of `sellToken` token and receive `buyToken` token.
|
||||
/// @param sellToken The token being sold.
|
||||
/// @param sellAmount The amount of `sellToken` token being sold.
|
||||
/// @param buyToken The token being bought.
|
||||
/// @param minBoughtAmount Minimum amount of `buyToken` token to buy.
|
||||
/// @return boughtAmount Amount of `buyToken` bought.
|
||||
function sellAllAmount(
|
||||
IERC20TokenV06 sellToken,
|
||||
uint256 sellAmount,
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 minBoughtAmount
|
||||
)
|
||||
external
|
||||
returns (uint256 boughtAmount);
|
||||
}
|
||||
|
||||
contract MixinOasis {
|
||||
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
|
||||
function _tradeOasis(
|
||||
IERC20TokenV06 sellToken,
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 sellAmount,
|
||||
bytes memory bridgeData
|
||||
)
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
|
||||
(IOasis oasis) = abi.decode(bridgeData, (IOasis));
|
||||
|
||||
// Grant an allowance to the exchange to spend `sellToken` token.
|
||||
sellToken.approveIfBelow(
|
||||
address(oasis),
|
||||
sellAmount
|
||||
);
|
||||
// Try to sell all of this contract's `sellToken` token balance.
|
||||
boughtAmount = oasis.sellAllAmount(
|
||||
sellToken,
|
||||
sellAmount,
|
||||
buyToken,
|
||||
// min fill amount
|
||||
1
|
||||
);
|
||||
return boughtAmount;
|
||||
}
|
||||
}
|
@@ -43,7 +43,7 @@
|
||||
"config": {
|
||||
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinPlatypus|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
|
||||
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|MixinBancor|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinPlatypus|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -83,6 +83,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.5.0",
|
||||
"@0x/contracts-utils": "^4.8.12",
|
||||
"@0x/protocol-utils": "^11.13.0",
|
||||
"@0x/subproviders": "^6.6.5",
|
||||
"@0x/types": "^3.3.6",
|
||||
|
@@ -103,7 +103,6 @@ import * as MixinBalancer from '../test/generated-artifacts/MixinBalancer.json';
|
||||
import * as MixinBalancerV2 from '../test/generated-artifacts/MixinBalancerV2.json';
|
||||
import * as MixinBalancerV2Batch from '../test/generated-artifacts/MixinBalancerV2Batch.json';
|
||||
import * as MixinBancor from '../test/generated-artifacts/MixinBancor.json';
|
||||
import * as MixinCoFiX from '../test/generated-artifacts/MixinCoFiX.json';
|
||||
import * as MixinCompound from '../test/generated-artifacts/MixinCompound.json';
|
||||
import * as MixinCryptoCom from '../test/generated-artifacts/MixinCryptoCom.json';
|
||||
import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json';
|
||||
@@ -111,14 +110,12 @@ import * as MixinCurveV2 from '../test/generated-artifacts/MixinCurveV2.json';
|
||||
import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json';
|
||||
import * as MixinDodoV2 from '../test/generated-artifacts/MixinDodoV2.json';
|
||||
import * as MixinGMX from '../test/generated-artifacts/MixinGMX.json';
|
||||
import * as MixinKyber from '../test/generated-artifacts/MixinKyber.json';
|
||||
import * as MixinKyberDmm from '../test/generated-artifacts/MixinKyberDmm.json';
|
||||
import * as MixinLido from '../test/generated-artifacts/MixinLido.json';
|
||||
import * as MixinMakerPSM from '../test/generated-artifacts/MixinMakerPSM.json';
|
||||
import * as MixinMooniswap from '../test/generated-artifacts/MixinMooniswap.json';
|
||||
import * as MixinMStable from '../test/generated-artifacts/MixinMStable.json';
|
||||
import * as MixinNerve from '../test/generated-artifacts/MixinNerve.json';
|
||||
import * as MixinOasis from '../test/generated-artifacts/MixinOasis.json';
|
||||
import * as MixinPlatypus from '../test/generated-artifacts/MixinPlatypus.json';
|
||||
import * as MixinShell from '../test/generated-artifacts/MixinShell.json';
|
||||
import * as MixinUniswap from '../test/generated-artifacts/MixinUniswap.json';
|
||||
@@ -318,7 +315,6 @@ export const artifacts = {
|
||||
MixinBalancerV2: MixinBalancerV2 as ContractArtifact,
|
||||
MixinBalancerV2Batch: MixinBalancerV2Batch as ContractArtifact,
|
||||
MixinBancor: MixinBancor as ContractArtifact,
|
||||
MixinCoFiX: MixinCoFiX as ContractArtifact,
|
||||
MixinCompound: MixinCompound as ContractArtifact,
|
||||
MixinCryptoCom: MixinCryptoCom as ContractArtifact,
|
||||
MixinCurve: MixinCurve as ContractArtifact,
|
||||
@@ -326,14 +322,12 @@ export const artifacts = {
|
||||
MixinDodo: MixinDodo as ContractArtifact,
|
||||
MixinDodoV2: MixinDodoV2 as ContractArtifact,
|
||||
MixinGMX: MixinGMX as ContractArtifact,
|
||||
MixinKyber: MixinKyber as ContractArtifact,
|
||||
MixinKyberDmm: MixinKyberDmm as ContractArtifact,
|
||||
MixinLido: MixinLido as ContractArtifact,
|
||||
MixinMStable: MixinMStable as ContractArtifact,
|
||||
MixinMakerPSM: MixinMakerPSM as ContractArtifact,
|
||||
MixinMooniswap: MixinMooniswap as ContractArtifact,
|
||||
MixinNerve: MixinNerve as ContractArtifact,
|
||||
MixinOasis: MixinOasis as ContractArtifact,
|
||||
MixinPlatypus: MixinPlatypus as ContractArtifact,
|
||||
MixinShell: MixinShell as ContractArtifact,
|
||||
MixinUniswap: MixinUniswap as ContractArtifact,
|
||||
|
@@ -16,6 +16,8 @@ import {
|
||||
FillQuoteTransformerSide as Side,
|
||||
LimitOrder,
|
||||
LimitOrderFields,
|
||||
OtcOrder,
|
||||
OtcOrderFields,
|
||||
RfqOrder,
|
||||
RfqOrderFields,
|
||||
Signature,
|
||||
@@ -26,10 +28,11 @@ import * as _ from 'lodash';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
import { TestFillQuoteTransformerBridgeContract } from '../generated-wrappers/test_fill_quote_transformer_bridge';
|
||||
import { getRandomLimitOrder, getRandomRfqOrder } from '../utils/orders';
|
||||
import { getRandomLimitOrder, getRandomRfqOrder, getRandomOtcOrder } from '../utils/orders';
|
||||
import {
|
||||
BridgeAdapterContract,
|
||||
FillQuoteTransformerContract,
|
||||
OtcOrdersFeatureContract,
|
||||
TestFillQuoteTransformerExchangeContract,
|
||||
TestFillQuoteTransformerHostContract,
|
||||
TestMintableERC20TokenContract,
|
||||
@@ -71,6 +74,15 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
||||
artifacts,
|
||||
NULL_ADDRESS,
|
||||
);
|
||||
const otcOrder = await OtcOrdersFeatureContract.deployFrom0xArtifactAsync(
|
||||
artifacts.OtcOrdersFeature,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
NULL_ADDRESS,
|
||||
NULL_ADDRESS, // weth
|
||||
);
|
||||
|
||||
transformer = await FillQuoteTransformerContract.deployFrom0xArtifactAsync(
|
||||
artifacts.FillQuoteTransformer,
|
||||
env.provider,
|
||||
@@ -78,6 +90,7 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
||||
artifacts,
|
||||
bridgeAdapter.address,
|
||||
exchange.address,
|
||||
otcOrder.address
|
||||
);
|
||||
host = await TestFillQuoteTransformerHostContract.deployFrom0xArtifactAsync(
|
||||
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 {
|
||||
return {
|
||||
// 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
|
||||
for (let i = 0; i < data.fillSequence.length; ++i) {
|
||||
const orderType = data.fillSequence[i];
|
||||
|
@@ -101,7 +101,6 @@ export * from '../test/generated-wrappers/mixin_balancer';
|
||||
export * from '../test/generated-wrappers/mixin_balancer_v2';
|
||||
export * from '../test/generated-wrappers/mixin_balancer_v2_batch';
|
||||
export * from '../test/generated-wrappers/mixin_bancor';
|
||||
export * from '../test/generated-wrappers/mixin_co_fi_x';
|
||||
export * from '../test/generated-wrappers/mixin_compound';
|
||||
export * from '../test/generated-wrappers/mixin_crypto_com';
|
||||
export * from '../test/generated-wrappers/mixin_curve';
|
||||
@@ -109,14 +108,12 @@ export * from '../test/generated-wrappers/mixin_curve_v2';
|
||||
export * from '../test/generated-wrappers/mixin_dodo';
|
||||
export * from '../test/generated-wrappers/mixin_dodo_v2';
|
||||
export * from '../test/generated-wrappers/mixin_g_m_x';
|
||||
export * from '../test/generated-wrappers/mixin_kyber';
|
||||
export * from '../test/generated-wrappers/mixin_kyber_dmm';
|
||||
export * from '../test/generated-wrappers/mixin_lido';
|
||||
export * from '../test/generated-wrappers/mixin_m_stable';
|
||||
export * from '../test/generated-wrappers/mixin_maker_p_s_m';
|
||||
export * from '../test/generated-wrappers/mixin_mooniswap';
|
||||
export * from '../test/generated-wrappers/mixin_nerve';
|
||||
export * from '../test/generated-wrappers/mixin_oasis';
|
||||
export * from '../test/generated-wrappers/mixin_platypus';
|
||||
export * from '../test/generated-wrappers/mixin_shell';
|
||||
export * from '../test/generated-wrappers/mixin_uniswap';
|
||||
|
@@ -134,7 +134,6 @@
|
||||
"test/generated-artifacts/MixinBalancerV2.json",
|
||||
"test/generated-artifacts/MixinBalancerV2Batch.json",
|
||||
"test/generated-artifacts/MixinBancor.json",
|
||||
"test/generated-artifacts/MixinCoFiX.json",
|
||||
"test/generated-artifacts/MixinCompound.json",
|
||||
"test/generated-artifacts/MixinCryptoCom.json",
|
||||
"test/generated-artifacts/MixinCurve.json",
|
||||
@@ -142,14 +141,12 @@
|
||||
"test/generated-artifacts/MixinDodo.json",
|
||||
"test/generated-artifacts/MixinDodoV2.json",
|
||||
"test/generated-artifacts/MixinGMX.json",
|
||||
"test/generated-artifacts/MixinKyber.json",
|
||||
"test/generated-artifacts/MixinKyberDmm.json",
|
||||
"test/generated-artifacts/MixinLido.json",
|
||||
"test/generated-artifacts/MixinMStable.json",
|
||||
"test/generated-artifacts/MixinMakerPSM.json",
|
||||
"test/generated-artifacts/MixinMooniswap.json",
|
||||
"test/generated-artifacts/MixinNerve.json",
|
||||
"test/generated-artifacts/MixinOasis.json",
|
||||
"test/generated-artifacts/MixinPlatypus.json",
|
||||
"test/generated-artifacts/MixinShell.json",
|
||||
"test/generated-artifacts/MixinUniswap.json",
|
||||
|
@@ -1,4 +1,23 @@
|
||||
[
|
||||
{
|
||||
"version": "16.61.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Offboard/clean up Oasis, CoFix, and legacy Kyber",
|
||||
"pr": 482
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "16.60.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Alias Balancer sor to the old version",
|
||||
"pr": 481
|
||||
}
|
||||
],
|
||||
"timestamp": 1652931596
|
||||
},
|
||||
{
|
||||
"version": "16.60.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v16.60.1 - _May 19, 2022_
|
||||
|
||||
* Alias Balancer sor to the old version (#481)
|
||||
|
||||
## v16.60.0 - _May 19, 2022_
|
||||
|
||||
* Add BiSwap on BSC (#467)
|
||||
|
@@ -29,7 +29,6 @@ import "./CurveSampler.sol";
|
||||
import "./DODOSampler.sol";
|
||||
import "./DODOV2Sampler.sol";
|
||||
import "./GMXSampler.sol";
|
||||
import "./KyberSampler.sol";
|
||||
import "./KyberDmmSampler.sol";
|
||||
import "./LidoSampler.sol";
|
||||
import "./LiquidityProviderSampler.sol";
|
||||
@@ -57,7 +56,6 @@ contract ERC20BridgeSampler is
|
||||
DODOSampler,
|
||||
DODOV2Sampler,
|
||||
GMXSampler,
|
||||
KyberSampler,
|
||||
KyberDmmSampler,
|
||||
LidoSampler,
|
||||
LiquidityProviderSampler,
|
||||
|
@@ -1,301 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2020 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./interfaces/IKyberNetwork.sol";
|
||||
import "./ApproximateBuys.sol";
|
||||
import "./SamplerUtils.sol";
|
||||
|
||||
|
||||
contract KyberSampler is
|
||||
SamplerUtils,
|
||||
ApproximateBuys
|
||||
{
|
||||
/// @dev Gas limit for Kyber calls.
|
||||
uint256 constant private KYBER_CALL_GAS = 500e3; // 500k
|
||||
/// @dev Kyber ETH pseudo-address.
|
||||
address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
|
||||
struct KyberSamplerOpts {
|
||||
uint256 reserveOffset;
|
||||
address hintHandler;
|
||||
address networkProxy;
|
||||
address weth;
|
||||
bytes hint;
|
||||
}
|
||||
|
||||
/// @dev Sample sell quotes from Kyber.
|
||||
/// @param opts KyberSamplerOpts The nth reserve
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return reserveId The id of the reserve found at reserveOffset
|
||||
/// @return hint The hint for the selected reserve
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token amount.
|
||||
function sampleSellsFromKyberNetwork(
|
||||
KyberSamplerOpts memory opts,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory takerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (bytes32 reserveId, bytes memory hint, uint256[] memory makerTokenAmounts)
|
||||
{
|
||||
_assertValidPair(makerToken, takerToken);
|
||||
reserveId = _getNextReserveId(opts, takerToken, makerToken);
|
||||
if (reserveId == 0x0) {
|
||||
return (reserveId, hint, makerTokenAmounts);
|
||||
}
|
||||
opts.hint = this.encodeKyberHint(opts, reserveId, takerToken, makerToken);
|
||||
hint = opts.hint;
|
||||
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
uint256 value = this.sampleSellFromKyberNetwork(
|
||||
opts,
|
||||
takerToken,
|
||||
makerToken,
|
||||
takerTokenAmounts[i]
|
||||
);
|
||||
makerTokenAmounts[i] = value;
|
||||
// Break early if there are 0 amounts
|
||||
if (makerTokenAmounts[i] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Sample buy quotes from Kyber.
|
||||
/// @param opts KyberSamplerOpts The nth reserve
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param makerTokenAmounts Maker token buy amount for each sample.
|
||||
/// @return reserveId The id of the reserve found at reserveOffset
|
||||
/// @return hint The hint for the selected reserve
|
||||
/// @return takerTokenAmounts Taker amounts sold at each maker token amount.
|
||||
function sampleBuysFromKyberNetwork(
|
||||
KyberSamplerOpts memory opts,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory makerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (bytes32 reserveId, bytes memory hint, uint256[] memory takerTokenAmounts)
|
||||
{
|
||||
_assertValidPair(makerToken, takerToken);
|
||||
|
||||
reserveId = _getNextReserveId(opts, takerToken, makerToken);
|
||||
if (reserveId == 0x0) {
|
||||
return (reserveId, hint, takerTokenAmounts);
|
||||
}
|
||||
opts.hint = this.encodeKyberHint(opts, reserveId, takerToken, makerToken);
|
||||
hint = opts.hint;
|
||||
|
||||
takerTokenAmounts = _sampleApproximateBuys(
|
||||
ApproximateBuyQuoteOpts({
|
||||
makerTokenData: abi.encode(makerToken, opts),
|
||||
takerTokenData: abi.encode(takerToken, opts),
|
||||
getSellQuoteCallback: _sampleSellForApproximateBuyFromKyber
|
||||
}),
|
||||
makerTokenAmounts
|
||||
);
|
||||
return (reserveId, hint, takerTokenAmounts);
|
||||
}
|
||||
|
||||
function encodeKyberHint(
|
||||
KyberSamplerOpts memory opts,
|
||||
bytes32 reserveId,
|
||||
address takerToken,
|
||||
address makerToken
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (bytes memory hint)
|
||||
{
|
||||
// Build a hint selecting the single reserve
|
||||
IKyberHintHandler kyberHint = IKyberHintHandler(opts.hintHandler);
|
||||
|
||||
// All other reserves should be ignored with this hint
|
||||
bytes32[] memory selectedReserves = new bytes32[](1);
|
||||
selectedReserves[0] = reserveId;
|
||||
uint256[] memory emptySplits = new uint256[](0);
|
||||
|
||||
if (takerToken == opts.weth) {
|
||||
// ETH to Token
|
||||
try
|
||||
kyberHint.buildEthToTokenHint
|
||||
{gas: KYBER_CALL_GAS}
|
||||
(
|
||||
makerToken,
|
||||
IKyberHintHandler.TradeType.MaskIn,
|
||||
selectedReserves,
|
||||
emptySplits
|
||||
)
|
||||
returns (bytes memory result)
|
||||
{
|
||||
return result;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
}
|
||||
} else if (makerToken == opts.weth) {
|
||||
// Token to ETH
|
||||
try
|
||||
kyberHint.buildTokenToEthHint
|
||||
{gas: KYBER_CALL_GAS}
|
||||
(
|
||||
takerToken,
|
||||
IKyberHintHandler.TradeType.MaskIn,
|
||||
selectedReserves,
|
||||
emptySplits
|
||||
)
|
||||
returns (bytes memory result)
|
||||
{
|
||||
return result;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
}
|
||||
|
||||
} else {
|
||||
// Token to Token
|
||||
// We use the same reserve both ways
|
||||
try
|
||||
kyberHint.buildTokenToTokenHint
|
||||
{gas: KYBER_CALL_GAS}
|
||||
(
|
||||
takerToken,
|
||||
IKyberHintHandler.TradeType.MaskIn,
|
||||
selectedReserves,
|
||||
emptySplits,
|
||||
makerToken,
|
||||
IKyberHintHandler.TradeType.MaskIn,
|
||||
selectedReserves,
|
||||
emptySplits
|
||||
)
|
||||
returns (bytes memory result)
|
||||
{
|
||||
return result;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _sampleSellForApproximateBuyFromKyber(
|
||||
bytes memory takerTokenData,
|
||||
bytes memory makerTokenData,
|
||||
uint256 sellAmount
|
||||
)
|
||||
private
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
(address makerToken, KyberSamplerOpts memory opts) =
|
||||
abi.decode(makerTokenData, (address, KyberSamplerOpts));
|
||||
(address takerToken, ) =
|
||||
abi.decode(takerTokenData, (address, KyberSamplerOpts));
|
||||
try
|
||||
this.sampleSellFromKyberNetwork
|
||||
(opts, takerToken, makerToken, sellAmount)
|
||||
returns (uint256 amount)
|
||||
{
|
||||
return amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function sampleSellFromKyberNetwork(
|
||||
KyberSamplerOpts memory opts,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256 takerTokenAmount
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256 makerTokenAmount)
|
||||
{
|
||||
// If there is no hint do not continue
|
||||
if (opts.hint.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
try
|
||||
IKyberNetworkProxy(opts.networkProxy).getExpectedRateAfterFee
|
||||
{gas: KYBER_CALL_GAS}
|
||||
(
|
||||
takerToken == opts.weth ? KYBER_ETH_ADDRESS : takerToken,
|
||||
makerToken == opts.weth ? KYBER_ETH_ADDRESS : makerToken,
|
||||
takerTokenAmount,
|
||||
0, // fee
|
||||
opts.hint
|
||||
)
|
||||
returns (uint256 rate)
|
||||
{
|
||||
uint256 makerTokenDecimals = _getTokenDecimals(makerToken);
|
||||
uint256 takerTokenDecimals = _getTokenDecimals(takerToken);
|
||||
makerTokenAmount =
|
||||
rate *
|
||||
takerTokenAmount *
|
||||
10 ** makerTokenDecimals /
|
||||
10 ** takerTokenDecimals /
|
||||
10 ** 18;
|
||||
return makerTokenAmount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function _getNextReserveId(
|
||||
KyberSamplerOpts memory opts,
|
||||
address takerToken,
|
||||
address makerToken
|
||||
)
|
||||
internal
|
||||
view
|
||||
returns (bytes32 reserveId)
|
||||
{
|
||||
// Fetch the registered reserves for this pair
|
||||
IKyberHintHandler kyberHint = IKyberHintHandler(opts.hintHandler);
|
||||
(bytes32[] memory reserveIds, ,) = kyberHint.getTradingReserves(
|
||||
takerToken == opts.weth ? KYBER_ETH_ADDRESS : takerToken,
|
||||
makerToken == opts.weth ? KYBER_ETH_ADDRESS : makerToken,
|
||||
true,
|
||||
new bytes(0) // empty hint
|
||||
);
|
||||
|
||||
if (opts.reserveOffset >= reserveIds.length) {
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
reserveId = reserveIds[opts.reserveOffset];
|
||||
// Ignore Kyber Bridged Reserves (0xbb)
|
||||
if (uint256(reserveId >> 248) == 0xbb) {
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
return reserveId;
|
||||
}
|
||||
}
|
@@ -1,96 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2020 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6;
|
||||
|
||||
// Keepin everything together
|
||||
interface IKyberNetwork {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface IKyberNetworkProxy {
|
||||
|
||||
function getExpectedRateAfterFee(
|
||||
address src,
|
||||
address dest,
|
||||
uint256 srcQty,
|
||||
uint256 platformFeeBps,
|
||||
bytes calldata hint
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256 expectedRate);
|
||||
}
|
||||
|
||||
interface IKyberHintHandler {
|
||||
|
||||
enum TradeType {BestOfAll, MaskIn, MaskOut, Split}
|
||||
|
||||
enum ProcessWithRate {NotRequired, Required}
|
||||
|
||||
function getTradingReserves(
|
||||
address tokenSrc,
|
||||
address tokenDest,
|
||||
bool isTokenToToken,
|
||||
bytes calldata hint
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
bytes32[] memory reserveIds,
|
||||
uint256[] memory splitValuesBps,
|
||||
ProcessWithRate processWithRate
|
||||
);
|
||||
|
||||
function buildTokenToEthHint(
|
||||
address tokenSrc,
|
||||
TradeType tokenToEthType,
|
||||
bytes32[] calldata tokenToEthReserveIds,
|
||||
uint256[] calldata tokenToEthSplits
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bytes memory hint);
|
||||
|
||||
function buildEthToTokenHint(
|
||||
address tokenDest,
|
||||
TradeType ethToTokenType,
|
||||
bytes32[] calldata ethToTokenReserveIds,
|
||||
uint256[] calldata ethToTokenSplits
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bytes memory hint);
|
||||
|
||||
function buildTokenToTokenHint(
|
||||
address tokenSrc,
|
||||
TradeType tokenToEthType,
|
||||
bytes32[] calldata tokenToEthReserveIds,
|
||||
uint256[] calldata tokenToEthSplits,
|
||||
address tokenDest,
|
||||
TradeType ethToTokenType,
|
||||
bytes32[] calldata ethToTokenReserveIds,
|
||||
uint256[] calldata ethToTokenSplits
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bytes memory hint);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/asset-swapper",
|
||||
"version": "16.60.0",
|
||||
"version": "16.60.1",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -39,7 +39,7 @@
|
||||
"config": {
|
||||
"publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2BatchSampler|BalancerV2Common|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|ERC20BridgeSampler|FakeTaker|GMXSampler|IBalancer|IBalancerV2Vault|IBancor|ICurve|IGMX|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IPlatypus|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|PlatypusSampler|SamplerUtils|ShellSampler|SmoothySampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
|
||||
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2BatchSampler|BalancerV2Common|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|ERC20BridgeSampler|FakeTaker|GMXSampler|IBalancer|IBalancerV2Vault|IBancor|ICurve|IGMX|IMStable|IMooniswap|IMultiBridge|IPlatypus|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|PlatypusSampler|SamplerUtils|ShellSampler|SmoothySampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
|
||||
"postpublish": {
|
||||
"assets": []
|
||||
}
|
||||
@@ -60,9 +60,10 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.34",
|
||||
"@0x/base-contract": "^6.5.0",
|
||||
"@0x/contract-addresses": "^6.14.0",
|
||||
"@0x/contract-wrappers": "^13.20.2",
|
||||
"@0x/contracts-erc20": "^3.3.30",
|
||||
"@0x/contract-addresses": "^6.16.0",
|
||||
"@0x/contract-wrappers": "^13.20.4",
|
||||
"@0x/contracts-erc20": "^3.3.32",
|
||||
"@0x/contracts-test-utils": "^5.4.23",
|
||||
"@0x/contracts-zero-ex": "^0.33.0",
|
||||
"@0x/dev-utils": "^4.2.14",
|
||||
"@0x/json-schemas": "^6.4.4",
|
||||
@@ -73,8 +74,7 @@
|
||||
"@0x/typescript-typings": "^5.3.1",
|
||||
"@0x/utils": "^6.5.3",
|
||||
"@0x/web3-wrapper": "^7.6.5",
|
||||
"@balancer-labs/sdk": "^0.1.6",
|
||||
"@balancer-labs/sor": "0.3.2",
|
||||
"@balancer-labs/sdk": "0.1.6",
|
||||
"@bancor/sdk": "0.2.9",
|
||||
"@ethersproject/abi": "^5.0.1",
|
||||
"@ethersproject/address": "^5.0.1",
|
||||
@@ -83,6 +83,7 @@
|
||||
"@ethersproject/strings": "^5.0.10",
|
||||
"axios": "^0.21.1",
|
||||
"axios-mock-adapter": "^1.19.0",
|
||||
"balancer-labs-sor-v1": "npm:@balancer-labs/sor@0.3.2",
|
||||
"cream-sor": "^0.3.3",
|
||||
"decimal.js": "^10.2.0",
|
||||
"ethereum-types": "^3.7.0",
|
||||
@@ -91,8 +92,7 @@
|
||||
"graphql": "^15.4.0",
|
||||
"graphql-request": "^3.4.0",
|
||||
"heartbeats": "^5.0.1",
|
||||
"lodash": "^4.17.11",
|
||||
"sorV2": "npm:@balancer-labs/sor"
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.8.0",
|
||||
|
@@ -153,7 +153,6 @@ export {
|
||||
Fill,
|
||||
FillData,
|
||||
GetMarketOrdersRfqOpts,
|
||||
KyberFillData,
|
||||
LiquidityProviderFillData,
|
||||
LiquidityProviderRegistry,
|
||||
MarketDepth,
|
||||
|
@@ -42,6 +42,7 @@ import {
|
||||
FinalUniswapV3FillData,
|
||||
LiquidityProviderFillData,
|
||||
MooniswapFillData,
|
||||
NativeOtcOrderFillData,
|
||||
NativeRfqOrderFillData,
|
||||
OptimizedMarketBridgeOrder,
|
||||
OptimizedMarketOrder,
|
||||
@@ -377,7 +378,66 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
||||
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)) {
|
||||
return {
|
||||
calldataHexString: this._encodeMultiplexBatchFillCalldata(
|
||||
|
@@ -5,6 +5,7 @@ import {
|
||||
LimitOrderFields,
|
||||
RfqOrder,
|
||||
RfqOrderFields,
|
||||
OtcOrderFields,
|
||||
Signature,
|
||||
} from '@0x/protocol-utils';
|
||||
import { TakerRequestQueryParamsUnnested, V4SignedRfqOrder } from '@0x/quote-server';
|
||||
@@ -34,11 +35,11 @@ export interface OrderPrunerOpts {
|
||||
|
||||
export interface SignedOrder<T> {
|
||||
order: T;
|
||||
type: FillQuoteTransformerOrderType.Limit | FillQuoteTransformerOrderType.Rfq;
|
||||
type: FillQuoteTransformerOrderType.Limit | FillQuoteTransformerOrderType.Rfq | FillQuoteTransformerOrderType.Otc;
|
||||
signature: Signature;
|
||||
}
|
||||
|
||||
export type SignedNativeOrder = SignedOrder<LimitOrderFields> | SignedOrder<RfqOrderFields>;
|
||||
export type SignedNativeOrder = SignedOrder<LimitOrderFields> | SignedOrder<RfqOrderFields> | SignedOrder<OtcOrderFields>;
|
||||
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 { AltRfqMakerAssetOfferings } from '../types';
|
||||
@@ -43,6 +43,48 @@ export interface RfqClientV1QuoteResponse {
|
||||
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.
|
||||
*/
|
||||
@@ -56,4 +98,14 @@ export interface IRfqClient {
|
||||
* Fetches a list of "firm quotes" or signed quotes from a remote Rfq server.
|
||||
*/
|
||||
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>;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { ChainId } from '@0x/contract-addresses';
|
||||
import { BigNumber, NULL_BYTES } from '@0x/utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import {
|
||||
ACRYPTOS_BSC_INFOS,
|
||||
@@ -28,10 +28,7 @@ import {
|
||||
IRONSWAP_POLYGON_INFOS,
|
||||
JETSWAP_ROUTER_BY_CHAIN_ID,
|
||||
JULSWAP_ROUTER_BY_CHAIN_ID,
|
||||
KYBER_BANNED_RESERVES,
|
||||
KYBER_BRIDGED_LIQUIDITY_PREFIX,
|
||||
MAX_DODOV2_POOLS_QUERIED,
|
||||
MAX_KYBER_RESERVES_QUERIED,
|
||||
MOBIUSMONEY_CELO_INFOS,
|
||||
MORPHEUSSWAP_ROUTER_BY_CHAIN_ID,
|
||||
MSTABLE_POOLS_BY_CHAIN_ID,
|
||||
@@ -66,32 +63,11 @@ import {
|
||||
} from './constants';
|
||||
import { CurveInfo, ERC20BridgeSource, PlatypusInfo } from './types';
|
||||
|
||||
/**
|
||||
* Filter Kyber reserves which should not be used (0xbb bridged reserves)
|
||||
* @param reserveId Kyber reserveId
|
||||
*/
|
||||
export function isAllowedKyberReserveId(reserveId: string): boolean {
|
||||
return (
|
||||
reserveId !== NULL_BYTES &&
|
||||
!reserveId.startsWith(KYBER_BRIDGED_LIQUIDITY_PREFIX) &&
|
||||
!KYBER_BANNED_RESERVES.includes(reserveId)
|
||||
);
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: completed-docs ban-types
|
||||
export function isValidAddress(address: string | String): address is string {
|
||||
return (typeof address === 'string' || address instanceof String) && address.toString() !== NULL_ADDRESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offsets to be used to discover Kyber reserves
|
||||
*/
|
||||
export function getKyberOffsets(): BigNumber[] {
|
||||
return Array(MAX_KYBER_RESERVES_QUERIED)
|
||||
.fill(0)
|
||||
.map((_v, i) => new BigNumber(i));
|
||||
}
|
||||
|
||||
// tslint:disable completed-docs
|
||||
export function getDodoV2Offsets(): BigNumber[] {
|
||||
return Array(MAX_DODOV2_POOLS_QUERIED)
|
||||
|
@@ -22,7 +22,6 @@ import {
|
||||
GeistFillData,
|
||||
GetMarketOrdersOpts,
|
||||
isFinalUniswapV3FillData,
|
||||
KyberSamplerOpts,
|
||||
LidoInfo,
|
||||
LiquidityProviderFillData,
|
||||
LiquidityProviderRegistry,
|
||||
@@ -80,7 +79,6 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
ERC20BridgeSource.UniswapV2,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Curve,
|
||||
ERC20BridgeSource.Balancer,
|
||||
ERC20BridgeSource.BalancerV2,
|
||||
@@ -111,7 +109,6 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
||||
// ERC20BridgeSource.Compound,
|
||||
]),
|
||||
[ChainId.Ropsten]: new SourceFilters([
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
@@ -226,7 +223,6 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
ERC20BridgeSource.UniswapV2,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Curve,
|
||||
ERC20BridgeSource.Balancer,
|
||||
ERC20BridgeSource.BalancerV2,
|
||||
@@ -257,7 +253,6 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
||||
// ERC20BridgeSource.Compound,
|
||||
]),
|
||||
[ChainId.Ropsten]: new SourceFilters([
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
@@ -646,6 +641,7 @@ export const OPTIMISM_TOKENS = {
|
||||
WBTC: '0x68f180fcce6836688e9084f035309e29bf0a2095',
|
||||
nETH: '0x809dc529f07651bd43a172e8db6f4a7a0d771036',
|
||||
sWETH: '0x121ab82b49b2bc4c7901ca46b8277962b4350204',
|
||||
nUSD: '0x67C10C397dD0Ba417329543c1a40eb48AAa7cd00',
|
||||
};
|
||||
|
||||
export const CURVE_POOLS = {
|
||||
@@ -775,6 +771,7 @@ export const SYNAPSE_MAINNET_POOLS = {
|
||||
|
||||
export const SYNAPSE_OPTIMISM_POOLS = {
|
||||
nETHLP: '0xe27bff97ce92c3e1ff7aa9f86781fdd6d48f5ee9',
|
||||
nUSDLP: '0xF44938b0125A6662f9536281aD2CD6c499F22004',
|
||||
};
|
||||
|
||||
export const SYNAPSE_BSC_POOLS = {
|
||||
@@ -788,6 +785,7 @@ export const SYNAPSE_POLYGON_POOLS = {
|
||||
export const SYNAPSE_FANTOM_POOLS = {
|
||||
nUSDLP: '0x2913e812cf0dcca30fb28e6cac3d2dcff4497688',
|
||||
nETHLP: '0x8d9ba570d6cb60c7e3e0f31343efe75ab8e65fb1',
|
||||
fUSDTLP: '0x85662fd123280827e11c59973ac9fcbe838dc3b4',
|
||||
};
|
||||
|
||||
export const SYNAPSE_AVALANCHE_POOLS = {
|
||||
@@ -1659,6 +1657,24 @@ export const SYNAPSE_FANTOM_INFOS: { [name: string]: CurveInfo } = {
|
||||
metaTokens: undefined,
|
||||
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 } = {
|
||||
@@ -1683,6 +1699,15 @@ export const SYNAPSE_OPTIMISM_INFOS: { [name: string]: CurveInfo } = {
|
||||
metaTokens: undefined,
|
||||
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 } = {
|
||||
@@ -1847,35 +1872,6 @@ export const PLATYPUS_AVALANCHE_INFOS: { [name: string]: PlatypusInfo } = {
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Kyber reserve prefixes
|
||||
* 0xff Fed price reserve
|
||||
* 0xaa Automated price reserve
|
||||
* 0xbb Bridged price reserve (i.e Uniswap/Curve)
|
||||
*/
|
||||
export const KYBER_BRIDGED_LIQUIDITY_PREFIX = '0xbb';
|
||||
export const KYBER_BANNED_RESERVES = ['0xff4f6e65426974205175616e7400000000000000000000000000000000000000'];
|
||||
export const MAX_KYBER_RESERVES_QUERIED = 5;
|
||||
export const KYBER_CONFIG_BY_CHAIN_ID = valueByChainId<KyberSamplerOpts>(
|
||||
{
|
||||
[ChainId.Mainnet]: {
|
||||
networkProxy: '0x9aab3f75489902f3a48495025729a0af77d4b11e',
|
||||
hintHandler: '0xa1C0Fa73c39CFBcC11ec9Eb1Afc665aba9996E2C',
|
||||
weth: MAINNET_TOKENS.WETH,
|
||||
},
|
||||
[ChainId.Ropsten]: {
|
||||
networkProxy: '0x818e6fecd516ecc3849daf6845e3ec868087b755',
|
||||
hintHandler: '0x63f773c026093eef988e803bdd5772dd235a8e71',
|
||||
weth: getContractAddressesForChainOrThrow(ChainId.Ropsten).etherToken,
|
||||
},
|
||||
},
|
||||
{
|
||||
networkProxy: NULL_ADDRESS,
|
||||
hintHandler: NULL_ADDRESS,
|
||||
weth: NULL_ADDRESS,
|
||||
},
|
||||
);
|
||||
|
||||
export const LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID = valueByChainId<LiquidityProviderRegistry>(
|
||||
{
|
||||
[ChainId.Mainnet]: {
|
||||
@@ -1980,13 +1976,6 @@ export const MSTABLE_POOLS_BY_CHAIN_ID = valueByChainId(
|
||||
},
|
||||
);
|
||||
|
||||
export const OASIS_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
||||
{
|
||||
[ChainId.Mainnet]: '0x5e3e0548935a83ad29fb2a9153d331dc6d49020f',
|
||||
},
|
||||
NULL_ADDRESS,
|
||||
);
|
||||
|
||||
export const KYBER_DMM_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
||||
{
|
||||
[ChainId.Mainnet]: '0x1c87257f5e8609940bc751a07bb085bb7f8cdbe6',
|
||||
@@ -2471,7 +2460,6 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
|
||||
[ERC20BridgeSource.LiquidityProvider]: fillData => {
|
||||
return (fillData as LiquidityProviderFillData).gasCost || 100e3;
|
||||
},
|
||||
[ERC20BridgeSource.Kyber]: () => 450e3,
|
||||
[ERC20BridgeSource.Curve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||
[ERC20BridgeSource.CurveV2]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||
[ERC20BridgeSource.Nerve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||
|
@@ -747,6 +747,26 @@ export class MarketOperationUtils {
|
||||
wholeOrderPrice,
|
||||
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;
|
||||
DEFAULT_INFO_LOGGER({
|
||||
rfqQuoteType: 'firm',
|
||||
@@ -777,6 +797,7 @@ export class MarketOperationUtils {
|
||||
);
|
||||
marketSideLiquidity.quotes.nativeOrders = [
|
||||
...quotesWithOrderFillableAmounts,
|
||||
...otcQuotesWithFillableAmounts,
|
||||
...marketSideLiquidity.quotes.nativeOrders,
|
||||
];
|
||||
|
||||
|
@@ -23,7 +23,6 @@ import {
|
||||
GenericRouterFillData,
|
||||
GMXFillData,
|
||||
KyberDmmFillData,
|
||||
KyberFillData,
|
||||
LidoFillData,
|
||||
LiquidityProviderFillData,
|
||||
MakerPsmFillData,
|
||||
@@ -92,8 +91,6 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
|
||||
return encodeBridgeSourceId(BridgeProtocol.BalancerV2Batch, 'BalancerV2');
|
||||
case ERC20BridgeSource.Bancor:
|
||||
return encodeBridgeSourceId(BridgeProtocol.Bancor, 'Bancor');
|
||||
// case ERC20BridgeSource.CoFiX:
|
||||
// return encodeBridgeSourceId(BridgeProtocol.CoFiX, 'CoFiX');
|
||||
case ERC20BridgeSource.Curve:
|
||||
return encodeBridgeSourceId(BridgeProtocol.Curve, 'Curve');
|
||||
case ERC20BridgeSource.Cream:
|
||||
@@ -102,8 +99,6 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
|
||||
return encodeBridgeSourceId(BridgeProtocol.CryptoCom, 'CryptoCom');
|
||||
case ERC20BridgeSource.Dodo:
|
||||
return encodeBridgeSourceId(BridgeProtocol.Dodo, 'Dodo');
|
||||
case ERC20BridgeSource.Kyber:
|
||||
return encodeBridgeSourceId(BridgeProtocol.Kyber, 'Kyber');
|
||||
case ERC20BridgeSource.LiquidityProvider:
|
||||
// "LiquidityProvider" is too long to encode (17 characters).
|
||||
return encodeBridgeSourceId(BridgeProtocol.Unknown, 'LP');
|
||||
@@ -305,10 +300,6 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
|
||||
const uniswapV2FillData = (order as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
|
||||
bridgeData = encoder.encode([uniswapV2FillData.router, uniswapV2FillData.tokenAddressPath]);
|
||||
break;
|
||||
case ERC20BridgeSource.Kyber:
|
||||
const kyberFillData = (order as OptimizedMarketBridgeOrder<KyberFillData>).fillData;
|
||||
bridgeData = encoder.encode([kyberFillData.networkProxy, kyberFillData.hint]);
|
||||
break;
|
||||
case ERC20BridgeSource.Mooniswap:
|
||||
const mooniswapFillData = (order as OptimizedMarketBridgeOrder<MooniswapFillData>).fillData;
|
||||
bridgeData = encoder.encode([mooniswapFillData.poolAddress]);
|
||||
@@ -490,10 +481,6 @@ export const BRIDGE_ENCODERS: {
|
||||
{ name: 'provider', type: 'address' },
|
||||
{ name: 'data', type: 'bytes' },
|
||||
]),
|
||||
[ERC20BridgeSource.Kyber]: AbiEncoder.create([
|
||||
{ name: 'kyberNetworkProxy', type: 'address' },
|
||||
{ name: 'hint', type: 'bytes' },
|
||||
]),
|
||||
[ERC20BridgeSource.Dodo]: AbiEncoder.create([
|
||||
{ name: 'helper', type: 'address' },
|
||||
{ name: 'poolAddress', type: 'address' },
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { getPoolsWithTokens, parsePoolData } from '@balancer-labs/sor';
|
||||
import { Pool } from '@balancer-labs/sor/dist/types';
|
||||
import { getPoolsWithTokens, parsePoolData } from 'balancer-labs-sor-v1';
|
||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
|
||||
import { gql, request } from 'graphql-request';
|
||||
|
||||
import { BALANCER_MAX_POOLS_FETCHED, BALANCER_SUBGRAPH_URL, BALANCER_TOP_POOLS_FETCHED } from '../constants';
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { ChainId } from '@0x/contract-addresses';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
// import { parsePoolData } from '@balancer-labs'; // TODO - upgrade to v2
|
||||
import { Pool } from '@balancer-labs/sor/dist/types';
|
||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
|
||||
import { gql, request } from 'graphql-request';
|
||||
|
||||
import { DEFAULT_WARNING_LOGGER } from '../../../constants';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Pool } from '@balancer-labs/sor/dist/types';
|
||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
|
||||
import { getPoolsWithTokens, parsePoolData } from 'cream-sor';
|
||||
|
||||
import { BALANCER_MAX_POOLS_FETCHED } from '../constants';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Pool } from '@balancer-labs/sor/dist/types';
|
||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
|
||||
|
||||
import { ONE_HOUR_IN_SECONDS, ONE_SECOND_MS } from '../constants';
|
||||
export { Pool };
|
||||
|
@@ -13,10 +13,8 @@ import { BancorService } from './bancor_service';
|
||||
import {
|
||||
getCurveLikeInfosForPair,
|
||||
getDodoV2Offsets,
|
||||
getKyberOffsets,
|
||||
getPlatypusInfoForPair,
|
||||
getShellLikeInfosForPair,
|
||||
isAllowedKyberReserveId,
|
||||
isBadTokenForSource,
|
||||
isValidAddress,
|
||||
uniswapV2LikeRouterAddress,
|
||||
@@ -35,7 +33,6 @@ import {
|
||||
GMX_READER_BY_CHAIN_ID,
|
||||
GMX_ROUTER_BY_CHAIN_ID,
|
||||
GMX_VAULT_BY_CHAIN_ID,
|
||||
KYBER_CONFIG_BY_CHAIN_ID,
|
||||
KYBER_DMM_ROUTER_BY_CHAIN_ID,
|
||||
LIDO_INFO_BY_CHAIN,
|
||||
LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID,
|
||||
@@ -44,7 +41,6 @@ import {
|
||||
MOONISWAP_REGISTRIES_BY_CHAIN_ID,
|
||||
NATIVE_FEE_TOKEN_BY_CHAIN_ID,
|
||||
NULL_ADDRESS,
|
||||
NULL_BYTES,
|
||||
PLATYPUS_ROUTER_BY_CHAIN_ID,
|
||||
SELL_SOURCE_FILTER_BY_CHAIN_ID,
|
||||
UNISWAPV1_ROUTER_BY_CHAIN_ID,
|
||||
@@ -81,8 +77,6 @@ import {
|
||||
GMXFillData,
|
||||
HopInfo,
|
||||
KyberDmmFillData,
|
||||
KyberFillData,
|
||||
KyberSamplerOpts,
|
||||
LidoFillData,
|
||||
LidoInfo,
|
||||
LiquidityProviderFillData,
|
||||
@@ -266,54 +260,6 @@ export class SamplerOperations {
|
||||
});
|
||||
}
|
||||
|
||||
public getKyberSellQuotes(
|
||||
kyberOpts: KyberSamplerOpts,
|
||||
reserveOffset: BigNumber,
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
takerFillAmounts: BigNumber[],
|
||||
): SourceQuoteOperation {
|
||||
return new SamplerContractOperation({
|
||||
source: ERC20BridgeSource.Kyber,
|
||||
contract: this._samplerContract,
|
||||
function: this._samplerContract.sampleSellsFromKyberNetwork,
|
||||
params: [{ ...kyberOpts, reserveOffset, hint: NULL_BYTES }, takerToken, makerToken, takerFillAmounts],
|
||||
callback: (callResults: string, fillData: KyberFillData): BigNumber[] => {
|
||||
const [reserveId, hint, samples] = this._samplerContract.getABIDecodedReturnData<
|
||||
[string, string, BigNumber[]]
|
||||
>('sampleSellsFromKyberNetwork', callResults);
|
||||
fillData.hint = hint;
|
||||
fillData.reserveId = reserveId;
|
||||
fillData.networkProxy = kyberOpts.networkProxy;
|
||||
return isAllowedKyberReserveId(reserveId) ? samples : [];
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public getKyberBuyQuotes(
|
||||
kyberOpts: KyberSamplerOpts,
|
||||
reserveOffset: BigNumber,
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
makerFillAmounts: BigNumber[],
|
||||
): SourceQuoteOperation {
|
||||
return new SamplerContractOperation({
|
||||
source: ERC20BridgeSource.Kyber,
|
||||
contract: this._samplerContract,
|
||||
function: this._samplerContract.sampleBuysFromKyberNetwork,
|
||||
params: [{ ...kyberOpts, reserveOffset, hint: NULL_BYTES }, takerToken, makerToken, makerFillAmounts],
|
||||
callback: (callResults: string, fillData: KyberFillData): BigNumber[] => {
|
||||
const [reserveId, hint, samples] = this._samplerContract.getABIDecodedReturnData<
|
||||
[string, string, BigNumber[]]
|
||||
>('sampleBuysFromKyberNetwork', callResults);
|
||||
fillData.hint = hint;
|
||||
fillData.reserveId = reserveId;
|
||||
fillData.networkProxy = kyberOpts.networkProxy;
|
||||
return isAllowedKyberReserveId(reserveId) ? samples : [];
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public getKyberDmmSellQuotes(
|
||||
router: string,
|
||||
tokenAddressPath: string[],
|
||||
@@ -1479,16 +1425,6 @@ export class SamplerOperations {
|
||||
return [];
|
||||
}
|
||||
return this.getKyberDmmSellQuotes(kyberDmmRouter, [takerToken, makerToken], takerFillAmounts);
|
||||
case ERC20BridgeSource.Kyber:
|
||||
return getKyberOffsets().map(offset =>
|
||||
this.getKyberSellQuotes(
|
||||
KYBER_CONFIG_BY_CHAIN_ID[this.chainId],
|
||||
offset,
|
||||
makerToken,
|
||||
takerToken,
|
||||
takerFillAmounts,
|
||||
),
|
||||
);
|
||||
case ERC20BridgeSource.Curve:
|
||||
case ERC20BridgeSource.CurveV2:
|
||||
case ERC20BridgeSource.Nerve:
|
||||
@@ -1810,16 +1746,6 @@ export class SamplerOperations {
|
||||
return [];
|
||||
}
|
||||
return this.getKyberDmmBuyQuotes(kyberDmmRouter, [takerToken, makerToken], makerFillAmounts);
|
||||
case ERC20BridgeSource.Kyber:
|
||||
return getKyberOffsets().map(offset =>
|
||||
this.getKyberBuyQuotes(
|
||||
KYBER_CONFIG_BY_CHAIN_ID[this.chainId],
|
||||
offset,
|
||||
makerToken,
|
||||
takerToken,
|
||||
makerFillAmounts,
|
||||
),
|
||||
);
|
||||
case ERC20BridgeSource.Curve:
|
||||
case ERC20BridgeSource.CurveV2:
|
||||
case ERC20BridgeSource.Nerve:
|
||||
|
@@ -2,6 +2,7 @@ import {
|
||||
FillQuoteTransformerLimitOrderInfo,
|
||||
FillQuoteTransformerOrderType,
|
||||
FillQuoteTransformerRfqOrderInfo,
|
||||
FillQuoteTransformerOtcOrderInfo
|
||||
} from '@0x/protocol-utils';
|
||||
import { MarketOperation } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
@@ -38,7 +39,6 @@ export enum ERC20BridgeSource {
|
||||
Native = 'Native',
|
||||
Uniswap = 'Uniswap',
|
||||
UniswapV2 = 'Uniswap_V2',
|
||||
Kyber = 'Kyber',
|
||||
Curve = 'Curve',
|
||||
LiquidityProvider = 'LiquidityProvider',
|
||||
MultiBridge = 'MultiBridge',
|
||||
@@ -196,7 +196,9 @@ export interface FillData {}
|
||||
// `FillData` for native fills. Represents a single native order
|
||||
export type NativeRfqOrderFillData = FillQuoteTransformerRfqOrderInfo;
|
||||
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
|
||||
export interface DexSample<TFillData extends FillData = FillData> {
|
||||
@@ -262,12 +264,6 @@ export interface BancorFillData extends FillData {
|
||||
networkAddress: string;
|
||||
}
|
||||
|
||||
export interface KyberFillData extends FillData {
|
||||
hint: string;
|
||||
reserveId: string;
|
||||
networkProxy: string;
|
||||
}
|
||||
|
||||
export interface MooniswapFillData extends FillData {
|
||||
poolAddress: string;
|
||||
}
|
||||
@@ -461,13 +457,19 @@ export interface OptimizedRfqOrder extends OptimizedMarketOrderBase<NativeRfqOrd
|
||||
fillData: NativeRfqOrderFillData;
|
||||
}
|
||||
|
||||
export interface OptimizedOtcOrder extends OptimizedMarketOrderBase<NativeOtcOrderFillData> {
|
||||
type: FillQuoteTransformerOrderType.Otc;
|
||||
fillData: NativeOtcOrderFillData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized orders to fill.
|
||||
*/
|
||||
export type OptimizedMarketOrder =
|
||||
| OptimizedMarketBridgeOrder<FillData>
|
||||
| OptimizedMarketOrderBase<NativeLimitOrderFillData>
|
||||
| OptimizedMarketOrderBase<NativeRfqOrderFillData>;
|
||||
| OptimizedMarketOrderBase<NativeRfqOrderFillData>
|
||||
| OptimizedMarketOrderBase<NativeOtcOrderFillData>;
|
||||
|
||||
export interface GetMarketOrdersRfqOpts extends RfqRequestOpts {
|
||||
rfqClient?: IRfqClient;
|
||||
@@ -693,9 +695,3 @@ export interface GenerateOptimizedOrdersOpts {
|
||||
export interface ComparisonPrice {
|
||||
wholeOrder: BigNumber | undefined;
|
||||
}
|
||||
|
||||
export interface KyberSamplerOpts {
|
||||
networkProxy: string;
|
||||
hintHandler: string;
|
||||
weth: string;
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ import {
|
||||
NativeCollapsedFill,
|
||||
NativeFillData,
|
||||
NativeLimitOrderFillData,
|
||||
NativeOtcOrderFillData,
|
||||
NativeRfqOrderFillData,
|
||||
RawQuotes,
|
||||
} from './market_operation_utils/types';
|
||||
@@ -353,7 +354,7 @@ function _isNativeOrderFromCollapsedFill(cf: CollapsedFill): cf is NativeCollaps
|
||||
*/
|
||||
export function nativeOrderToReportEntry(
|
||||
type: FillQuoteTransformerOrderType,
|
||||
fillData: NativeLimitOrderFillData | NativeRfqOrderFillData,
|
||||
fillData: NativeLimitOrderFillData | NativeRfqOrderFillData | NativeOtcOrderFillData,
|
||||
fillableAmount: BigNumber,
|
||||
comparisonPrice?: BigNumber | undefined,
|
||||
quoteRequestor?: QuoteRequestor,
|
||||
|
@@ -24,7 +24,6 @@ import * as IBalancerV2Vault from '../test/generated-artifacts/IBalancerV2Vault.
|
||||
import * as IBancor from '../test/generated-artifacts/IBancor.json';
|
||||
import * as ICurve from '../test/generated-artifacts/ICurve.json';
|
||||
import * as IGMX from '../test/generated-artifacts/IGMX.json';
|
||||
import * as IKyberNetwork from '../test/generated-artifacts/IKyberNetwork.json';
|
||||
import * as IMooniswap from '../test/generated-artifacts/IMooniswap.json';
|
||||
import * as IMStable from '../test/generated-artifacts/IMStable.json';
|
||||
import * as IMultiBridge from '../test/generated-artifacts/IMultiBridge.json';
|
||||
@@ -34,7 +33,6 @@ import * as ISmoothy from '../test/generated-artifacts/ISmoothy.json';
|
||||
import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExchangeQuotes.json';
|
||||
import * as IUniswapV2Router01 from '../test/generated-artifacts/IUniswapV2Router01.json';
|
||||
import * as KyberDmmSampler from '../test/generated-artifacts/KyberDmmSampler.json';
|
||||
import * as KyberSampler from '../test/generated-artifacts/KyberSampler.json';
|
||||
import * as LidoSampler from '../test/generated-artifacts/LidoSampler.json';
|
||||
import * as LiquidityProviderSampler from '../test/generated-artifacts/LiquidityProviderSampler.json';
|
||||
import * as MakerPSMSampler from '../test/generated-artifacts/MakerPSMSampler.json';
|
||||
@@ -67,7 +65,6 @@ export const artifacts = {
|
||||
FakeTaker: FakeTaker as ContractArtifact,
|
||||
GMXSampler: GMXSampler as ContractArtifact,
|
||||
KyberDmmSampler: KyberDmmSampler as ContractArtifact,
|
||||
KyberSampler: KyberSampler as ContractArtifact,
|
||||
LidoSampler: LidoSampler as ContractArtifact,
|
||||
LiquidityProviderSampler: LiquidityProviderSampler as ContractArtifact,
|
||||
MStableSampler: MStableSampler as ContractArtifact,
|
||||
@@ -88,7 +85,6 @@ export const artifacts = {
|
||||
IBancor: IBancor as ContractArtifact,
|
||||
ICurve: ICurve as ContractArtifact,
|
||||
IGMX: IGMX as ContractArtifact,
|
||||
IKyberNetwork: IKyberNetwork as ContractArtifact,
|
||||
IMStable: IMStable as ContractArtifact,
|
||||
IMooniswap: IMooniswap as ContractArtifact,
|
||||
IMultiBridge: IMultiBridge as ContractArtifact,
|
||||
|
@@ -21,8 +21,8 @@ const GAS_PRICE = new BigNumber(50e9); // 50 gwei
|
||||
const NATIVE_ORDER_FEE = new BigNumber(220e3); // 220K gas
|
||||
|
||||
// DEX samples to fill in MarketSideLiquidity
|
||||
const kyberSample1: DexSample = {
|
||||
source: ERC20BridgeSource.Kyber,
|
||||
const curveSample: DexSample = {
|
||||
source: ERC20BridgeSource.Curve,
|
||||
input: new BigNumber(10000),
|
||||
output: new BigNumber(10001),
|
||||
fillData: {},
|
||||
@@ -33,7 +33,7 @@ const uniswapSample1: DexSample = {
|
||||
output: new BigNumber(10004),
|
||||
fillData: {},
|
||||
};
|
||||
const dexQuotes: DexSample[] = [kyberSample1, uniswapSample1];
|
||||
const dexQuotes: DexSample[] = [curveSample, uniswapSample1];
|
||||
|
||||
const feeSchedule = {
|
||||
[ERC20BridgeSource.Native]: _.constant(GAS_PRICE.times(NATIVE_ORDER_FEE)),
|
||||
|
@@ -1,9 +1,7 @@
|
||||
import { ChainId } from '@0x/contract-addresses';
|
||||
import { blockchainTests, describe, expect, toBaseUnitAmount, Web3ProviderEngine } from '@0x/contracts-test-utils';
|
||||
import { RPCSubprovider } from '@0x/subproviders';
|
||||
import { BigNumber, NULL_BYTES, providerUtils } from '@0x/utils';
|
||||
import { BigNumber, providerUtils } from '@0x/utils';
|
||||
|
||||
import { KYBER_CONFIG_BY_CHAIN_ID, MAINNET_TOKENS } from '../../src/utils/market_operation_utils/constants';
|
||||
import { artifacts } from '../artifacts';
|
||||
import { ERC20BridgeSamplerContract } from '../wrappers';
|
||||
|
||||
@@ -79,60 +77,4 @@ blockchainTests.skip('Mainnet Sampler Tests', env => {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('Kyber', () => {
|
||||
const WETH = MAINNET_TOKENS.WETH;
|
||||
const DAI = MAINNET_TOKENS.DAI;
|
||||
const USDC = MAINNET_TOKENS.USDC;
|
||||
const RESERVE_OFFSET = new BigNumber(0);
|
||||
const KYBER_OPTS = {
|
||||
...KYBER_CONFIG_BY_CHAIN_ID[ChainId.Mainnet],
|
||||
reserveOffset: RESERVE_OFFSET,
|
||||
hint: NULL_BYTES,
|
||||
};
|
||||
describe('sampleSellsFromKyberNetwork()', () => {
|
||||
it('samples sells from Kyber DAI->WETH', async () => {
|
||||
const [, samples] = await testContract
|
||||
.sampleSellsFromKyberNetwork(KYBER_OPTS, DAI, WETH, [toBaseUnitAmount(1)])
|
||||
.callAsync({ overrides });
|
||||
expect(samples.length).to.be.bignumber.greaterThan(0);
|
||||
expect(samples[0]).to.be.bignumber.greaterThan(0);
|
||||
});
|
||||
it('samples sells from Kyber WETH->DAI', async () => {
|
||||
const [, samples] = await testContract
|
||||
.sampleSellsFromKyberNetwork(KYBER_OPTS, WETH, DAI, [toBaseUnitAmount(1)])
|
||||
.callAsync({ overrides });
|
||||
expect(samples.length).to.be.bignumber.greaterThan(0);
|
||||
expect(samples[0]).to.be.bignumber.greaterThan(0);
|
||||
});
|
||||
it('samples sells from Kyber DAI->USDC', async () => {
|
||||
const [, samples] = await testContract
|
||||
.sampleSellsFromKyberNetwork(KYBER_OPTS, DAI, USDC, [toBaseUnitAmount(1)])
|
||||
.callAsync({ overrides });
|
||||
expect(samples.length).to.be.bignumber.greaterThan(0);
|
||||
expect(samples[0]).to.be.bignumber.greaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sampleBuysFromKyber()', () => {
|
||||
it('samples buys from Kyber WETH->DAI', async () => {
|
||||
// From ETH to DAI
|
||||
// I want to buy 1 DAI
|
||||
const [, samples] = await testContract
|
||||
.sampleBuysFromKyberNetwork(KYBER_OPTS, WETH, DAI, [toBaseUnitAmount(1)])
|
||||
.callAsync({ overrides });
|
||||
expect(samples.length).to.be.bignumber.greaterThan(0);
|
||||
expect(samples[0]).to.be.bignumber.greaterThan(0);
|
||||
});
|
||||
|
||||
it('samples buys from Kyber DAI->WETH', async () => {
|
||||
// From USDC to DAI
|
||||
// I want to buy 1 WETH
|
||||
const [, samples] = await testContract
|
||||
.sampleBuysFromKyberNetwork(KYBER_OPTS, DAI, WETH, [toBaseUnitAmount(1)])
|
||||
.callAsync({ overrides });
|
||||
expect(samples.length).to.be.bignumber.greaterThan(0);
|
||||
expect(samples[0]).to.be.bignumber.greaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -21,7 +21,7 @@ import { generatePseudoRandomSalt } from './utils/utils';
|
||||
const CHAIN_ID = 1;
|
||||
const EMPTY_BYTES32 = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
||||
// tslint:disable: custom-no-magic-numbers
|
||||
describe.skip('DexSampler tests', () => {
|
||||
describe('DexSampler tests', () => {
|
||||
const MAKER_TOKEN = randomAddress();
|
||||
const TAKER_TOKEN = randomAddress();
|
||||
const chainId = ChainId.Mainnet;
|
||||
@@ -142,40 +142,6 @@ describe.skip('DexSampler tests', () => {
|
||||
expect(fillableAmounts).to.deep.eq(expectedFillableAmounts);
|
||||
});
|
||||
|
||||
it('getKyberSellQuotes()', async () => {
|
||||
const expectedTakerToken = randomAddress();
|
||||
const expectedMakerToken = randomAddress();
|
||||
const expectedTakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
|
||||
const expectedMakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
|
||||
const sampler = new MockSamplerContract({
|
||||
sampleSellsFromKyberNetwork: (_reserveOffset, takerToken, makerToken, fillAmounts) => {
|
||||
expect(takerToken).to.eq(expectedTakerToken);
|
||||
expect(makerToken).to.eq(expectedMakerToken);
|
||||
expect(fillAmounts).to.deep.eq(expectedTakerFillAmounts);
|
||||
return ['0x', '0x', expectedMakerFillAmounts];
|
||||
},
|
||||
});
|
||||
const dexOrderSampler = new DexOrderSampler(
|
||||
chainId,
|
||||
sampler,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
async () => undefined,
|
||||
);
|
||||
const [fillableAmounts] = await dexOrderSampler.executeAsync(
|
||||
dexOrderSampler.getKyberSellQuotes(
|
||||
{ hintHandler: randomAddress(), networkProxy: randomAddress(), weth: randomAddress() },
|
||||
new BigNumber(0),
|
||||
expectedMakerToken,
|
||||
expectedTakerToken,
|
||||
expectedTakerFillAmounts,
|
||||
),
|
||||
);
|
||||
expect(fillableAmounts).to.deep.eq(expectedMakerFillAmounts);
|
||||
});
|
||||
|
||||
it('getLiquidityProviderSellQuotes()', async () => {
|
||||
const expectedMakerToken = randomAddress();
|
||||
const expectedTakerToken = randomAddress();
|
||||
@@ -370,7 +336,6 @@ describe.skip('DexSampler tests', () => {
|
||||
const expectedMakerToken = randomAddress();
|
||||
const sources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.UniswapV2];
|
||||
const ratesBySource: RatesBySource = {
|
||||
[ERC20BridgeSource.Kyber]: getRandomFloat(0, 100),
|
||||
[ERC20BridgeSource.Uniswap]: getRandomFloat(0, 100),
|
||||
[ERC20BridgeSource.UniswapV2]: getRandomFloat(0, 100),
|
||||
};
|
||||
|
@@ -11,7 +11,7 @@ import {
|
||||
import { FillQuoteTransformerOrderType, LimitOrder, RfqOrder, SignatureType } from '@0x/protocol-utils';
|
||||
import { BigNumber, hexUtils, NULL_BYTES } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { Pool } from '@balancer-labs/sor/dist/types';
|
||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
|
||||
import * as _ from 'lodash';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
|
||||
@@ -50,9 +50,9 @@ const TAKER_TOKEN = randomAddress();
|
||||
|
||||
const DEFAULT_INCLUDED = [
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
ERC20BridgeSource.Curve,
|
||||
];
|
||||
|
||||
const DEFAULT_EXCLUDED = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources.filter(
|
||||
@@ -321,7 +321,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
[ERC20BridgeSource.Native]: createDecreasingRates(NUM_SAMPLES),
|
||||
[ERC20BridgeSource.SushiSwap]: createDecreasingRates(NUM_SAMPLES),
|
||||
[ERC20BridgeSource.Uniswap]: createDecreasingRates(NUM_SAMPLES),
|
||||
[ERC20BridgeSource.Kyber]: createDecreasingRates(NUM_SAMPLES),
|
||||
[ERC20BridgeSource.Curve]: createDecreasingRates(NUM_SAMPLES),
|
||||
};
|
||||
|
||||
interface FillDataBySource {
|
||||
@@ -337,7 +337,6 @@ describe('MarketOperationUtils tests', () => {
|
||||
deadline: Math.floor(Date.now() / 1000) + 300,
|
||||
},
|
||||
[ERC20BridgeSource.Bancor]: { path: [], networkAddress: randomAddress() },
|
||||
[ERC20BridgeSource.Kyber]: { hint: '0x', reserveId: '0x', networkAddress: randomAddress() },
|
||||
[ERC20BridgeSource.Curve]: {
|
||||
pool: {
|
||||
poolAddress: randomAddress(),
|
||||
@@ -1034,7 +1033,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
rates[ERC20BridgeSource.Native] = [0.4, 0.3, 0.2, 0.1];
|
||||
rates[ERC20BridgeSource.Uniswap] = [0.5, 0.05, 0.05, 0.05];
|
||||
rates[ERC20BridgeSource.SushiSwap] = [0.6, 0.05, 0.05, 0.05];
|
||||
rates[ERC20BridgeSource.Kyber] = [0, 0, 0, 0]; // unused
|
||||
rates[ERC20BridgeSource.Curve] = [0, 0, 0, 0]; // unused
|
||||
replaceSamplerOps({
|
||||
getSellQuotes: createGetMultipleSellQuotesOperationFromRates(rates),
|
||||
});
|
||||
@@ -1066,7 +1065,6 @@ describe('MarketOperationUtils tests', () => {
|
||||
[ERC20BridgeSource.Native]: [1, 0.99, 0.98, 0.97], // Effectively [0.94, 0.93, 0.92, 0.91]
|
||||
[ERC20BridgeSource.Uniswap]: [0.96, 0.1, 0.1, 0.1],
|
||||
[ERC20BridgeSource.SushiSwap]: [0.95, 0.1, 0.1, 0.1],
|
||||
[ERC20BridgeSource.Kyber]: [0.1, 0.1, 0.1, 0.1],
|
||||
};
|
||||
const feeSchedule = {
|
||||
[ERC20BridgeSource.Native]: _.constant(
|
||||
@@ -1097,12 +1095,10 @@ describe('MarketOperationUtils tests', () => {
|
||||
});
|
||||
|
||||
it('factors in fees for dexes', async () => {
|
||||
// Kyber will have the best rates but will have fees,
|
||||
// dropping its effective rates.
|
||||
const uniswapFeeRate = 0.2;
|
||||
const rates: RatesBySource = {
|
||||
[ERC20BridgeSource.Native]: [0.95, 0.1, 0.1, 0.1],
|
||||
[ERC20BridgeSource.Kyber]: [0.1, 0.1, 0.1, 0.1],
|
||||
[ERC20BridgeSource.Curve]: [0.1, 0.1, 0.1, 0.1],
|
||||
[ERC20BridgeSource.SushiSwap]: [0.92, 0.1, 0.1, 0.1],
|
||||
// Effectively [0.8, ~0.5, ~0, ~0]
|
||||
[ERC20BridgeSource.Uniswap]: [1, 0.7, 0.2, 0.2],
|
||||
@@ -1136,7 +1132,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
|
||||
it('can mix one concave source', async () => {
|
||||
const rates: RatesBySource = {
|
||||
[ERC20BridgeSource.Kyber]: [0, 0, 0, 0], // Won't use
|
||||
[ERC20BridgeSource.Curve]: [0, 0, 0, 0], // Won't use
|
||||
[ERC20BridgeSource.SushiSwap]: [0.5, 0.85, 0.75, 0.75], // Concave
|
||||
[ERC20BridgeSource.Uniswap]: [0.96, 0.2, 0.1, 0.1],
|
||||
[ERC20BridgeSource.Native]: [0.95, 0.2, 0.2, 0.1],
|
||||
@@ -1168,7 +1164,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
rates[ERC20BridgeSource.Native] = [1, 1, 0.01, 0.01];
|
||||
rates[ERC20BridgeSource.Uniswap] = [1, 1, 0.01, 0.01];
|
||||
rates[ERC20BridgeSource.SushiSwap] = [0.49, 0.49, 0.49, 0.49];
|
||||
rates[ERC20BridgeSource.Kyber] = [0.35, 0.2, 0.01, 0.01];
|
||||
rates[ERC20BridgeSource.Curve] = [0.35, 0.2, 0.01, 0.01];
|
||||
replaceSamplerOps({
|
||||
getSellQuotes: createGetMultipleSellQuotesOperationFromRates(rates),
|
||||
});
|
||||
@@ -1517,7 +1513,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
[ERC20BridgeSource.Native]: [1, 0.99, 0.98, 0.97], // Effectively [0.94, ~0.93, ~0.92, ~0.91]
|
||||
[ERC20BridgeSource.Uniswap]: [0.96, 0.1, 0.1, 0.1],
|
||||
[ERC20BridgeSource.SushiSwap]: [0.95, 0.1, 0.1, 0.1],
|
||||
[ERC20BridgeSource.Kyber]: [0.1, 0.1, 0.1, 0.1],
|
||||
[ERC20BridgeSource.Curve]: [0.1, 0.1, 0.1, 0.1],
|
||||
};
|
||||
const feeSchedule = {
|
||||
[ERC20BridgeSource.Native]: _.constant(
|
||||
|
@@ -58,8 +58,8 @@ describe('generateQuoteReport', async () => {
|
||||
it('should generate report properly for sell', () => {
|
||||
const marketOperation: MarketOperation = MarketOperation.Sell;
|
||||
|
||||
const kyberSample2: DexSample = {
|
||||
source: ERC20BridgeSource.Kyber,
|
||||
const balancerSample2: DexSample = {
|
||||
source: ERC20BridgeSource.BalancerV2,
|
||||
input: new BigNumber(10003),
|
||||
output: new BigNumber(10004),
|
||||
fillData: {},
|
||||
@@ -117,15 +117,15 @@ describe('generateQuoteReport', async () => {
|
||||
sourcePathId: hexUtils.random(),
|
||||
type: FillQuoteTransformerOrderType.Bridge,
|
||||
};
|
||||
const kyber2Fill: CollapsedFill = {
|
||||
...kyberSample2,
|
||||
const balancer2Fill: CollapsedFill = {
|
||||
...balancerSample2,
|
||||
subFills: [],
|
||||
sourcePathId: hexUtils.random(),
|
||||
type: FillQuoteTransformerOrderType.Bridge,
|
||||
};
|
||||
const orderbookOrder2Fill: CollapsedFill = collapsedFillFromNativeOrder(orderbookOrder2);
|
||||
const rfqtOrder2Fill: CollapsedFill = collapsedFillFromNativeOrder(rfqtOrder2);
|
||||
const pathGenerated: CollapsedFill[] = [rfqtOrder2Fill, orderbookOrder2Fill, uniswap2Fill, kyber2Fill];
|
||||
const pathGenerated: CollapsedFill[] = [rfqtOrder2Fill, orderbookOrder2Fill, uniswap2Fill, balancer2Fill];
|
||||
|
||||
// quote generator mock
|
||||
const quoteRequestor = TypeMoq.Mock.ofType<QuoteRequestor>();
|
||||
@@ -190,10 +190,10 @@ describe('generateQuoteReport', async () => {
|
||||
takerAmount: uniswapSample2.input,
|
||||
fillData: {},
|
||||
};
|
||||
const kyber2Source: BridgeQuoteReportEntry = {
|
||||
liquiditySource: ERC20BridgeSource.Kyber,
|
||||
makerAmount: kyberSample2.output,
|
||||
takerAmount: kyberSample2.input,
|
||||
const balancer2Source: BridgeQuoteReportEntry = {
|
||||
liquiditySource: ERC20BridgeSource.BalancerV2,
|
||||
makerAmount: balancerSample2.output,
|
||||
takerAmount: balancerSample2.input,
|
||||
fillData: {},
|
||||
};
|
||||
|
||||
@@ -202,7 +202,7 @@ describe('generateQuoteReport', async () => {
|
||||
rfqtOrder2Source,
|
||||
orderbookOrder2Source,
|
||||
uniswap2Source,
|
||||
kyber2Source,
|
||||
balancer2Source,
|
||||
];
|
||||
expectEqualQuoteReportEntries(orderReport.sourcesConsidered, expectedSourcesConsidered, `sourcesConsidered`);
|
||||
expectEqualQuoteReportEntries(orderReport.sourcesDelivered, expectedSourcesDelivered, `sourcesDelivered`);
|
||||
@@ -210,8 +210,8 @@ describe('generateQuoteReport', async () => {
|
||||
});
|
||||
it('should handle properly for buy without quoteRequestor', () => {
|
||||
const marketOperation: MarketOperation = MarketOperation.Buy;
|
||||
const kyberSample1: DexSample = {
|
||||
source: ERC20BridgeSource.Kyber,
|
||||
const balancerSample1: DexSample = {
|
||||
source: ERC20BridgeSource.BalancerV2,
|
||||
input: new BigNumber(10000),
|
||||
output: new BigNumber(10001),
|
||||
fillData: {},
|
||||
@@ -248,13 +248,13 @@ describe('generateQuoteReport', async () => {
|
||||
sourcePathId: hexUtils.random(),
|
||||
type: FillQuoteTransformerOrderType.Bridge,
|
||||
};
|
||||
const kyber1Fill: CollapsedFill = {
|
||||
...kyberSample1,
|
||||
const balancer1Fill: CollapsedFill = {
|
||||
...balancerSample1,
|
||||
subFills: [],
|
||||
sourcePathId: hexUtils.random(),
|
||||
type: FillQuoteTransformerOrderType.Bridge,
|
||||
};
|
||||
const pathGenerated: CollapsedFill[] = [orderbookOrder1Fill, uniswap1Fill, kyber1Fill];
|
||||
const pathGenerated: CollapsedFill[] = [orderbookOrder1Fill, uniswap1Fill, balancer1Fill];
|
||||
|
||||
const orderReport = generateQuoteReport(marketOperation, nativeOrders, pathGenerated);
|
||||
|
||||
@@ -274,16 +274,16 @@ describe('generateQuoteReport', async () => {
|
||||
takerAmount: uniswapSample1.output,
|
||||
fillData: {},
|
||||
};
|
||||
const kyber1Source: BridgeQuoteReportEntry = {
|
||||
liquiditySource: ERC20BridgeSource.Kyber,
|
||||
makerAmount: kyberSample1.input,
|
||||
takerAmount: kyberSample1.output,
|
||||
const balancer1Source: BridgeQuoteReportEntry = {
|
||||
liquiditySource: ERC20BridgeSource.BalancerV2,
|
||||
makerAmount: balancerSample1.input,
|
||||
takerAmount: balancerSample1.output,
|
||||
fillData: {},
|
||||
};
|
||||
|
||||
// No order is considered here because only Native RFQ orders are considered.
|
||||
const expectedSourcesConsidered: QuoteReportEntry[] = [];
|
||||
const expectedSourcesDelivered: QuoteReportEntry[] = [orderbookOrder1Source, uniswap1Source, kyber1Source];
|
||||
const expectedSourcesDelivered: QuoteReportEntry[] = [orderbookOrder1Source, uniswap1Source, balancer1Source];
|
||||
expectEqualQuoteReportEntries(orderReport.sourcesConsidered, expectedSourcesConsidered, `sourcesConsidered`);
|
||||
expectEqualQuoteReportEntries(orderReport.sourcesDelivered, expectedSourcesDelivered, `sourcesDelivered`);
|
||||
});
|
||||
|
@@ -1,10 +1,9 @@
|
||||
import { ContractTxFunctionObj } from '@0x/base-contract';
|
||||
import { constants } from '@0x/contracts-test-utils';
|
||||
import { LimitOrderFields, Signature } from '@0x/protocol-utils';
|
||||
import { BigNumber, hexUtils, NULL_BYTES } from '@0x/utils';
|
||||
import { BigNumber, hexUtils } from '@0x/utils';
|
||||
|
||||
import { SamplerCallResult } from '../../src/types';
|
||||
import { KyberSamplerOpts } from '../../src/utils/market_operation_utils/types';
|
||||
import { ERC20BridgeSamplerContract } from '../../src/wrappers';
|
||||
|
||||
export type GetOrderFillableAssetAmountResult = BigNumber[];
|
||||
@@ -39,18 +38,6 @@ export type SampleBuysEth2DaiHandler = (
|
||||
makerToken: string,
|
||||
makerTokenAmounts: BigNumber[],
|
||||
) => SampleResults;
|
||||
export type SampleSellsKyberHandler = (
|
||||
opts: KyberSamplerOpts,
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
takerTokenAmounts: BigNumber[],
|
||||
) => [string, string, SampleResults];
|
||||
export type SampleBuysKyberHandler = (
|
||||
reserveId: string,
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
makerTokenAmounts: BigNumber[],
|
||||
) => [string, SampleResults];
|
||||
export type SampleUniswapV2Handler = (router: string, path: string[], assetAmounts: BigNumber[]) => SampleResults;
|
||||
export type SampleBuysMultihopHandler = (path: string[], takerTokenAmounts: BigNumber[]) => SampleResults;
|
||||
export type SampleSellsLPHandler = (
|
||||
@@ -70,7 +57,6 @@ const DUMMY_PROVIDER = {
|
||||
interface Handlers {
|
||||
getLimitOrderFillableMakerAssetAmounts: GetOrderFillableAssetAmountHandler;
|
||||
getLimitOrderFillableTakerAssetAmounts: GetOrderFillableAssetAmountHandler;
|
||||
sampleSellsFromKyberNetwork: SampleSellsKyberHandler;
|
||||
sampleSellsFromLiquidityProvider: SampleSellsLPHandler;
|
||||
sampleSellsFromUniswap: SampleSellsUniswapHandler;
|
||||
sampleSellsFromUniswapV2: SampleUniswapV2Handler;
|
||||
@@ -123,22 +109,6 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
);
|
||||
}
|
||||
|
||||
public sampleSellsFromKyberNetwork(
|
||||
opts: KyberSamplerOpts,
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
takerAssetAmounts: BigNumber[],
|
||||
): ContractTxFunctionObj<[string, string, BigNumber[]]> {
|
||||
return this._wrapCall(
|
||||
super.sampleSellsFromKyberNetwork,
|
||||
this._handlers.sampleSellsFromKyberNetwork,
|
||||
{ ...opts, reserveOffset: new BigNumber(1), hint: NULL_BYTES },
|
||||
takerToken,
|
||||
makerToken,
|
||||
takerAssetAmounts,
|
||||
);
|
||||
}
|
||||
|
||||
public sampleSellsFromUniswap(
|
||||
router: string,
|
||||
takerToken: string,
|
||||
|
@@ -21,7 +21,6 @@ export * from '../test/generated-wrappers/i_balancer';
|
||||
export * from '../test/generated-wrappers/i_balancer_v2_vault';
|
||||
export * from '../test/generated-wrappers/i_bancor';
|
||||
export * from '../test/generated-wrappers/i_curve';
|
||||
export * from '../test/generated-wrappers/i_kyber_network';
|
||||
export * from '../test/generated-wrappers/i_m_stable';
|
||||
export * from '../test/generated-wrappers/i_mooniswap';
|
||||
export * from '../test/generated-wrappers/i_multi_bridge';
|
||||
@@ -32,7 +31,6 @@ export * from '../test/generated-wrappers/i_uniswap_exchange_quotes';
|
||||
export * from '../test/generated-wrappers/i_uniswap_v2_router01';
|
||||
export * from '../test/generated-wrappers/igmx';
|
||||
export * from '../test/generated-wrappers/kyber_dmm_sampler';
|
||||
export * from '../test/generated-wrappers/kyber_sampler';
|
||||
export * from '../test/generated-wrappers/lido_sampler';
|
||||
export * from '../test/generated-wrappers/liquidity_provider_sampler';
|
||||
export * from '../test/generated-wrappers/m_stable_sampler';
|
||||
|
@@ -25,7 +25,6 @@
|
||||
"test/generated-artifacts/IBancor.json",
|
||||
"test/generated-artifacts/ICurve.json",
|
||||
"test/generated-artifacts/IGMX.json",
|
||||
"test/generated-artifacts/IKyberNetwork.json",
|
||||
"test/generated-artifacts/IMStable.json",
|
||||
"test/generated-artifacts/IMooniswap.json",
|
||||
"test/generated-artifacts/IMultiBridge.json",
|
||||
@@ -35,7 +34,6 @@
|
||||
"test/generated-artifacts/IUniswapExchangeQuotes.json",
|
||||
"test/generated-artifacts/IUniswapV2Router01.json",
|
||||
"test/generated-artifacts/KyberDmmSampler.json",
|
||||
"test/generated-artifacts/KyberSampler.json",
|
||||
"test/generated-artifacts/LidoSampler.json",
|
||||
"test/generated-artifacts/LiquidityProviderSampler.json",
|
||||
"test/generated-artifacts/MStableSampler.json",
|
||||
|
@@ -63,7 +63,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.34",
|
||||
"@0x/contract-addresses": "^6.14.0",
|
||||
"@0x/contract-addresses": "^6.16.0",
|
||||
"@0x/contract-wrappers": "^13.20.2",
|
||||
"@0x/json-schemas": "^6.4.4",
|
||||
"@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 OtcOrderFields = typeof OTC_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 {
|
||||
Invalid = 0,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { AbiEncoder, BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils';
|
||||
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';
|
||||
|
||||
const BRIDGE_ORDER_ABI_COMPONENTS = [
|
||||
@@ -39,6 +39,20 @@ const RFQ_ORDER_INFO_ABI_COMPONENTS = [
|
||||
{ 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`
|
||||
*/
|
||||
@@ -65,6 +79,11 @@ export const fillQuoteTransformerDataEncoder = AbiEncoder.create([
|
||||
type: 'tuple[]',
|
||||
components: RFQ_ORDER_INFO_ABI_COMPONENTS,
|
||||
},
|
||||
{
|
||||
name: 'otcOrders',
|
||||
type: 'tuple[]',
|
||||
components: OTC_ORDER_INFO_ABI_COMPONENTS,
|
||||
},
|
||||
{ name: 'fillSequence', type: 'uint8[]' },
|
||||
{ name: 'fillAmount', type: 'uint256' },
|
||||
{ name: 'refundReceiver', type: 'address' },
|
||||
@@ -87,6 +106,7 @@ export enum FillQuoteTransformerOrderType {
|
||||
Bridge,
|
||||
Limit,
|
||||
Rfq,
|
||||
Otc,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,16 +134,13 @@ export enum BridgeProtocol {
|
||||
UniswapV2,
|
||||
Uniswap,
|
||||
Balancer,
|
||||
Kyber,
|
||||
Mooniswap,
|
||||
MStable,
|
||||
Oasis,
|
||||
Shell,
|
||||
Dodo,
|
||||
DodoV2,
|
||||
CryptoCom,
|
||||
Bancor,
|
||||
CoFiX,
|
||||
Nerve,
|
||||
MakerPsm,
|
||||
BalancerV2,
|
||||
@@ -173,6 +190,11 @@ export type FillQuoteTransformerLimitOrderInfo = FillQuoteTransformerNativeOrder
|
||||
*/
|
||||
export type FillQuoteTransformerRfqOrderInfo = FillQuoteTransformerNativeOrderInfo<RfqOrderFields>;
|
||||
|
||||
/**
|
||||
* `FillQuoteTransformer.OtcOrderInfo`
|
||||
*/
|
||||
export type FillQuoteTransformerOtcOrderInfo = FillQuoteTransformerNativeOrderInfo<OtcOrderFields>;
|
||||
|
||||
/**
|
||||
* ABI-encode a `FillQuoteTransformer.TransformData` type.
|
||||
*/
|
||||
@@ -180,6 +202,8 @@ export function encodeFillQuoteTransformerData(data: FillQuoteTransformerData):
|
||||
return fillQuoteTransformerDataEncoder.encode([data]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ABI-decode a `FillQuoteTransformer.TransformData` type.
|
||||
*/
|
||||
@@ -187,6 +211,7 @@ export function decodeFillQuoteTransformerData(encoded: string): FillQuoteTransf
|
||||
return fillQuoteTransformerDataEncoder.decode(encoded).data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ABI encoder for `WethTransformer.TransformData`
|
||||
*/
|
||||
|
@@ -4,7 +4,7 @@ import { BigNumber } from '@0x/utils';
|
||||
import { expect } from 'chai';
|
||||
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';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -145,4 +145,64 @@ describe('orders', () => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
134
yarn.lock
134
yarn.lock
@@ -646,7 +646,6 @@
|
||||
"@0x/abi-gen@^5.8.0":
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@0x/abi-gen/-/abi-gen-5.8.0.tgz#d5507de71021ebb121d50dc239c80f9cbe156da2"
|
||||
integrity sha512-5+dal6EY5Ji13WozUpNsyNvYUP4TW35Z0+t+9dDTtGKtZmxK6KxlNaDTUaK4qZcGy+bv39cYnLHfjDTGOLUCyA==
|
||||
dependencies:
|
||||
"@0x/types" "^3.3.6"
|
||||
"@0x/typescript-typings" "^5.3.1"
|
||||
@@ -680,7 +679,6 @@
|
||||
"@0x/assert@^3.0.34":
|
||||
version "3.0.34"
|
||||
resolved "https://registry.yarnpkg.com/@0x/assert/-/assert-3.0.34.tgz#aa43642abb969882910f271d9eab957217510807"
|
||||
integrity sha512-KDdmUs0O055PPnijmdoBOrZwztl2fmjox1peLzeKNl5OfxwpGBxuce4AhUkmcWKI3u7Mj3Az69gUByX6/NLnVg==
|
||||
dependencies:
|
||||
"@0x/json-schemas" "^6.4.4"
|
||||
"@0x/typescript-typings" "^5.3.1"
|
||||
@@ -720,7 +718,6 @@
|
||||
"@0x/base-contract@^6.5.0":
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@0x/base-contract/-/base-contract-6.5.0.tgz#95b0c3000e571cf4c2a4ee648d029d0ed744b88f"
|
||||
integrity sha512-FbtBmF1qKLvbJL7FmFtxI3enCV0a9YKkltlwgCU/CDlGqGH/1ZP0p32cWLP48tRfqrgCcvWlfc4rRTs4aIwlow==
|
||||
dependencies:
|
||||
"@0x/assert" "^3.0.34"
|
||||
"@0x/json-schemas" "^6.4.4"
|
||||
@@ -735,6 +732,26 @@
|
||||
js-sha3 "^0.7.0"
|
||||
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":
|
||||
version "3.7.19"
|
||||
resolved "https://registry.yarnpkg.com/@0x/contracts-asset-proxy/-/contracts-asset-proxy-3.7.19.tgz#ee621a233f4d77b439c74c5b8d70db2e1ed001c4"
|
||||
@@ -786,6 +803,14 @@
|
||||
"@0x/web3-wrapper" "^7.5.3"
|
||||
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":
|
||||
version "3.1.37"
|
||||
resolved "https://registry.yarnpkg.com/@0x/contracts-erc721/-/contracts-erc721-3.1.37.tgz#d7d356737e3d2752cf49be385237fbf7d0c5745c"
|
||||
@@ -838,7 +863,6 @@
|
||||
"@0x/contracts-gen@^2.0.46":
|
||||
version "2.0.46"
|
||||
resolved "https://registry.yarnpkg.com/@0x/contracts-gen/-/contracts-gen-2.0.46.tgz#3b840b8a56b67abecb2859c1b8e1db36c309dc11"
|
||||
integrity sha512-zlFSH+TAtDvAG+fEAjOojMPP4E4tO3usmMQdHP26DzqMaJNLGuquLNsx7RQJkECfl/wfMRHMinhRd18pXlmrNw==
|
||||
dependencies:
|
||||
"@0x/sol-compiler" "^4.8.1"
|
||||
"@0x/sol-resolver" "^3.1.12"
|
||||
@@ -871,10 +895,58 @@
|
||||
ethereum-types "^3.5.0"
|
||||
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":
|
||||
version "4.2.14"
|
||||
resolved "https://registry.yarnpkg.com/@0x/dev-utils/-/dev-utils-4.2.14.tgz#2b15b3247ccaf111d8d42689907b603537b0a86c"
|
||||
integrity sha512-1NY2ito5eNo5r8kb9RUP8xoYj5WxnyrcXBDu34ezKHhTMeMcXw7LvXZWSTqrJ6jlZpWT5BM+bJEXGuHDRYJqRA==
|
||||
dependencies:
|
||||
"@0x/subproviders" "^6.6.5"
|
||||
"@0x/types" "^3.3.6"
|
||||
@@ -912,7 +984,6 @@
|
||||
"@0x/json-schemas@^6.4.4":
|
||||
version "6.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@0x/json-schemas/-/json-schemas-6.4.4.tgz#9243c18ef6c1333c3cc47bf2870912d7badb307e"
|
||||
integrity sha512-uPl/gGQo3sYHwmoiNRITEyTOdr2bQTmsxzYquVwHIA1ZM6UHSIjiFcbeAO91aSE/U5uiCc9vuz8Ux9x+8F1BWw==
|
||||
dependencies:
|
||||
"@0x/typescript-typings" "^5.3.1"
|
||||
"@types/node" "12.12.54"
|
||||
@@ -934,7 +1005,6 @@
|
||||
"@0x/monorepo-scripts@^3.2.4":
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@0x/monorepo-scripts/-/monorepo-scripts-3.2.4.tgz#7a089db39a3bd128ee22448d341cdabcc948614b"
|
||||
integrity sha512-Fszb8zo5ao5jRRfugnmoRg1kI8el6q0SXo4Ibnpqj+ahAsjGN/1cgVuhqEzy+3PYU6X7Z/gmV1GE7RYn+mFk1g==
|
||||
dependencies:
|
||||
"@0x/types" "^3.3.6"
|
||||
"@0x/utils" "^6.5.3"
|
||||
@@ -962,7 +1032,6 @@
|
||||
"@0x/neon-router@^0.3.5":
|
||||
version "0.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@0x/neon-router/-/neon-router-0.3.5.tgz#895e7a2dc65d492a413daaea283cbc0ca6df83fa"
|
||||
integrity sha512-8wizP3smc5o4jVg1smZzCCFo4ohOrgDhO4JFjF+/oNHbFImlGHOvmH9HQ2FJXAXiLEOTxrbp3T5XxP5GNATq3w==
|
||||
dependencies:
|
||||
"@mapbox/node-pre-gyp" "^1.0.5"
|
||||
|
||||
@@ -983,7 +1052,6 @@
|
||||
"@0x/protocol-utils@^1.0.1":
|
||||
version "1.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@0x/protocol-utils/-/protocol-utils-1.11.2.tgz#c27ccf3410b99d8c364550bc18dc8b04dc2e967e"
|
||||
integrity sha512-DmYCWb3fB1NSBbR7JV2Tr4oXr/3rDzVpECWUvntCyIwdohHSM7ytjYbL9ilvlH3vuDK85CSyFWNrbSP6xZfTpA==
|
||||
dependencies:
|
||||
"@0x/assert" "^3.0.34"
|
||||
"@0x/contract-addresses" "^6.12.1"
|
||||
@@ -1013,7 +1081,6 @@
|
||||
"@0x/sol-compiler@^4.8.1":
|
||||
version "4.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@0x/sol-compiler/-/sol-compiler-4.8.1.tgz#87340455c1ff7505a6201549910972016524857e"
|
||||
integrity sha512-bTTbrWv8GE0HbPIYK7EVxIWcPxs1R7SPr9G3qiOM+HGg7tHip8t2ehGdoY00zR7UALXVi3lHvKGl/na3uM7t4w==
|
||||
dependencies:
|
||||
"@0x/assert" "^3.0.34"
|
||||
"@0x/json-schemas" "^6.4.4"
|
||||
@@ -1042,7 +1109,6 @@
|
||||
"@0x/sol-coverage@^4.0.45":
|
||||
version "4.0.45"
|
||||
resolved "https://registry.yarnpkg.com/@0x/sol-coverage/-/sol-coverage-4.0.45.tgz#5661cfe4eae7c8c8a9d24c9173e269aae54fe366"
|
||||
integrity sha512-6WuGPIax1l1/8dcrvwUTiB3Gz5FIbW9ie2QAiQv8qNJAVmZHDSPX3obd5eCFaVaPEtrLB7fOQpiDoyQJ7mFyZQ==
|
||||
dependencies:
|
||||
"@0x/sol-tracing-utils" "^7.3.1"
|
||||
"@0x/subproviders" "^6.6.5"
|
||||
@@ -1057,7 +1123,6 @@
|
||||
"@0x/sol-profiler@^4.1.35":
|
||||
version "4.1.35"
|
||||
resolved "https://registry.yarnpkg.com/@0x/sol-profiler/-/sol-profiler-4.1.35.tgz#aef3a46c11be1caeb0f060a5c3584e7b160ef67c"
|
||||
integrity sha512-Lvs7gyyr8kiiAA2saLLCGHct9VVYC4DB4hNP+/82GDXXBu51ZYxuxE8q9M9fUj6kGyNM1jhd614w2aYUB5MpNw==
|
||||
dependencies:
|
||||
"@0x/sol-tracing-utils" "^7.3.1"
|
||||
"@0x/subproviders" "^6.6.5"
|
||||
@@ -1072,7 +1137,6 @@
|
||||
"@0x/sol-resolver@^3.1.12":
|
||||
version "3.1.12"
|
||||
resolved "https://registry.yarnpkg.com/@0x/sol-resolver/-/sol-resolver-3.1.12.tgz#36156ff540751ae8b5e082cfa37ab0d4192580b8"
|
||||
integrity sha512-r22NN6LKaihc40PSzgpIni0nYRwk7bTu7Yz9mGySb3sgiqRHt+QJV13q5rwBuoIMwLpfmCgiL0qC3NVHcfl1BA==
|
||||
dependencies:
|
||||
"@0x/types" "^3.3.6"
|
||||
"@0x/typescript-typings" "^5.3.1"
|
||||
@@ -1082,7 +1146,6 @@
|
||||
"@0x/sol-trace@^3.0.45":
|
||||
version "3.0.45"
|
||||
resolved "https://registry.yarnpkg.com/@0x/sol-trace/-/sol-trace-3.0.45.tgz#337bb5ffb362a1b3e9631cf3bb1a40d6e8f4cf3e"
|
||||
integrity sha512-zrWOJ7ut25kxHLhJGItQBt7Z3idUnpEIJlsYLhtmKK+nf3E1QLluhsdn0No0ijtBpIiI3KtlZvFXHyqktH6NCg==
|
||||
dependencies:
|
||||
"@0x/sol-tracing-utils" "^7.3.1"
|
||||
"@0x/subproviders" "^6.6.5"
|
||||
@@ -1098,7 +1161,6 @@
|
||||
"@0x/sol-tracing-utils@^7.3.1":
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@0x/sol-tracing-utils/-/sol-tracing-utils-7.3.1.tgz#99a1948d3fac88d442beda73ea53029142e6748b"
|
||||
integrity sha512-IWMvokOdA83ORwyn3HqjK3+zXEGSr+fRcwNu6khikGDi70gUWVDmkSghHKltEcy05YC8mRRoJgIw8Skrzvbd4w==
|
||||
dependencies:
|
||||
"@0x/dev-utils" "^4.2.14"
|
||||
"@0x/sol-compiler" "^4.8.1"
|
||||
@@ -1126,7 +1188,6 @@
|
||||
"@0x/subproviders@^6.6.5":
|
||||
version "6.6.5"
|
||||
resolved "https://registry.yarnpkg.com/@0x/subproviders/-/subproviders-6.6.5.tgz#7083abd28aad5564ad5bbf98c9f7d35ebf948aff"
|
||||
integrity sha512-tpkKH5XBgrlO4K9dMNqsYiTgrAOJUnThiu73y9tYl4mwX/1gRpyG1EebvD8w6VKPrLjnyPyMw50ZvTyaYgbXNQ==
|
||||
dependencies:
|
||||
"@0x/assert" "^3.0.34"
|
||||
"@0x/types" "^3.3.6"
|
||||
@@ -1204,7 +1265,6 @@
|
||||
"@0x/types@^3.3.6":
|
||||
version "3.3.6"
|
||||
resolved "https://registry.yarnpkg.com/@0x/types/-/types-3.3.6.tgz#2746137791d5c8ca6034311a9327fc78b46c5f63"
|
||||
integrity sha512-ljtc9X4BnlM+MkcLet6hypsF1og0N4lMxt/2nNuPvbI6qude1kdu7Eyw2yb8fpwQfClTtR4rYUT6DeL0zh7qmQ==
|
||||
dependencies:
|
||||
"@types/node" "12.12.54"
|
||||
bignumber.js "~9.0.2"
|
||||
@@ -1246,7 +1306,6 @@
|
||||
"@0x/typescript-typings@^5.3.1":
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@0x/typescript-typings/-/typescript-typings-5.3.1.tgz#853bcad04fbaee4af63532317d7f9ef486dfbb1a"
|
||||
integrity sha512-baxz6gTNDI+q/TBOm8xXeqCiCu/Rw6a/cpuWzjFNPPTMgO7o4nsk6fIGFGJLuSGUmDMOx+YVzUB0emV6dMtMxA==
|
||||
dependencies:
|
||||
"@types/bn.js" "^4.11.0"
|
||||
"@types/node" "12.12.54"
|
||||
@@ -1313,7 +1372,6 @@
|
||||
"@0x/utils@^6.5.3":
|
||||
version "6.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@0x/utils/-/utils-6.5.3.tgz#b944ffb197a062e3996a4f2e6e43f7babe21e113"
|
||||
integrity sha512-C8Af9MeNvWTtSg5eEOObSZ+7gjOGSHkhqDWv8iPfrMMt7yFkAjHxpXW+xufk6ZG2VTg+hel82GDyhKaGtoQZDA==
|
||||
dependencies:
|
||||
"@0x/types" "^3.3.6"
|
||||
"@0x/typescript-typings" "^5.3.1"
|
||||
@@ -1347,7 +1405,6 @@
|
||||
"@0x/web3-wrapper@^7.6.5":
|
||||
version "7.6.5"
|
||||
resolved "https://registry.yarnpkg.com/@0x/web3-wrapper/-/web3-wrapper-7.6.5.tgz#9e6731663b1856c043e45165ba564ab6ee7b97f6"
|
||||
integrity sha512-AyaisigXUsuwLcLqfji7DzQ+komL9NpaH1k2eTZMn7sxPfZZBSIMFbu3vgSKYvRnJdrXrkeKjE5h0BhIvTngMA==
|
||||
dependencies:
|
||||
"@0x/assert" "^3.0.34"
|
||||
"@0x/json-schemas" "^6.4.4"
|
||||
@@ -1401,7 +1458,7 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@balancer-labs/sdk@^0.1.6":
|
||||
"@balancer-labs/sdk@0.1.6":
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@balancer-labs/sdk/-/sdk-0.1.6.tgz#1a6f0aacfada7b0afbdf02259ef40ed37d3ecbcb"
|
||||
integrity sha512-r9s7Y2XJks+8V53kqwaqHDAETipgFSEQxI7TFHYigoOtWp/sUaZnlu0kDMv3NuDvya0+t9gp5a0VxbztLwcn+g==
|
||||
@@ -1412,19 +1469,9 @@
|
||||
graphql-request "^3.5.0"
|
||||
lodash "^4.17.21"
|
||||
|
||||
"@balancer-labs/sor@0.3.2":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-0.3.2.tgz#b05c63a07031c2ea13ed0d2670f5105cfaa40523"
|
||||
dependencies:
|
||||
bignumber.js "^9.0.0"
|
||||
ethers "^4.0.39"
|
||||
isomorphic-fetch "^2.2.1"
|
||||
typescript "^3.8.3"
|
||||
|
||||
"@balancer-labs/sor@^4.0.0-beta.2":
|
||||
version "4.0.0-beta.2"
|
||||
resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-4.0.0-beta.2.tgz#17ee901c7434f9a5702653488b1a3ec6e1f926f1"
|
||||
integrity sha512-ylDxsMDKpoynOQIH4PhucYc7bkXddjL6GRFCF2BwnQ4Yoy7vBOT7S0zJvIkKuUG6MSUdoTBaAtWckxXBJiNxyA==
|
||||
dependencies:
|
||||
isomorphic-fetch "^2.2.1"
|
||||
|
||||
@@ -3290,7 +3337,6 @@ axios@^0.21.1:
|
||||
axios@^0.24.0:
|
||||
version "0.24.0"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
|
||||
integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
|
||||
dependencies:
|
||||
follow-redirects "^1.14.4"
|
||||
|
||||
@@ -3775,6 +3821,15 @@ balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
|
||||
"balancer-labs-sor-v1@npm:@balancer-labs/sor@0.3.2":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-0.3.2.tgz#b05c63a07031c2ea13ed0d2670f5105cfaa40523"
|
||||
dependencies:
|
||||
bignumber.js "^9.0.0"
|
||||
ethers "^4.0.39"
|
||||
isomorphic-fetch "^2.2.1"
|
||||
typescript "^3.8.3"
|
||||
|
||||
base-x@^3.0.2, base-x@^3.0.8:
|
||||
version "3.0.8"
|
||||
resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d"
|
||||
@@ -4600,7 +4655,6 @@ commander@^2.12.1, commander@^2.8.1:
|
||||
commander@^8.1.0:
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
|
||||
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
|
||||
|
||||
commondir@^1.0.1:
|
||||
version "1.0.1"
|
||||
@@ -5895,7 +5949,6 @@ ethereum-types@^3.5.0:
|
||||
ethereum-types@^3.7.0:
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/ethereum-types/-/ethereum-types-3.7.0.tgz#2fec14cebef6e68f3b66a6efd4eaa1003f2c972b"
|
||||
integrity sha512-7gU4cUkpmKbAMgEdF3vWFCcLS1aKdsGxIFbd8WIHgBOHLwlcjfcxtkwrFGXuCc90cg6V4MDA9iOI7W0hQ7eTvQ==
|
||||
dependencies:
|
||||
"@types/node" "12.12.54"
|
||||
bignumber.js "~9.0.2"
|
||||
@@ -6560,7 +6613,6 @@ follow-redirects@^1.10.0:
|
||||
follow-redirects@^1.12.1, follow-redirects@^1.14.4:
|
||||
version "1.14.9"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7"
|
||||
integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
|
||||
|
||||
for-each@~0.3.3:
|
||||
version "0.3.3"
|
||||
@@ -7076,7 +7128,6 @@ graphql-request@^3.4.0:
|
||||
graphql-request@^3.5.0:
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-3.7.0.tgz#c7406e537084f8b9788541e3e6704340ca13055b"
|
||||
integrity sha512-dw5PxHCgBneN2DDNqpWu8QkbbJ07oOziy8z+bK/TAXufsOLaETuVO4GkXrbs0WjhdKhBMN3BkpN/RIvUHkmNUQ==
|
||||
dependencies:
|
||||
cross-fetch "^3.0.6"
|
||||
extract-files "^9.0.0"
|
||||
@@ -7089,7 +7140,6 @@ graphql@^15.4.0:
|
||||
graphql@^15.6.1:
|
||||
version "15.8.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.8.0.tgz#33410e96b012fa3bdb1091cc99a94769db212b38"
|
||||
integrity sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==
|
||||
|
||||
growl@1.10.5:
|
||||
version "1.10.5"
|
||||
@@ -8452,7 +8502,6 @@ lodash@4.17.20, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.
|
||||
lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
log-driver@^1.2.7:
|
||||
version "1.2.7"
|
||||
@@ -11254,7 +11303,6 @@ socks@~2.3.2:
|
||||
solc@^0.8:
|
||||
version "0.8.12"
|
||||
resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.12.tgz#3002ed3092ee2f7672f1a2ab80c0d8df8df3ef2b"
|
||||
integrity sha512-TU3anAhKWBQ/WrerJ9EcHrNwGOA1y5vIk5Flz7dBNamLDkX9VQTIwcKd3FiZsT0Ew8rSU7RTmJyGNHRGzP5TBA==
|
||||
dependencies:
|
||||
command-exists "^1.2.8"
|
||||
commander "^8.1.0"
|
||||
@@ -11284,13 +11332,6 @@ solidity-parser-antlr@^0.4.2:
|
||||
version "0.4.11"
|
||||
resolved "https://registry.yarnpkg.com/solidity-parser-antlr/-/solidity-parser-antlr-0.4.11.tgz#af43e1f13b3b88309a875455f5d6e565b05ee5f1"
|
||||
|
||||
"sorV2@npm:@balancer-labs/sor":
|
||||
version "4.0.0-beta.1"
|
||||
resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-4.0.0-beta.1.tgz#fb8b3f2d9bb5cec5c79446e0062aab7cdfcabccb"
|
||||
integrity sha512-L3eMBRA51egMNKHkLktOr3sNJuqgoz24AfJkpzU4w1I66m9HlOPY/E3FgYKWO+1cXJ2sQZWDH3pEjnWMRnNbNg==
|
||||
dependencies:
|
||||
isomorphic-fetch "^2.2.1"
|
||||
|
||||
sort-keys@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128"
|
||||
@@ -12207,7 +12248,6 @@ typescript@3.7.x:
|
||||
typescript@4.6.3:
|
||||
version "4.6.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c"
|
||||
integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==
|
||||
|
||||
typescript@^3.8.3:
|
||||
version "3.9.7"
|
||||
|
Reference in New Issue
Block a user