Commit d342ccdb authored by Noah Zinsmeister's avatar Noah Zinsmeister

use sdk for more calldata

parent 3a34c2ec
...@@ -90,13 +90,15 @@ function useSwapCallArguments( ...@@ -90,13 +90,15 @@ function useSwapCallArguments(
})) }))
} else { } else {
// trade is V3Trade // trade is V3Trade
const swapRouterAddress = SWAP_ROUTER_ADDRESSES[chainId as ChainId]
if (!swapRouterAddress) return []
const { value, calldata } = SwapRouter.swapCallParameters(trade, { const { value, calldata } = SwapRouter.swapCallParameters(trade, {
recipient, recipient,
slippageTolerance: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE), slippageTolerance: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE),
deadline: deadline.toNumber(), deadline: deadline.toString(),
swapRouterAddressOverride: swapRouterAddress,
}) })
const swapRouterAddress = SWAP_ROUTER_ADDRESSES[chainId as ChainId]
if (!swapRouterAddress) return []
return [ return [
{ {
address: swapRouterAddress, address: swapRouterAddress,
......
...@@ -54,6 +54,7 @@ import FeeSelector from 'components/FeeSelector' ...@@ -54,6 +54,7 @@ import FeeSelector from 'components/FeeSelector'
import RangeSelector from 'components/RangeSelector' import RangeSelector from 'components/RangeSelector'
import RateToggle from 'components/RateToggle' import RateToggle from 'components/RateToggle'
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { calculateGasMargin } from 'utils'
export default function AddLiquidity({ export default function AddLiquidity({
match: { match: {
...@@ -189,16 +190,16 @@ export default function AddLiquidity({ ...@@ -189,16 +190,16 @@ export default function AddLiquidity({
if (position && account && deadline && fractionalizedTolerance) { if (position && account && deadline && fractionalizedTolerance) {
const { calldata, value } = const { calldata, value } =
hasExistingPosition && tokenId hasExistingPosition && tokenId
? NonfungiblePositionManager.increaseLiquidityCallParameters(position, { ? NonfungiblePositionManager.increaseCallParameters(position, {
tokenId: tokenId, tokenId,
slippageTolerance: fractionalizedTolerance, slippageTolerance: fractionalizedTolerance,
deadline: deadline.toNumber(), deadline: deadline.toString(),
useEther: currencyA === ETHER || currencyB === ETHER, useEther: currencyA === ETHER || currencyB === ETHER,
}) })
: NonfungiblePositionManager.mintCallParameters(position, { : NonfungiblePositionManager.increaseCallParameters(position, {
slippageTolerance: fractionalizedTolerance, slippageTolerance: fractionalizedTolerance,
recipient: account, recipient: account,
deadline: deadline.toNumber(), deadline: deadline.toString(),
useEther: currencyA === ETHER || currencyB === ETHER, useEther: currencyA === ETHER || currencyB === ETHER,
createPool: noLiquidity, createPool: noLiquidity,
}) })
...@@ -217,9 +218,10 @@ export default function AddLiquidity({ ...@@ -217,9 +218,10 @@ export default function AddLiquidity({
.then((estimate) => { .then((estimate) => {
const newTxn = { const newTxn = {
...txn, ...txn,
gasLimit: estimate, gasLimit: calculateGasMargin(estimate),
} }
library
return library
.getSigner() .getSigner()
.sendTransaction(newTxn) .sendTransaction(newTxn)
.then((response: TransactionResponse) => { .then((response: TransactionResponse) => {
...@@ -236,13 +238,6 @@ export default function AddLiquidity({ ...@@ -236,13 +238,6 @@ export default function AddLiquidity({
label: [currencies[Field.CURRENCY_A]?.symbol, currencies[Field.CURRENCY_B]?.symbol].join('/'), label: [currencies[Field.CURRENCY_A]?.symbol, currencies[Field.CURRENCY_B]?.symbol].join('/'),
}) })
}) })
.catch((error) => {
setAttemptingTxn(false)
// we only care if the error is something _other_ than the user rejected the tx
if (error?.code !== 4001) {
console.error(error)
}
})
}) })
.catch((error) => { .catch((error) => {
setAttemptingTxn(false) setAttemptingTxn(false)
......
...@@ -12,7 +12,7 @@ import { RowBetween, RowFixed } from 'components/Row' ...@@ -12,7 +12,7 @@ import { RowBetween, RowFixed } from 'components/Row'
import DoubleCurrencyLogo from 'components/DoubleLogo' import DoubleCurrencyLogo from 'components/DoubleLogo'
import { ButtonText, TYPE } from 'theme' import { ButtonText, TYPE } from 'theme'
import Badge, { BadgeVariant } from 'components/Badge' import Badge, { BadgeVariant } from 'components/Badge'
import { basisPointsToPercent } from 'utils' import { basisPointsToPercent, calculateGasMargin } from 'utils'
import { ButtonConfirmed, ButtonPrimary } from 'components/Button' import { ButtonConfirmed, ButtonPrimary } from 'components/Button'
import { DarkCard, DarkGreyCard } from 'components/Card' import { DarkCard, DarkGreyCard } from 'components/Card'
import CurrencyLogo from 'components/CurrencyLogo' import CurrencyLogo from 'components/CurrencyLogo'
...@@ -187,7 +187,7 @@ export function PositionPage({ ...@@ -187,7 +187,7 @@ export function PositionPage({
const involvesWETH = feeValue0.token.equals(WETH9[chainId]) || feeValue1.token.equals(WETH9[chainId]) const involvesWETH = feeValue0.token.equals(WETH9[chainId]) || feeValue1.token.equals(WETH9[chainId])
const data = [] const data: string[] = []
// collect, hard-coding ETH collection for now // collect, hard-coding ETH collection for now
data.push( data.push(
...@@ -220,21 +220,25 @@ export function PositionPage({ ...@@ -220,21 +220,25 @@ export function PositionPage({
) )
} }
positionManager positionManager.estimateGas
.multicall(data) .multicall(data)
.then((response: TransactionResponse) => { .then(async (estimate) => {
setCollectMigrationHash(response.hash) return positionManager
setCollecting(false) .multicall(data, { gasLimit: calculateGasMargin(estimate) })
.then((response: TransactionResponse) => {
ReactGA.event({ setCollectMigrationHash(response.hash)
category: 'Liquidity', setCollecting(false)
action: 'CollectV3',
label: [feeValue0.token.symbol, feeValue1.token.symbol].join('/'), ReactGA.event({
}) category: 'Liquidity',
action: 'CollectV3',
addTransaction(response, { label: [feeValue0.token.symbol, feeValue1.token.symbol].join('/'),
summary: `Collect ${feeValue0.token.symbol}/${feeValue1.token.symbol} fees`, })
})
addTransaction(response, {
summary: `Collect ${feeValue0.token.symbol}/${feeValue1.token.symbol} fees`,
})
})
}) })
.catch((error) => { .catch((error) => {
setCollecting(false) setCollecting(false)
......
...@@ -22,7 +22,7 @@ import ReactGA from 'react-ga' ...@@ -22,7 +22,7 @@ import ReactGA from 'react-ga'
import { useActiveWeb3React } from 'hooks' import { useActiveWeb3React } from 'hooks'
import { TransactionResponse } from '@ethersproject/providers' import { TransactionResponse } from '@ethersproject/providers'
import { useTransactionAdder } from 'state/transactions/hooks' import { useTransactionAdder } from 'state/transactions/hooks'
import { WETH9 } from '@uniswap/sdk-core' import { WETH9, Percent } from '@uniswap/sdk-core'
import { TYPE } from 'theme' import { TYPE } from 'theme'
import styled from 'styled-components' import styled from 'styled-components'
import { Wrapper, SmallMaxButton } from './styled' import { Wrapper, SmallMaxButton } from './styled'
...@@ -32,6 +32,9 @@ import { unwrappedToken } from 'utils/wrappedCurrency' ...@@ -32,6 +32,9 @@ import { unwrappedToken } from 'utils/wrappedCurrency'
import DoubleCurrencyLogo from 'components/DoubleLogo' import DoubleCurrencyLogo from 'components/DoubleLogo'
import { RangeBadge } from 'pages/AddLiquidity/styled' import { RangeBadge } from 'pages/AddLiquidity/styled'
import { Break } from 'components/earn/styled' import { Break } from 'components/earn/styled'
import { NonfungiblePositionManager } from '@uniswap/v3-sdk'
import { BIPS_BASE } from '../../constants'
import { calculateGasMargin } from 'utils'
export const UINT128MAX = BigNumber.from(2).pow(128).sub(1) export const UINT128MAX = BigNumber.from(2).pow(128).sub(1)
...@@ -63,7 +66,7 @@ export default function RemoveLiquidityV3({ ...@@ -63,7 +66,7 @@ export default function RemoveLiquidityV3({
function Remove({ tokenId }: { tokenId: BigNumber }) { function Remove({ tokenId }: { tokenId: BigNumber }) {
const { position } = useV3PositionFromTokenId(tokenId) const { position } = useV3PositionFromTokenId(tokenId)
const { account, chainId } = useActiveWeb3React() const { account, chainId, library } = useActiveWeb3React()
// currencies from position // currencies from position
const token0 = useToken(position?.token0) const token0 = useToken(position?.token0)
...@@ -73,9 +76,16 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -73,9 +76,16 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
// burn state // burn state
const { percent } = useBurnV3State() const { percent } = useBurnV3State()
const { liquidity, liquidityValue0, liquidityValue1, feeValue0, feeValue1, outOfRange, error } = useDerivedV3BurnInfo( const {
position position: positionSDK,
) liquidityPercentage,
liquidityValue0,
liquidityValue1,
feeValue0,
feeValue1,
outOfRange,
error,
} = useDerivedV3BurnInfo(position)
const { onPercentSelect } = useBurnV3ActionHandlers() const { onPercentSelect } = useBurnV3ActionHandlers()
// boilerplate for the slider // boilerplate for the slider
...@@ -89,11 +99,10 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -89,11 +99,10 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
const [txnHash, setTxnHash] = useState<string | undefined>() const [txnHash, setTxnHash] = useState<string | undefined>()
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
const positionManager = useV3NFTPositionManagerContract() const positionManager = useV3NFTPositionManagerContract()
const burn = useCallback(() => { const burn = useCallback(async () => {
setShowConfirm(true) setShowConfirm(true)
setAttemptingTxn(true) setAttemptingTxn(true)
if ( if (
!liquidity ||
!positionManager || !positionManager ||
!liquidityValue0 || !liquidityValue0 ||
!liquidityValue1 || !liquidityValue1 ||
...@@ -101,89 +110,57 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -101,89 +110,57 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
!account || !account ||
!chainId || !chainId ||
!feeValue0 || !feeValue0 ||
!feeValue1 !feeValue1 ||
!positionSDK ||
!liquidityPercentage ||
!library
) { ) {
setShowConfirm(false) setShowConfirm(false)
return return
} }
const data = []
// decreaseLiquidity if necessary
const amount0Min = JSBI.divide(
JSBI.multiply(liquidityValue0.raw, JSBI.BigInt(10000 - allowedSlippage)),
JSBI.BigInt(10000)
)
const amount1Min = JSBI.divide(
JSBI.multiply(liquidityValue1.raw, JSBI.BigInt(10000 - allowedSlippage)),
JSBI.BigInt(10000)
)
if (liquidity.gt(0)) {
data.push(
positionManager.interface.encodeFunctionData('decreaseLiquidity', [
{
tokenId,
liquidity,
amount0Min: `0x${amount0Min.toString(16)}`,
amount1Min: `0x${amount1Min.toString(16)}`,
deadline,
},
])
)
}
const involvesWETH = liquidityValue0.token.equals(WETH9[chainId]) || liquidityValue1.token.equals(WETH9[chainId]) const involvesWETH = liquidityValue0.token.equals(WETH9[chainId]) || liquidityValue1.token.equals(WETH9[chainId])
// collect, hard-coding ETH collection for now const { calldata, value } = NonfungiblePositionManager.decreaseCallParameters(positionSDK, {
data.push( tokenId: tokenId.toString(),
positionManager.interface.encodeFunctionData('collect', [ liquidityPercentage,
{ slippageTolerance: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE),
tokenId, recipient: account,
recipient: involvesWETH ? positionManager.address : account, deadline: deadline.toString(),
amount0Max: UINT128MAX, receiveEther: involvesWETH,
amount1Max: UINT128MAX, nonfungiblePositionManagerAddressOverride: positionManager.address,
}, })
])
)
if (involvesWETH) {
// unwrap
data.push(
positionManager.interface.encodeFunctionData('unwrapWETH9', [
`0x${(liquidityValue0.token.equals(WETH9[chainId])
? JSBI.add(amount0Min, feeValue0.raw)
: JSBI.add(amount1Min, feeValue1.raw)
).toString(16)}`,
account,
])
)
// sweep const txn = {
data.push( to: positionManager.address,
positionManager.interface.encodeFunctionData('sweepToken', [ data: calldata,
liquidityValue0.token.equals(WETH9[chainId]) ? liquidityValue1.token.address : liquidityValue0.token.address, value,
`0x${(liquidityValue0.token.equals(WETH9[chainId])
? JSBI.add(amount1Min, feeValue1.raw)
: JSBI.add(amount0Min, feeValue0.raw)
).toString(16)}`,
account,
])
)
} }
positionManager library
.multicall(data) .getSigner()
.then((response: TransactionResponse) => { .estimateGas(txn)
ReactGA.event({ .then((estimate) => {
category: 'Liquidity', const newTxn = {
action: 'RemoveV3', ...txn,
label: [liquidityValue0.token.symbol, liquidityValue1.token.symbol].join('/'), gasLimit: calculateGasMargin(estimate),
}) }
setTxnHash(response.hash)
setAttemptingTxn(false) return library
addTransaction(response, { .getSigner()
summary: `Remove ${liquidityValue0.token.symbol}/${liquidityValue1.token.symbol} V3 liquidity`, .sendTransaction(newTxn)
}) .then((response: TransactionResponse) => {
ReactGA.event({
category: 'Liquidity',
action: 'RemoveV3',
label: [liquidityValue0.token.symbol, liquidityValue1.token.symbol].join('/'),
})
setTxnHash(response.hash)
setAttemptingTxn(false)
addTransaction(response, {
summary: `Remove ${liquidityValue0.token.symbol}/${liquidityValue1.token.symbol} V3 liquidity`,
})
})
}) })
.catch((error) => { .catch((error) => {
setShowConfirm(false) setShowConfirm(false)
...@@ -192,7 +169,6 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -192,7 +169,6 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
}) })
}, [ }, [
tokenId, tokenId,
liquidity,
liquidityValue0, liquidityValue0,
liquidityValue1, liquidityValue1,
deadline, deadline,
...@@ -203,6 +179,9 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -203,6 +179,9 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
chainId, chainId,
feeValue0, feeValue0,
feeValue1, feeValue1,
library,
liquidityPercentage,
positionSDK,
]) ])
const handleDismissConfirmation = useCallback(() => { const handleDismissConfirmation = useCallback(() => {
...@@ -236,7 +215,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -236,7 +215,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
<TYPE.label margin="0 10px" opacity={'0.4'}> <TYPE.label margin="0 10px" opacity={'0.4'}>
{' > '} {' > '}
</TYPE.label> </TYPE.label>
<TYPE.label>{liquidity?.eq(0) ? 'Collect Fees' : 'Remove Liquidity'}</TYPE.label> <TYPE.label>{liquidityPercentage?.equalTo(0) ? 'Collect Fees' : 'Remove Liquidity'}</TYPE.label>
</AutoRow> </AutoRow>
<AppBody> <AppBody>
<Wrapper> <Wrapper>
...@@ -327,8 +306,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -327,8 +306,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</LightCard> </LightCard>
<div style={{ display: 'flex' }}> <div style={{ display: 'flex' }}>
<AutoColumn gap="12px" style={{ flex: '1' }}> <AutoColumn gap="12px" style={{ flex: '1' }}>
<ButtonConfirmed confirmed={false} disabled={!liquidity} onClick={burn}> <ButtonConfirmed confirmed={false} disabled={!liquidityValue0} onClick={burn}>
{error ?? liquidity?.eq(0) ? 'Collect' : 'Remove Liquidity'} {error ?? liquidityPercentage?.equalTo(0) ? 'Collect Fees' : 'Remove Liquidity'}
</ButtonConfirmed> </ButtonConfirmed>
</AutoColumn> </AutoColumn>
</div> </div>
......
import { BigNumber } from '@ethersproject/bignumber' import { TokenAmount, Percent } from '@uniswap/sdk-core'
import { TokenAmount } from '@uniswap/sdk-core'
import { Position } from '@uniswap/v3-sdk' import { Position } from '@uniswap/v3-sdk'
import { usePool } from 'hooks/usePools' import { usePool } from 'hooks/usePools'
import { useActiveWeb3React } from 'hooks' import { useActiveWeb3React } from 'hooks'
...@@ -19,7 +18,8 @@ export function useBurnV3State(): AppState['burnV3'] { ...@@ -19,7 +18,8 @@ export function useBurnV3State(): AppState['burnV3'] {
export function useDerivedV3BurnInfo( export function useDerivedV3BurnInfo(
position?: PositionDetails position?: PositionDetails
): { ): {
liquidity?: BigNumber position?: Position
liquidityPercentage?: Percent
liquidityValue0?: TokenAmount liquidityValue0?: TokenAmount
liquidityValue1?: TokenAmount liquidityValue1?: TokenAmount
feeValue0?: TokenAmount feeValue0?: TokenAmount
...@@ -35,26 +35,27 @@ export function useDerivedV3BurnInfo( ...@@ -35,26 +35,27 @@ export function useDerivedV3BurnInfo(
const [, pool] = usePool(token0 ?? undefined, token1 ?? undefined, position?.fee) const [, pool] = usePool(token0 ?? undefined, token1 ?? undefined, position?.fee)
const partialPosition = useMemo( const positionSDK = useMemo(
() => () =>
pool && pool && position?.liquidity && typeof position?.tickLower === 'number' && typeof position?.tickUpper === 'number'
position?.liquidity &&
position?.tickLower &&
position?.tickUpper &&
typeof position.tickLower === 'number' &&
typeof position.tickUpper === 'number'
? new Position({ ? new Position({
pool, pool,
liquidity: position.liquidity.mul(percent).div(100).toString(), liquidity: position.liquidity.toString(),
tickLower: position.tickLower, tickLower: position.tickLower,
tickUpper: position.tickUpper, tickUpper: position.tickUpper,
}) })
: undefined, : undefined,
[pool, percent, position] [pool, position]
) )
const liquidityValue0 = partialPosition?.amount0 const liquidityPercentage = new Percent(percent, 100)
const liquidityValue1 = partialPosition?.amount1
const liquidityValue0 =
positionSDK &&
new TokenAmount(positionSDK.amount0.token, liquidityPercentage.multiply(positionSDK.amount0.raw).quotient)
const liquidityValue1 =
positionSDK &&
new TokenAmount(positionSDK.amount1.token, liquidityPercentage.multiply(positionSDK.amount1.raw).quotient)
const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, position) const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, position)
...@@ -69,7 +70,8 @@ export function useDerivedV3BurnInfo( ...@@ -69,7 +70,8 @@ export function useDerivedV3BurnInfo(
error = error ?? 'Enter an percent' error = error ?? 'Enter an percent'
} }
return { return {
liquidity: partialPosition?.liquidity ? BigNumber.from(partialPosition?.liquidity.toString()) : undefined, position: positionSDK,
liquidityPercentage,
liquidityValue0, liquidityValue0,
liquidityValue1, liquidityValue1,
feeValue0, feeValue0,
......
...@@ -4158,10 +4158,10 @@ ...@@ -4158,10 +4158,10 @@
"@uniswap/v2-core" "1.0.1" "@uniswap/v2-core" "1.0.1"
"@uniswap/v3-core" "1.0.0-rc.2" "@uniswap/v3-core" "1.0.0-rc.2"
"@uniswap/v3-sdk@^1.0.0-alpha.23": "@uniswap/v3-sdk@^1.0.0-alpha.27":
version "1.0.0-alpha.23" version "1.0.0-alpha.27"
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-1.0.0-alpha.23.tgz#0971b38acd46e08d727f17ad8b10b5c21a25b99f" resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-1.0.0-alpha.27.tgz#2258b36f9f21cb23c7aa78fc89066a2a2dc429a7"
integrity sha512-ibVW9EnwymIQAHBCCQCorwA5yLzRfQ4OYwafTkD1fHx2UtrZoHVYLBSshMa4tcN1uMAuiglFOQv/IIJ20ZRgyw== integrity sha512-xR+zEfR0lljREwAbejF4lvKXK2ZpVUjvbEMNngle3rb+oYGJxzzJgcSa4lw8Y2uo91w+gvUcVbO69bCu62IRHQ==
dependencies: dependencies:
"@ethersproject/abi" "^5.0.12" "@ethersproject/abi" "^5.0.12"
"@ethersproject/solidity" "^5.0.9" "@ethersproject/solidity" "^5.0.9"
......
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