Skip to content
This repository was archived by the owner on Apr 11, 2023. It is now read-only.

Commit

Permalink
PR changes/improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
DaoDev44 committed Sep 28, 2021
1 parent ccf65bf commit a76639e
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 64 deletions.
1 change: 1 addition & 0 deletions packages/swapper/src/swappers/zrx/ZrxSwapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const BTC = ({
sendSupport: false,
receiveSupport: false,
symbol: 'BTC'
// TODO: remove the type casts from test files when we unify `ChainTypes` and `ChainIdentifier`
} as unknown) as Asset
const WETH = ({
name: 'WETH',
Expand Down
17 changes: 3 additions & 14 deletions packages/swapper/src/swappers/zrx/ZrxSwapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { BuildQuoteTxArgs, GetQuoteInput, Quote, Swapper, SwapperType } from '..

import { buildQuoteTx } from './buildQuoteTx/buildQuoteTx'
import { getZrxQuote } from './getQuote/getQuote'
import { getDeps } from '../zrx/utils/helpers/helpers'

export type ZrxSwapperDeps = {
adapterManager: ChainAdapterManager
Expand All @@ -21,28 +20,18 @@ export class ZrxError extends Error {

export class ZrxSwapper implements Swapper {
public static swapperName = 'ZrxSwapper'
adapterManager: ChainAdapterManager
web3: Web3
deps: ZrxSwapperDeps

constructor(deps: ZrxSwapperDeps) {
this.adapterManager = deps.adapterManager
this.web3 = deps.web3
}

private getDeps<
T extends typeof ZrxSwapper,
P = Parameters<typeof getDeps>[],
R = ReturnType<typeof getDeps>
>(): R {
return getDeps.call<T, P[], R>((this as unknown) as T)
this.deps = deps
}

getType() {
return SwapperType.Zrx
}

async buildQuoteTx({ input, wallet }: BuildQuoteTxArgs): Promise<Quote> {
return buildQuoteTx(this.getDeps(), { input, wallet })
return buildQuoteTx(this.deps, { input, wallet })
}

async getQuote(input: GetQuoteInput): Promise<Quote> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { buildQuoteTx } from './buildQuoteTx'
import { setupQuote } from '../utils/test-data/setupSwapQuote'
import { GetQuoteInput } from '../../../api'
import { zrxService } from '../utils/zrxService'
import { APPROVAL_GAS_LIMIT, MAX_SLIPPAGE } from '../utils/constants'

jest.mock('web3')

Expand Down Expand Up @@ -142,6 +143,15 @@ describe('buildQuoteTx', () => {
)
})

it.only(`should throw error if slippage is higher than ${MAX_SLIPPAGE}%`, async () => {
const slippage = '31.0'
const input = { ...quoteInput, slippage }

await expect(buildQuoteTx(deps, { input, wallet })).rejects.toThrow(
`ZrxSwapper:buildQuoteTx slippage value of ${slippage} is greater than max slippage value of ${MAX_SLIPPAGE}`
)
})

it('should throw error if tokenId, symbol and network are not provided for buyAsset', async () => {
const input = ({
...quoteInput,
Expand Down Expand Up @@ -213,7 +223,7 @@ describe('buildQuoteTx', () => {
})
})

it('should return a quote response with gasPrice times estimatedGas', async () => {
it('should return a quote response with gasPrice multiplied by estimatedGas', async () => {
const gasPrice = '10000'
const estimatedGas = '100'
const data = {
Expand All @@ -227,7 +237,7 @@ describe('buildQuoteTx', () => {
...mockQuoteResponse,
feeData: {
...mockQuoteResponse.feeData,
approvalFee: '1000000000',
approvalFee: new BigNumber(APPROVAL_GAS_LIMIT).multipliedBy(gasPrice).toString(),
gasPrice,
estimatedGas,
fee: new BigNumber(gasPrice).multipliedBy(estimatedGas).toString()
Expand All @@ -249,7 +259,7 @@ describe('buildQuoteTx', () => {
})
})

it('should throw on api call status of 400', async () => {
it('should throw on api error status of 400', async () => {
;(zrxService.get as jest.Mock<unknown>).mockImplementation(() =>
Promise.reject({ response: { data: { code: 400 } } })
)
Expand All @@ -263,7 +273,7 @@ describe('buildQuoteTx', () => {
})
})

it('should throw on api call status of 500', async () => {
it('should throw on api error status of 500', async () => {
;(zrxService.get as jest.Mock<unknown>).mockImplementation(() =>
Promise.reject({ response: { data: { code: 500 } } })
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
DEFAULT_SOURCE,
DEFAULT_ETH_PATH,
AFFILIATE_ADDRESS,
APPROVAL_GAS_LIMIT
APPROVAL_GAS_LIMIT,
MAX_SLIPPAGE
} from '../utils/constants'

type LiquiditySource = {
Expand Down Expand Up @@ -86,6 +87,12 @@ export async function buildQuoteTx(
)
const receiveAddress = await adapter.getAddress({ wallet, path: DEFAULT_ETH_PATH })

if (new BigNumber(slippage || 0).gt(MAX_SLIPPAGE)) {
throw new SwapError(
`ZrxSwapper:buildQuoteTx slippage value of ${slippage} is greater than max slippage value of ${MAX_SLIPPAGE}`
)
}

const slippagePercentage = slippage
? new BigNumber(slippage).div(100).toString()
: DEFAULT_SLIPPAGE
Expand Down
9 changes: 5 additions & 4 deletions packages/swapper/src/swappers/zrx/getQuote/getQuote.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jest.mock('../utils/zrxService')
const setupQuote = () => {
const sellAmount = '1000000000000000000'
;(normalizeAmount as jest.Mock<unknown>).mockReturnValue(sellAmount)
const sellAsset = {
const sellAsset = ({
name: 'Fox',
chain: ChainTypes.Ethereum,
network: NetworkTypes.MAINNET,
Expand All @@ -29,8 +29,9 @@ const setupQuote = () => {
sendSupport: true,
receiveSupport: true,
symbol: 'FOX'
} as unknown as Asset
const buyAsset = {
// TODO: remove the type casts from test files when we unify `ChainTypes` and `ChainIdentifier`
} as unknown) as Asset
const buyAsset = ({
name: 'WETH',
chain: ChainTypes.Ethereum,
network: NetworkTypes.MAINNET,
Expand All @@ -45,7 +46,7 @@ const setupQuote = () => {
sendSupport: true,
receiveSupport: true,
symbol: 'WETH'
} as unknown as Asset
} as unknown) as Asset

const quoteInput = {
sellAsset,
Expand Down
1 change: 0 additions & 1 deletion packages/swapper/src/swappers/zrx/utils/applyAxiosRetry.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AxiosInstance, AxiosRequestConfig } from 'axios'
import { attach, RetryConfig } from 'retry-axios'

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type PartialRaxConfig = { raxConfig?: RetryConfig } & AxiosRequestConfig

export function applyAxiosRetry(
Expand Down
3 changes: 2 additions & 1 deletion packages/swapper/src/swappers/zrx/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ export const MAX_GAS_PRICE = '1000000000000' // 1000 GWei
export const MAX_ZRX_TRADE = '100000000000000000000000000'
export const DEFAULT_SOURCE = [{ name: '0x', proportion: '1' }]
export const DEFAULT_SLIPPAGE = '3.0' // 3%
export const DEFAULT_ETH_PATH = `m/44'/60'/0'/0/0`
export const MAX_SLIPPAGE = '30.0' // 30%
export const DEFAULT_ETH_PATH = `m/44'/60'/0'/0/0` // TODO: remove when `adapter.getAddress` changes to take an account instead of default path
export const AFFILIATE_ADDRESS = '0xc770eefad204b5180df6a14ee197d99d808ee52d'
23 changes: 4 additions & 19 deletions packages/swapper/src/swappers/zrx/utils/helpers/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import Web3 from 'web3'
import BigNumber from 'bignumber.js'
import { setupQuote } from '../test-data/setupSwapQuote'
import { ChainAdapterManager, ChainIdentifier } from '@shapeshiftoss/chain-adapters'
import { erc20AllowanceAbi } from '../../utils/abi/erc20-abi'
import { normalizeAmount, getAllowanceRequired, getDeps } from '../helpers/helpers'
import { ZrxSwapper } from '../../ZrxSwapper'
import { normalizeAmount, getAllowanceRequired } from '../helpers/helpers'

jest.mock('web3')

Expand All @@ -22,20 +20,16 @@ Web3.mockImplementation(() => ({
}))

const setup = () => {
const unchainedUrls = {
[ChainIdentifier.Ethereum]: 'http://localhost:31300/api/v1'
}
const ethNodeUrl = 'http://localhost:1000'
const adapterManager = new ChainAdapterManager(unchainedUrls)
const web3Provider = new Web3.providers.HttpProvider(ethNodeUrl)
const web3Instance = new Web3(web3Provider)

return { web3Instance, adapterManager }
return { web3Instance }
}

describe('utils', () => {
const { quoteInput, sellAsset } = setupQuote()
const { web3Instance, adapterManager } = setup()
const { web3Instance } = setup()

describe('normalizeAmount', () => {
it('should return undefined if not amount is given', () => {
Expand Down Expand Up @@ -74,7 +68,7 @@ describe('utils', () => {
).toEqual(new BigNumber(quoteInput.sellAmount))
})

it('should thow error if allowanceOnChain is undefined', async () => {
it('should throw error if allowanceOnChain is undefined', async () => {
const allowanceOnChain = undefined
;(web3Instance.eth.Contract as jest.Mock<unknown>).mockImplementation(() => ({
methods: {
Expand Down Expand Up @@ -131,13 +125,4 @@ describe('utils', () => {
)
})
})

describe('getDeps', () => {
it('returns dependency list for binded class', () => {
const deps = { web3: web3Instance, adapterManager }
const swapper = new ZrxSwapper(deps)
expect(getDeps.call(swapper)).toEqual(deps)
})
})

})
16 changes: 0 additions & 16 deletions packages/swapper/src/swappers/zrx/utils/helpers/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import BigNumber from 'bignumber.js'
import { AbiItem } from 'web3-utils'
import Web3 from 'web3'
import { Quote, SwapError } from '../../../../api'
import { ThorchainSwapper } from '../../..'
import { ZrxSwapper } from '../../ZrxSwapper'
import { Swapper } from '../../../..'

export type GetAllowanceRequiredArgs = {
quote: Quote
Expand Down Expand Up @@ -51,16 +48,3 @@ export const getAllowanceRequired = async ({
const allowanceRequired = new BigNumber(quote.sellAmount || 0).minus(allowanceOnChain)
return allowanceRequired.lt(0) ? new BigNumber(0) : allowanceRequired
}

export function getDeps<
T extends typeof ZrxSwapper | typeof ThorchainSwapper,
D = ConstructorParameters<T>[0]
>(this: T): D {
const initial = <D>{}
type K = keyof D
type Entry = [K, D[K]]
return (Object.entries(this) as Entry[]).reduce((deps, args) => {
deps[args[0]] = args[1]
return deps
}, initial)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ContractTypes, NetworkTypes, ChainTypes, Asset } from '@shapeshiftoss/a
import { DEFAULT_SLIPPAGE } from '../constants'

export const setupQuote = () => {
const sellAsset = {
const sellAsset = ({
name: 'Fox',
chain: ChainTypes.Ethereum,
network: NetworkTypes.MAINNET,
Expand All @@ -15,8 +15,9 @@ export const setupQuote = () => {
sendSupport: true,
receiveSupport: true,
symbol: 'FOX'
} as unknown as Asset
const buyAsset = {
// TODO: remove the type casts from test files when we unify `ChainTypes` and `ChainIdentifier`
} as unknown) as Asset
const buyAsset = ({
name: 'WETH',
chain: ChainTypes.Ethereum,
network: NetworkTypes.MAINNET,
Expand All @@ -31,7 +32,7 @@ export const setupQuote = () => {
sendSupport: true,
receiveSupport: true,
symbol: 'WETH'
} as unknown as Asset
} as unknown) as Asset

const quoteInput = {
sellAsset,
Expand Down

0 comments on commit a76639e

Please sign in to comment.