Commit 3680b93f authored by Moody Salem's avatar Moody Salem

make the way we get the v2 router consistent, start working through changes in the swap callback

parent 8e86ded0
import { Contract } from '@ethersproject/contracts' import { Contract } from '@ethersproject/contracts'
import { ChainId, WETH9 } from '@uniswap/sdk-core'
import { abi as GOVERNANCE_ABI } from '@uniswap/governance/build/GovernorAlpha.json' import { abi as GOVERNANCE_ABI } from '@uniswap/governance/build/GovernorAlpha.json'
import { abi as UNI_ABI } from '@uniswap/governance/build/Uni.json' import { abi as UNI_ABI } from '@uniswap/governance/build/Uni.json'
import { abi as STAKING_REWARDS_ABI } from '@uniswap/liquidity-staker/build/StakingRewards.json' import { abi as STAKING_REWARDS_ABI } from '@uniswap/liquidity-staker/build/StakingRewards.json'
import { abi as MERKLE_DISTRIBUTOR_ABI } from '@uniswap/merkle-distributor/build/MerkleDistributor.json' import { abi as MERKLE_DISTRIBUTOR_ABI } from '@uniswap/merkle-distributor/build/MerkleDistributor.json'
import { ChainId, WETH9 } from '@uniswap/sdk-core'
import { abi as IUniswapV2PairABI } from '@uniswap/v2-core/build/IUniswapV2Pair.json' import { abi as IUniswapV2PairABI } from '@uniswap/v2-core/build/IUniswapV2Pair.json'
import { abi as V3FactoryABI } from '@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json' import { abi as V3FactoryABI } from '@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json'
import { abi as V3PoolABI } from '@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json' import { abi as V3PoolABI } from '@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json'
import { abi as QuoterABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json' import { abi as QuoterABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json'
import { abi as V2MigratorABI } from '@uniswap/v3-periphery/artifacts/contracts/V3Migrator.sol/V3Migrator.json' import { abi as V2MigratorABI } from '@uniswap/v3-periphery/artifacts/contracts/V3Migrator.sol/V3Migrator.json'
import { abi as TickLensABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/TickLens.sol/TickLens.json' import { abi as TickLensABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/TickLens.sol/TickLens.json'
import { abi as IUniswapV2Router02ABI } from '@uniswap/v2-periphery/build/IUniswapV2Router02.json'
import ARGENT_WALLET_DETECTOR_ABI from 'abis/argent-wallet-detector.json' import ARGENT_WALLET_DETECTOR_ABI from 'abis/argent-wallet-detector.json'
import ENS_PUBLIC_RESOLVER_ABI from 'abis/ens-public-resolver.json' import ENS_PUBLIC_RESOLVER_ABI from 'abis/ens-public-resolver.json'
...@@ -21,6 +22,7 @@ import MULTICALL_ABI from 'abis/multicall2.json' ...@@ -21,6 +22,7 @@ import MULTICALL_ABI from 'abis/multicall2.json'
import { Unisocks } from 'abis/types/Unisocks' import { Unisocks } from 'abis/types/Unisocks'
import UNISOCKS_ABI from 'abis/unisocks.json' import UNISOCKS_ABI from 'abis/unisocks.json'
import WETH_ABI from 'abis/weth.json' import WETH_ABI from 'abis/weth.json'
import { import {
ARGENT_WALLET_DETECTOR_MAINNET_ADDRESS, ARGENT_WALLET_DETECTOR_MAINNET_ADDRESS,
GOVERNANCE_ADDRESS, GOVERNANCE_ADDRESS,
...@@ -28,6 +30,7 @@ import { ...@@ -28,6 +30,7 @@ import {
V1_MIGRATOR_ADDRESS, V1_MIGRATOR_ADDRESS,
UNI, UNI,
MULTICALL2_ADDRESSES, MULTICALL2_ADDRESSES,
V2_ROUTER_ADDRESS,
} from 'constants/index' } from 'constants/index'
import { abi as NFTPositionManagerABI } from '@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json' import { abi as NFTPositionManagerABI } from '@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'
import { import {
...@@ -116,6 +119,10 @@ export function usePairContract(pairAddress?: string, withSignerIfPossible?: boo ...@@ -116,6 +119,10 @@ export function usePairContract(pairAddress?: string, withSignerIfPossible?: boo
return useContract(pairAddress, IUniswapV2PairABI, withSignerIfPossible) return useContract(pairAddress, IUniswapV2PairABI, withSignerIfPossible)
} }
export function useV2RouterContract(): Contract | null {
return useContract(V2_ROUTER_ADDRESS, IUniswapV2Router02ABI, true)
}
export function useMulticall2Contract(): Multicall2 | null { export function useMulticall2Contract(): Multicall2 | null {
const { chainId } = useActiveWeb3React() const { chainId } = useActiveWeb3React()
return useContract(chainId && MULTICALL2_ADDRESSES[chainId], MULTICALL_ABI, false) as Multicall2 return useContract(chainId && MULTICALL2_ADDRESSES[chainId], MULTICALL_ABI, false) as Multicall2
......
import JSBI from 'jsbi'
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { Contract } from '@ethersproject/contracts' import { Contract } from '@ethersproject/contracts'
import { JSBI, Router, SwapParameters, Trade } from '@uniswap/v2-sdk' import { Router, SwapParameters, Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk'
import { Percent, TradeType } from '@uniswap/sdk-core' import { Percent, TradeType } from '@uniswap/sdk-core'
import { useMemo } from 'react' import { useMemo } from 'react'
import { BIPS_BASE, INITIAL_ALLOWED_SLIPPAGE } from '../constants' import { BIPS_BASE, INITIAL_ALLOWED_SLIPPAGE } from '../constants'
import { getTradeVersion } from '../utils/getTradeVersion' import { getTradeVersion } from '../utils/getTradeVersion'
import { useTransactionAdder } from '../state/transactions/hooks' import { useTransactionAdder } from '../state/transactions/hooks'
import { calculateGasMargin, getRouterContract, isAddress, shortenAddress } from '../utils' import { calculateGasMargin, isAddress, shortenAddress } from '../utils'
import isZero from '../utils/isZero' import isZero from '../utils/isZero'
import { useActiveWeb3React } from './index' import { useActiveWeb3React } from './index'
import { useV2RouterContract } from './useContract'
import useTransactionDeadline from './useTransactionDeadline' import useTransactionDeadline from './useTransactionDeadline'
import useENS from './useENS' import useENS from './useENS'
import { Version } from './useToggledVersion' import { Version } from './useToggledVersion'
...@@ -43,7 +46,7 @@ type EstimatedSwapCall = SuccessfulCall | FailedCall ...@@ -43,7 +46,7 @@ type EstimatedSwapCall = SuccessfulCall | FailedCall
* @param recipientAddressOrName * @param recipientAddressOrName
*/ */
function useSwapCallArguments( function useSwapCallArguments(
trade: Trade | undefined, // trade to execute, required trade: V2Trade | V3Trade | undefined, // trade to execute, required
allowedSlippage: number = INITIAL_ALLOWED_SLIPPAGE, // in bips allowedSlippage: number = INITIAL_ALLOWED_SLIPPAGE, // in bips
recipientAddressOrName: string | null // the ENS name or address of the recipient of the trade, or null if swap should be returned to sender recipientAddressOrName: string | null // the ENS name or address of the recipient of the trade, or null if swap should be returned to sender
): SwapCall[] { ): SwapCall[] {
...@@ -53,43 +56,43 @@ function useSwapCallArguments( ...@@ -53,43 +56,43 @@ function useSwapCallArguments(
const recipient = recipientAddressOrName === null ? account : recipientAddress const recipient = recipientAddressOrName === null ? account : recipientAddress
const deadline = useTransactionDeadline() const deadline = useTransactionDeadline()
return useMemo(() => { const routerContract = useV2RouterContract()
if (!trade || !recipient || !library || !account || !chainId || !deadline) return []
const contract: Contract | null = getRouterContract(chainId, library, account)
if (!contract) {
return []
}
const swapMethods = [] return useMemo(() => {
if (!trade || !recipient || !library || !account || !chainId || !deadline || !routerContract) return []
swapMethods.push(
Router.swapCallParameters(trade, {
feeOnTransfer: false,
allowedSlippage: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE),
recipient,
deadline: deadline.toNumber(),
})
)
if (trade.tradeType === TradeType.EXACT_INPUT) { if (trade instanceof V2Trade) {
const swapMethods = []
swapMethods.push( swapMethods.push(
Router.swapCallParameters(trade, { Router.swapCallParameters(trade, {
feeOnTransfer: true, feeOnTransfer: false,
allowedSlippage: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE), allowedSlippage: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE),
recipient, recipient,
deadline: deadline.toNumber(), deadline: deadline.toNumber(),
}) })
) )
if (trade.tradeType === TradeType.EXACT_INPUT) {
swapMethods.push(
Router.swapCallParameters(trade, {
feeOnTransfer: true,
allowedSlippage: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE),
recipient,
deadline: deadline.toNumber(),
})
)
}
return swapMethods.map((parameters) => ({ parameters, contract: routerContract }))
} }
return swapMethods.map((parameters) => ({ parameters, contract }))
}, [account, allowedSlippage, chainId, deadline, library, recipient, trade]) return []
}, [account, allowedSlippage, chainId, deadline, library, recipient, routerContract, trade])
} }
// returns a function that will execute a swap, if the parameters are all valid // returns a function that will execute a swap, if the parameters are all valid
// and the user has approved the slippage adjusted input amount for the trade // and the user has approved the slippage adjusted input amount for the trade
export function useV2SwapCallback( export function useSwapCallback(
trade: Trade | undefined, // trade to execute, required trade: V2Trade | V3Trade | undefined, // trade to execute, required
allowedSlippage: number = INITIAL_ALLOWED_SLIPPAGE, // in bips allowedSlippage: number = INITIAL_ALLOWED_SLIPPAGE, // in bips
recipientAddressOrName: string | null // the ENS name or address of the recipient of the trade, or null if swap should be returned to sender recipientAddressOrName: string | null // the ENS name or address of the recipient of the trade, or null if swap should be returned to sender
): { state: SwapCallbackState; callback: null | (() => Promise<string>); error: string | null } { ): { state: SwapCallbackState; callback: null | (() => Promise<string>); error: string | null } {
......
...@@ -18,6 +18,7 @@ import { MinimalPositionCard } from '../../components/PositionCard' ...@@ -18,6 +18,7 @@ import { MinimalPositionCard } from '../../components/PositionCard'
import Row, { RowBetween, RowFlat } from '../../components/Row' import Row, { RowBetween, RowFlat } from '../../components/Row'
import { V2_ROUTER_ADDRESS } from '../../constants' import { V2_ROUTER_ADDRESS } from '../../constants'
import { useV2RouterContract } from '../../hooks/useContract'
import { PairState } from '../../hooks/useV2Pairs' import { PairState } from '../../hooks/useV2Pairs'
import { useActiveWeb3React } from '../../hooks' import { useActiveWeb3React } from '../../hooks'
import { useCurrency } from '../../hooks/Tokens' import { useCurrency } from '../../hooks/Tokens'
...@@ -31,7 +32,7 @@ import { useMintActionHandlers, useMintState } from '../../state/mint/hooks' ...@@ -31,7 +32,7 @@ import { useMintActionHandlers, useMintState } from '../../state/mint/hooks'
import { useTransactionAdder } from '../../state/transactions/hooks' import { useTransactionAdder } from '../../state/transactions/hooks'
import { useIsExpertMode, useUserSlippageTolerance } from '../../state/user/hooks' import { useIsExpertMode, useUserSlippageTolerance } from '../../state/user/hooks'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { calculateGasMargin, calculateSlippageAmount, getRouterContract } from '../../utils' import { calculateGasMargin, calculateSlippageAmount } from '../../utils'
import { maxAmountSpend } from '../../utils/maxAmountSpend' import { maxAmountSpend } from '../../utils/maxAmountSpend'
import { wrappedCurrency } from '../../utils/wrappedCurrency' import { wrappedCurrency } from '../../utils/wrappedCurrency'
import AppBody from '../AppBody' import AppBody from '../AppBody'
...@@ -126,9 +127,10 @@ export default function AddLiquidity({ ...@@ -126,9 +127,10 @@ export default function AddLiquidity({
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
const router = useV2RouterContract()
async function onAdd() { async function onAdd() {
if (!chainId || !library || !account) return if (!chainId || !library || !account || !router) return
const router = getRouterContract(chainId, library, account)
const { [Field.CURRENCY_A]: parsedAmountA, [Field.CURRENCY_B]: parsedAmountB } = parsedAmounts const { [Field.CURRENCY_A]: parsedAmountA, [Field.CURRENCY_B]: parsedAmountB } = parsedAmounts
if (!parsedAmountA || !parsedAmountB || !currencyA || !currencyB || !deadline) { if (!parsedAmountA || !parsedAmountB || !currencyA || !currencyB || !deadline) {
......
...@@ -23,13 +23,13 @@ import CurrencyLogo from '../../components/CurrencyLogo' ...@@ -23,13 +23,13 @@ import CurrencyLogo from '../../components/CurrencyLogo'
import { V2_ROUTER_ADDRESS } from '../../constants' import { V2_ROUTER_ADDRESS } from '../../constants'
import { useActiveWeb3React } from '../../hooks' import { useActiveWeb3React } from '../../hooks'
import { useCurrency } from '../../hooks/Tokens' import { useCurrency } from '../../hooks/Tokens'
import { usePairContract } from '../../hooks/useContract' import { usePairContract, useV2RouterContract } from '../../hooks/useContract'
import useIsArgentWallet from '../../hooks/useIsArgentWallet' import useIsArgentWallet from '../../hooks/useIsArgentWallet'
import useTransactionDeadline from '../../hooks/useTransactionDeadline' import useTransactionDeadline from '../../hooks/useTransactionDeadline'
import { useTransactionAdder } from '../../state/transactions/hooks' import { useTransactionAdder } from '../../state/transactions/hooks'
import { StyledInternalLink, TYPE } from '../../theme' import { StyledInternalLink, TYPE } from '../../theme'
import { calculateGasMargin, calculateSlippageAmount, getRouterContract } from '../../utils' import { calculateGasMargin, calculateSlippageAmount } from '../../utils'
import { currencyId } from '../../utils/currencyId' import { currencyId } from '../../utils/currencyId'
import useDebouncedChangeHandler from '../../hooks/useDebouncedChangeHandler' import useDebouncedChangeHandler from '../../hooks/useDebouncedChangeHandler'
import { wrappedCurrency } from '../../utils/wrappedCurrency' import { wrappedCurrency } from '../../utils/wrappedCurrency'
...@@ -192,13 +192,14 @@ export default function RemoveLiquidity({ ...@@ -192,13 +192,14 @@ export default function RemoveLiquidity({
// tx sending // tx sending
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
const router = useV2RouterContract()
async function onRemove() { async function onRemove() {
if (!chainId || !library || !account || !deadline) throw new Error('missing dependencies') if (!chainId || !library || !account || !deadline || !router) throw new Error('missing dependencies')
const { [Field.CURRENCY_A]: currencyAmountA, [Field.CURRENCY_B]: currencyAmountB } = parsedAmounts const { [Field.CURRENCY_A]: currencyAmountA, [Field.CURRENCY_B]: currencyAmountB } = parsedAmounts
if (!currencyAmountA || !currencyAmountB) { if (!currencyAmountA || !currencyAmountB) {
throw new Error('missing currency amounts') throw new Error('missing currency amounts')
} }
const router = getRouterContract(chainId, library, account)
const amountsMin = { const amountsMin = {
[Field.CURRENCY_A]: calculateSlippageAmount(currencyAmountA, allowedSlippage)[0], [Field.CURRENCY_A]: calculateSlippageAmount(currencyAmountA, allowedSlippage)[0],
...@@ -243,7 +244,7 @@ export default function RemoveLiquidity({ ...@@ -243,7 +244,7 @@ export default function RemoveLiquidity({
] ]
} }
} }
// we have a signataure, use permit versions of remove liquidity // we have a signature, use permit versions of remove liquidity
else if (signatureData !== null) { else if (signatureData !== null) {
// removeLiquidityETHWithPermit // removeLiquidityETHWithPermit
if (oneCurrencyIsETH) { if (oneCurrencyIsETH) {
......
...@@ -29,7 +29,7 @@ import { useCurrency, useAllTokens } from '../../hooks/Tokens' ...@@ -29,7 +29,7 @@ import { useCurrency, useAllTokens } from '../../hooks/Tokens'
import { ApprovalState, useApproveCallbackFromTrade } from '../../hooks/useApproveCallback' import { ApprovalState, useApproveCallbackFromTrade } from '../../hooks/useApproveCallback'
import useENSAddress from '../../hooks/useENSAddress' import useENSAddress from '../../hooks/useENSAddress'
import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported' import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported'
import { useV2SwapCallback } from '../../hooks/useV2SwapCallback' import { useSwapCallback } from '../../hooks/useSwapCallback'
import useWrapCallback, { WrapType } from '../../hooks/useWrapCallback' import useWrapCallback, { WrapType } from '../../hooks/useWrapCallback'
import { useWalletModalToggle } from '../../state/application/hooks' import { useWalletModalToggle } from '../../state/application/hooks'
import { Field } from '../../state/swap/actions' import { Field } from '../../state/swap/actions'
...@@ -189,7 +189,7 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -189,7 +189,7 @@ export default function Swap({ history }: RouteComponentProps) {
const atMaxAmountInput = Boolean(maxAmountInput && parsedAmounts[Field.INPUT]?.equalTo(maxAmountInput)) const atMaxAmountInput = Boolean(maxAmountInput && parsedAmounts[Field.INPUT]?.equalTo(maxAmountInput))
// the callback to execute the swap // the callback to execute the swap
const { callback: swapCallback, error: swapCallbackError } = useV2SwapCallback( const { callback: swapCallback, error: swapCallbackError } = useSwapCallback(
trade instanceof V2Trade ? trade : undefined, trade instanceof V2Trade ? trade : undefined,
allowedSlippage, allowedSlippage,
recipient recipient
......
...@@ -5,6 +5,5 @@ import { Version } from '../hooks/useToggledVersion' ...@@ -5,6 +5,5 @@ import { Version } from '../hooks/useToggledVersion'
export function getTradeVersion(trade?: V2Trade | V3Trade): Version | undefined { export function getTradeVersion(trade?: V2Trade | V3Trade): Version | undefined {
if (!trade) return undefined if (!trade) return undefined
if (trade instanceof V2Trade) return Version.v2 if (trade instanceof V2Trade) return Version.v2
if (trade instanceof V3Trade) return Version.v3 return Version.v3
throw new Error('Unknown trade type')
} }
import { FeeAmount } from '@uniswap/v3-sdk'
import { Contract } from '@ethersproject/contracts' import { Contract } from '@ethersproject/contracts'
import { getAddress } from '@ethersproject/address' import { getAddress } from '@ethersproject/address'
import { AddressZero } from '@ethersproject/constants' import { AddressZero } from '@ethersproject/constants'
import { JsonRpcSigner, Web3Provider } from '@ethersproject/providers' import { JsonRpcSigner, Web3Provider } from '@ethersproject/providers'
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { abi as IUniswapV2Router02ABI } from '@uniswap/v2-periphery/build/IUniswapV2Router02.json'
import { V2_ROUTER_ADDRESS } from '../constants'
import { ChainId, Percent, Token, CurrencyAmount, Currency, ETHER } from '@uniswap/sdk-core' import { ChainId, Percent, Token, CurrencyAmount, Currency, ETHER } from '@uniswap/sdk-core'
import { JSBI } from '@uniswap/v2-sdk' import { JSBI } from '@uniswap/v2-sdk'
import { FeeAmount } from '@uniswap/v3-sdk/dist/'
import { TokenAddressMap } from '../state/lists/hooks' import { TokenAddressMap } from '../state/lists/hooks'
// returns the checksummed address if the address is valid, otherwise returns false // returns the checksummed address if the address is valid, otherwise returns false
...@@ -100,11 +97,6 @@ export function getContract(address: string, ABI: any, library: Web3Provider, ac ...@@ -100,11 +97,6 @@ export function getContract(address: string, ABI: any, library: Web3Provider, ac
return new Contract(address, ABI, getProviderOrSigner(library, account) as any) return new Contract(address, ABI, getProviderOrSigner(library, account) as any)
} }
// account is optional
export function getRouterContract(_: number, library: Web3Provider, account?: string): Contract {
return getContract(V2_ROUTER_ADDRESS, IUniswapV2Router02ABI, library, account)
}
export function escapeRegExp(string: string): string { export function escapeRegExp(string: string): string {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
} }
...@@ -126,6 +118,6 @@ export function supportedChainId(chainId: number): ChainId | undefined { ...@@ -126,6 +118,6 @@ export function supportedChainId(chainId: number): ChainId | undefined {
return undefined return undefined
} }
export const formattedFeeAmount = (feeAmount: FeeAmount): number => { export function formattedFeeAmount(feeAmount: FeeAmount): number {
return feeAmount / 10000 return feeAmount / 10000
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment