patch asset-swapper to support ERC721
This commit is contained in:
@@ -21,6 +21,10 @@ const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
const MAINNET_CHAIN_ID = 1;
|
||||
const ONE_SECOND_MS = 1000;
|
||||
const DEFAULT_PER_PAGE = 1000;
|
||||
const PROXY_IDS = {
|
||||
ERC20_PROXY_ID: '0xf47261b0',
|
||||
ERC721_PROXY_ID: '0x02571792',
|
||||
};
|
||||
|
||||
const DEFAULT_ORDER_PRUNER_OPTS: OrderPrunerOpts = {
|
||||
expiryBufferMs: 120000, // 2 minutes
|
||||
@@ -114,4 +118,5 @@ export const constants = {
|
||||
MARKET_UTILS_AMOUNT_BUFFER_PERCENTAGE,
|
||||
BRIDGE_ASSET_DATA_PREFIX: '0xdc1600f3',
|
||||
DEFAULT_CURVE_OPTS,
|
||||
PROXY_IDS,
|
||||
};
|
||||
|
||||
@@ -234,6 +234,7 @@ export enum SwapQuoterError {
|
||||
InsufficientAssetLiquidity = 'INSUFFICIENT_ASSET_LIQUIDITY',
|
||||
AssetUnavailable = 'ASSET_UNAVAILABLE',
|
||||
NoGasPriceProvidedOrEstimated = 'NO_GAS_PRICE_PROVIDED_OR_ESTIMATED',
|
||||
AssetDataUnsupported = 'ASSET_DATA_UNSUPPORTED',
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { orderCalculationUtils } from '@0x/order-utils';
|
||||
import { assetDataUtils, orderCalculationUtils } from '@0x/order-utils';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
SwapQuoteBase,
|
||||
SwapQuoteInfo,
|
||||
SwapQuoteOrdersBreakdown,
|
||||
SwapQuoterError,
|
||||
} from '../types';
|
||||
|
||||
import { fillableAmountsUtils } from './fillable_amounts_utils';
|
||||
@@ -126,6 +127,10 @@ export class SwapQuoteCalculator {
|
||||
operation: MarketOperation,
|
||||
opts: CalculateSwapQuoteOpts,
|
||||
): Promise<SwapQuote> {
|
||||
// checks if maker asset is ERC721 or ERC20 and taker asset is ERC20
|
||||
if (!isSupportedAssetDataInOrders(prunedOrders)) {
|
||||
throw Error(SwapQuoterError.AssetDataUnsupported);
|
||||
}
|
||||
// since prunedOrders do not have fillState, we will add a buffer of fillable orders to consider that some native are orders are partially filled
|
||||
|
||||
const slippageBufferAmount = assetFillAmount.multipliedBy(slippagePercentage).integerValue();
|
||||
@@ -137,21 +142,41 @@ export class SwapQuoteCalculator {
|
||||
...opts,
|
||||
fees: _.mapValues(opts.fees, (v, k) => v.times(gasPrice)),
|
||||
};
|
||||
if (operation === MarketOperation.Buy) {
|
||||
resultOrders = await this._marketOperationUtils.getMarketBuyOrdersAsync(
|
||||
prunedOrders,
|
||||
assetFillAmount.plus(slippageBufferAmount),
|
||||
_opts,
|
||||
);
|
||||
|
||||
const firstOrderMakerAssetData = !!prunedOrders[0] ? assetDataUtils.decodeAssetDataOrThrow(prunedOrders[0].makerAssetData) : { assetProxyId: ''};
|
||||
|
||||
if (firstOrderMakerAssetData.assetProxyId === constants.PROXY_IDS.ERC721_PROXY_ID ) {
|
||||
resultOrders = prunedOrders.map(o => {
|
||||
// HACK: to conform ERC721 orders to the output of market operation utils, assumes complete fillable
|
||||
return {
|
||||
...o,
|
||||
fillableMakerAssetAmount: o.makerAssetAmount,
|
||||
fillableTakerAssetAmount: o.takerAssetAmount,
|
||||
fillableTakerFeeAmount: o.takerFee,
|
||||
fill: {
|
||||
source: ERC20BridgeSource.Native,
|
||||
totalMakerAssetAmount: o.makerAssetAmount,
|
||||
totalTakerAssetAmount: o.takerAssetAmount,
|
||||
subFills: [],
|
||||
},
|
||||
};
|
||||
});
|
||||
} else {
|
||||
resultOrders = await this._marketOperationUtils.getMarketSellOrdersAsync(
|
||||
prunedOrders,
|
||||
assetFillAmount.plus(slippageBufferAmount),
|
||||
_opts,
|
||||
);
|
||||
if (operation === MarketOperation.Buy) {
|
||||
resultOrders = await this._marketOperationUtils.getMarketBuyOrdersAsync(
|
||||
prunedOrders,
|
||||
assetFillAmount.plus(slippageBufferAmount),
|
||||
_opts,
|
||||
);
|
||||
} else {
|
||||
resultOrders = await this._marketOperationUtils.getMarketSellOrdersAsync(
|
||||
prunedOrders,
|
||||
assetFillAmount.plus(slippageBufferAmount),
|
||||
_opts,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// assetData information for the result
|
||||
const { makerAssetData, takerAssetData } = prunedOrders[0];
|
||||
return this._createSwapQuoteAsync(
|
||||
@@ -442,6 +467,24 @@ export class SwapQuoteCalculator {
|
||||
}
|
||||
}
|
||||
|
||||
function isSupportedAssetDataInOrders(
|
||||
orders: SignedOrder[],
|
||||
): boolean {
|
||||
const firstOrderMakerAssetData = !!orders[0] ? assetDataUtils.decodeAssetDataOrThrow(orders[0].makerAssetData) : { assetProxyId: '' };
|
||||
return orders.every(o => {
|
||||
const takerAssetData = assetDataUtils.decodeAssetDataOrThrow(o.takerAssetData);
|
||||
const makerAssetData = assetDataUtils.decodeAssetDataOrThrow(o.makerAssetData);
|
||||
return (
|
||||
(makerAssetData.assetProxyId === constants.PROXY_IDS.ERC20_PROXY_ID
|
||||
|| makerAssetData.assetProxyId === constants.PROXY_IDS.ERC721_PROXY_ID)
|
||||
) &&
|
||||
(
|
||||
takerAssetData.assetProxyId === constants.PROXY_IDS.ERC20_PROXY_ID
|
||||
) &&
|
||||
firstOrderMakerAssetData.assetProxyId === makerAssetData.assetProxyId; // checks that all native order maker assets are of the same type
|
||||
});
|
||||
}
|
||||
|
||||
function getTakerAssetAmountBreakDown(
|
||||
order: SignedOrderWithFillableAmounts,
|
||||
takerAssetAmountWithFees: BigNumber,
|
||||
|
||||
@@ -72,7 +72,13 @@ export class InstantHeading extends React.PureComponent<InstantHeadingProps, {}>
|
||||
overflow="hidden"
|
||||
borderRadius="50%"
|
||||
>
|
||||
<Image src={asset.metaData.imageUrl} height="100%" objectFit="cover" />
|
||||
<Flex
|
||||
justify="center"
|
||||
align="center"
|
||||
height="100%"
|
||||
>
|
||||
<Image src={asset.metaData.imageUrl} height="100%" objectFit="cover" />
|
||||
</Flex>
|
||||
</Container>
|
||||
</Flex>
|
||||
</Container>
|
||||
|
||||
Reference in New Issue
Block a user