Commit d342ccdb authored by Noah Zinsmeister's avatar Noah Zinsmeister

use sdk for more calldata

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