From a3d93d17cdefc2258a9f08e6fc680df1fb2b8456 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 14 Dec 2018 10:23:01 -0800 Subject: Factor in slippage amount in InsufficientAssetLiquidityError error, and show in instant --- packages/instant/src/constants.ts | 1 + packages/instant/src/util/asset.ts | 17 ++++++++++++++++- packages/instant/src/util/buy_quote_updater.ts | 7 ++++++- 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index f83eb4ac7..2417c8615 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -16,6 +16,7 @@ export const ONE_SECOND_MS = 1000; export const ONE_MINUTE_MS = ONE_SECOND_MS * 60; export const GIT_SHA = process.env.GIT_SHA; export const NODE_ENV = process.env.NODE_ENV; +export const SLIPPAGE_PERCENTAGE = 0.2; export const NPM_PACKAGE_VERSION = process.env.NPM_PACKAGE_VERSION; export const ACCOUNT_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 5; export const BUY_QUOTE_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 15; diff --git a/packages/instant/src/util/asset.ts b/packages/instant/src/util/asset.ts index 13f84ef74..5e83e7e6d 100644 --- a/packages/instant/src/util/asset.ts +++ b/packages/instant/src/util/asset.ts @@ -1,7 +1,10 @@ -import { AssetBuyerError } from '@0x/asset-buyer'; +import { AssetBuyerError, InsufficientAssetLiquidityError } from '@0x/asset-buyer'; import { AssetProxyId, ObjectMap } from '@0x/types'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; +import { BIG_NUMBER_ZERO } from '../constants'; import { assetDataNetworkMapping } from '../data/asset_data_network_mapping'; import { Asset, AssetMetaData, ERC20Asset, Network, ZeroExInstantError } from '../types'; @@ -110,6 +113,18 @@ export const assetUtils = { assetBuyerErrorMessage: (asset: ERC20Asset, error: Error): string | undefined => { if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); + if (error instanceof InsufficientAssetLiquidityError) { + const unitAmountAvailableToFill = Web3Wrapper.toUnitAmount( + error.amountAvailableToFill, + asset.metaData.decimals, + ); + const roundedUnitAmountAvailableToFill = unitAmountAvailableToFill.round(2, BigNumber.ROUND_DOWN); + + if (roundedUnitAmountAvailableToFill.greaterThan(BIG_NUMBER_ZERO)) { + return `There are only ${roundedUnitAmountAvailableToFill} ${assetName} available to buy`; + } + } + return `Not enough ${assetName} available`; } else if (error.message === AssetBuyerError.InsufficientZrxLiquidity) { return 'Not enough ZRX available'; diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/buy_quote_updater.ts index 6191c92e3..37974e71c 100644 --- a/packages/instant/src/util/buy_quote_updater.ts +++ b/packages/instant/src/util/buy_quote_updater.ts @@ -5,6 +5,7 @@ import * as _ from 'lodash'; import { Dispatch } from 'redux'; import { oc } from 'ts-optchain'; +import { SLIPPAGE_PERCENTAGE } from '../constants'; import { Action, actions } from '../redux/actions'; import { AffiliateInfo, ERC20Asset, QuoteFetchOrigin } from '../types'; import { analytics } from '../util/analytics'; @@ -33,8 +34,12 @@ export const buyQuoteUpdater = { } const feePercentage = oc(options.affiliateInfo).feePercentage(); let newBuyQuote: BuyQuote | undefined; + const slippagePercentage = SLIPPAGE_PERCENTAGE; try { - newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { feePercentage }); + newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { + feePercentage, + slippagePercentage, + }); } catch (error) { const errorMessage = assetUtils.assetBuyerErrorMessage(asset, error); -- cgit v1.2.3 From c3884dfa32d0d8292163892934d7f243e813590f Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 14 Dec 2018 11:06:15 -0800 Subject: More tests for assetBuyerErrorMessage --- packages/instant/test/util/asset.test.ts | 41 +++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/test/util/asset.test.ts b/packages/instant/test/util/asset.test.ts index fc4e4e2e4..c13424685 100644 --- a/packages/instant/test/util/asset.test.ts +++ b/packages/instant/test/util/asset.test.ts @@ -1,5 +1,6 @@ -import { AssetBuyerError } from '@0x/asset-buyer'; +import { AssetBuyerError, InsufficientAssetLiquidityError, BigNumber } from '@0x/asset-buyer'; import { AssetProxyId, ObjectMap } from '@0x/types'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { Asset, AssetMetaData, ERC20Asset, ERC20AssetMetaData, Network, ZeroExInstantError } from '../../src/types'; import { assetUtils } from '../../src/util/asset'; @@ -19,6 +20,16 @@ const ZRX_ASSET: ERC20Asset = { const META_DATA_MAP: ObjectMap = { [ZRX_ASSET_DATA]: ZRX_META_DATA, }; +const WAX_ASSET: ERC20Asset = { + assetData: '0xf47261b000000000000000000000000039bb259f66e1c59d5abef88375979b4d20d98022', + metaData: { + assetProxyId: AssetProxyId.ERC20, + decimals: 8, + primaryColor: '#EDB740', + symbol: 'wax', + name: 'WAX', + }, +}; describe('assetDataUtil', () => { describe('bestNameForAsset', () => { @@ -47,13 +58,37 @@ describe('assetDataUtil', () => { }); }); describe('assetBuyerErrorMessage', () => { - it('should return message for InsufficientAssetLiquidity', () => { + it('should return message for generic InsufficientAssetLiquidity error', () => { const insufficientAssetError = new Error(AssetBuyerError.InsufficientAssetLiquidity); expect(assetUtils.assetBuyerErrorMessage(ZRX_ASSET, insufficientAssetError)).toEqual( 'Not enough ZRX available', ); }); - it('should return message for InsufficientAssetLiquidity', () => { + it('should return custom message for InsufficientAssetLiquidityError error for token w/ 18 decimals', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(20.059), 18); + expect( + assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('There are only 20.05 ZRX available to buy'); + }); + it('should return custom message for InsufficientAssetLiquidityError error for token w/ 18 decimals and small amount available', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.01), 18); + expect( + assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('There are only 0.01 ZRX available to buy'); + }); + it('should return custom message for InsufficientAssetLiquidityError error for token w/ 8 decimals', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(3), 8); + expect( + assetUtils.assetBuyerErrorMessage(WAX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('There are only 3 WAX available to buy'); + }); + it('should generic message for InsufficientAssetLiquidityError error when amount available rounds to zero', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.002), 18); + expect( + assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('Not enough ZRX available'); + }); + it('should return message for InsufficientZrxLiquidity', () => { const insufficientZrxError = new Error(AssetBuyerError.InsufficientZrxLiquidity); expect(assetUtils.assetBuyerErrorMessage(ZRX_ASSET, insufficientZrxError)).toEqual( 'Not enough ZRX available', -- cgit v1.2.3 From 3e596f6a8c211eb39917cfd2a9a68a6facf2c904 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 14 Dec 2018 11:08:21 -0800 Subject: Nesting errors --- packages/instant/test/util/asset.test.ts | 48 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/test/util/asset.test.ts b/packages/instant/test/util/asset.test.ts index c13424685..dbf2e15a5 100644 --- a/packages/instant/test/util/asset.test.ts +++ b/packages/instant/test/util/asset.test.ts @@ -64,29 +64,31 @@ describe('assetDataUtil', () => { 'Not enough ZRX available', ); }); - it('should return custom message for InsufficientAssetLiquidityError error for token w/ 18 decimals', () => { - const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(20.059), 18); - expect( - assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), - ).toEqual('There are only 20.05 ZRX available to buy'); - }); - it('should return custom message for InsufficientAssetLiquidityError error for token w/ 18 decimals and small amount available', () => { - const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.01), 18); - expect( - assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), - ).toEqual('There are only 0.01 ZRX available to buy'); - }); - it('should return custom message for InsufficientAssetLiquidityError error for token w/ 8 decimals', () => { - const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(3), 8); - expect( - assetUtils.assetBuyerErrorMessage(WAX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), - ).toEqual('There are only 3 WAX available to buy'); - }); - it('should generic message for InsufficientAssetLiquidityError error when amount available rounds to zero', () => { - const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.002), 18); - expect( - assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), - ).toEqual('Not enough ZRX available'); + describe('InsufficientAssetLiquidityError', () => { + it('should return custom message for token w/ 18 decimals', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(20.059), 18); + expect( + assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('There are only 20.05 ZRX available to buy'); + }); + it('should return custom message for token w/ 18 decimals and small amount available', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.01), 18); + expect( + assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('There are only 0.01 ZRX available to buy'); + }); + it('should return custom message for token w/ 8 decimals', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(3), 8); + expect( + assetUtils.assetBuyerErrorMessage(WAX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('There are only 3 WAX available to buy'); + }); + it('should generic message when amount available rounds to zero', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.002), 18); + expect( + assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('Not enough ZRX available'); + }); }); it('should return message for InsufficientZrxLiquidity', () => { const insufficientZrxError = new Error(AssetBuyerError.InsufficientZrxLiquidity); -- cgit v1.2.3 From 69054d85e80f9e41200015a9b0eef2a9fe00f439 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 14 Dec 2018 15:18:20 -0800 Subject: Only send in amountAvailableToFill if it's a non-zero amount, add additional tests and nest, and put error into its own file --- packages/instant/src/util/asset.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/util/asset.ts b/packages/instant/src/util/asset.ts index 5e83e7e6d..756194f1f 100644 --- a/packages/instant/src/util/asset.ts +++ b/packages/instant/src/util/asset.ts @@ -113,7 +113,11 @@ export const assetUtils = { assetBuyerErrorMessage: (asset: ERC20Asset, error: Error): string | undefined => { if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); - if (error instanceof InsufficientAssetLiquidityError) { + if ( + error instanceof InsufficientAssetLiquidityError && + error.amountAvailableToFill && + error.amountAvailableToFill.greaterThan(BIG_NUMBER_ZERO) + ) { const unitAmountAvailableToFill = Web3Wrapper.toUnitAmount( error.amountAvailableToFill, asset.metaData.decimals, -- cgit v1.2.3 From ab10119c5af208be60782395b1faff906f0948f2 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 14 Dec 2018 15:24:01 -0800 Subject: one more test for undefined --- packages/instant/test/util/asset.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/test/util/asset.test.ts b/packages/instant/test/util/asset.test.ts index dbf2e15a5..213e69dd8 100644 --- a/packages/instant/test/util/asset.test.ts +++ b/packages/instant/test/util/asset.test.ts @@ -83,7 +83,12 @@ describe('assetDataUtil', () => { assetUtils.assetBuyerErrorMessage(WAX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), ).toEqual('There are only 3 WAX available to buy'); }); - it('should generic message when amount available rounds to zero', () => { + it('should return generic message when InsufficientAssetLiquidityError contains undefined value', () => { + expect(assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError())).toEqual( + 'Not enough ZRX available', + ); + }); + it('should return generic message when amount available rounds to zero', () => { const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.002), 18); expect( assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), -- cgit v1.2.3 From c8c8219c055cc5798cf5cdc71199ee7ae505cd5a Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 21 Dec 2018 16:26:07 -0800 Subject: Make amountAvailableToFill required --- packages/instant/src/util/asset.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/util/asset.ts b/packages/instant/src/util/asset.ts index e7aa55c88..b009a327f 100644 --- a/packages/instant/src/util/asset.ts +++ b/packages/instant/src/util/asset.ts @@ -115,7 +115,6 @@ export const assetUtils = { const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); if ( error instanceof InsufficientAssetLiquidityError && - error.amountAvailableToFill && error.amountAvailableToFill.greaterThan(BIG_NUMBER_ZERO) ) { const unitAmountAvailableToFill = Web3Wrapper.toUnitAmount( -- cgit v1.2.3 From 89f67b9becf3b4c0d13cceeaca4d5656ad500a9a Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 2 Jan 2019 16:56:28 -0800 Subject: take out no-longer necessary test --- packages/instant/test/util/asset.test.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/test/util/asset.test.ts b/packages/instant/test/util/asset.test.ts index 213e69dd8..402a556d5 100644 --- a/packages/instant/test/util/asset.test.ts +++ b/packages/instant/test/util/asset.test.ts @@ -1,4 +1,4 @@ -import { AssetBuyerError, InsufficientAssetLiquidityError, BigNumber } from '@0x/asset-buyer'; +import { AssetBuyerError, BigNumber, InsufficientAssetLiquidityError } from '@0x/asset-buyer'; import { AssetProxyId, ObjectMap } from '@0x/types'; import { Web3Wrapper } from '@0x/web3-wrapper'; @@ -83,11 +83,6 @@ describe('assetDataUtil', () => { assetUtils.assetBuyerErrorMessage(WAX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), ).toEqual('There are only 3 WAX available to buy'); }); - it('should return generic message when InsufficientAssetLiquidityError contains undefined value', () => { - expect(assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError())).toEqual( - 'Not enough ZRX available', - ); - }); it('should return generic message when amount available rounds to zero', () => { const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.002), 18); expect( -- cgit v1.2.3 From ffd14ab2f2b625574bdd1e8ce96189ef18782f3b Mon Sep 17 00:00:00 2001 From: fragosti Date: Thu, 10 Jan 2019 09:47:46 -0800 Subject: feature: implement logging and friendly wallet name for Opera --- packages/instant/src/constants.ts | 1 + packages/instant/src/types.ts | 1 + packages/instant/src/util/env.ts | 9 ++++++--- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 67558c84a..bfd9e9098 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -74,5 +74,6 @@ export const PROVIDER_TYPE_TO_NAME: { [key in ProviderType]: string } = { [ProviderType.CoinbaseWallet]: 'Coinbase Wallet', [ProviderType.Parity]: 'Parity', [ProviderType.TrustWallet]: 'Trust Wallet', + [ProviderType.Opera]: 'Opera Wallet', [ProviderType.Fallback]: 'Fallback', }; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index ae672c919..f07a407da 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -183,6 +183,7 @@ export enum ProviderType { CoinbaseWallet = 'COINBASE_WALLET', Cipher = 'CIPHER', TrustWallet = 'TRUST_WALLET', + Opera = 'OPERA', Fallback = 'FALLBACK', } diff --git a/packages/instant/src/util/env.ts b/packages/instant/src/util/env.ts index aedf4f5d6..7d4f836ff 100644 --- a/packages/instant/src/util/env.ts +++ b/packages/instant/src/util/env.ts @@ -42,18 +42,21 @@ export const envUtil = { } }, getProviderType(provider: Provider): ProviderType | undefined { + const anyProvider = provider as any; if (provider.constructor.name === 'EthereumProvider') { return ProviderType.Mist; - } else if ((provider as any).isTrust) { + } else if (anyProvider.isTrust) { return ProviderType.TrustWallet; - } else if ((provider as any).isParity) { + } else if (anyProvider.isParity) { return ProviderType.Parity; - } else if ((provider as any).isMetaMask) { + } else if (anyProvider.isMetaMask) { return ProviderType.MetaMask; } else if (!_.isUndefined(_.get(window, 'SOFA'))) { return ProviderType.CoinbaseWallet; } else if (!_.isUndefined(_.get(window, '__CIPHER__'))) { return ProviderType.Cipher; + } else if (envUtil.getBrowser() === Browser.Opera && !anyProvider.isMetaMask) { + return ProviderType.Opera; } return; }, -- cgit v1.2.3