Commit 55eb03c2 authored by ianlapham's avatar ianlapham

remove version with derived percent

parent a6d8613b
...@@ -49,11 +49,11 @@ export default function ConfirmationModal({ ...@@ -49,11 +49,11 @@ export default function ConfirmationModal({
amount1, amount1,
price, price,
transactionType, transactionType,
pendingConfirmation,
hash, hash,
signed = false, signed = false,
contractCall, contractCall,
attemptedRemoval = false, attemptedRemoval = false,
pendingConfirmation,
extraCall = undefined extraCall = undefined
}) { }) {
const { address: address0, symbol: symbol0 } = amount0?.token || {} const { address: address0, symbol: symbol0 } = amount0?.token || {}
......
...@@ -161,7 +161,7 @@ export default function CurrencyInputPanel({ ...@@ -161,7 +161,7 @@ export default function CurrencyInputPanel({
value, value,
field, field,
onUserInput, onUserInput,
onTokenSelection, onTokenSelection = null,
title, title,
onMax, onMax,
atMax, atMax,
......
...@@ -7,6 +7,7 @@ const IOSSlider = withStyles({ ...@@ -7,6 +7,7 @@ const IOSSlider = withStyles({
width: '95%', width: '95%',
color: '#3880ff', color: '#3880ff',
height: 4, height: 4,
marginLeft: '15px',
padding: '15px 0' padding: '15px 0'
}, },
thumb: { thumb: {
......
...@@ -5,18 +5,16 @@ import { parseUnits } from '@ethersproject/units' ...@@ -5,18 +5,16 @@ import { parseUnits } from '@ethersproject/units'
import { TokenAmount, JSBI, Route, WETH, Percent } from '@uniswap/sdk' import { TokenAmount, JSBI, Route, WETH, Percent } from '@uniswap/sdk'
import Slider from '../../components/Slider' import Slider from '../../components/Slider'
import DoubleLogo from '../../components/DoubleLogo' import TokenLogo from '../../components/TokenLogo'
import SearchModal from '../../components/SearchModal'
import PositionCard from '../../components/PositionCard' import PositionCard from '../../components/PositionCard'
import ConfirmationModal from '../../components/ConfirmationModal' import ConfirmationModal from '../../components/ConfirmationModal'
import CurrencyInputPanel from '../../components/CurrencyInputPanel' import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import { Text } from 'rebass' import { Text } from 'rebass'
import { LightCard } from '../../components/Card' import { LightCard } from '../../components/Card'
import { ChevronDown } from 'react-feather' import { ButtonPrimary } from '../../components/Button'
import { ArrowDown, Plus } from 'react-feather' import { ArrowDown, Plus } from 'react-feather'
import { RowBetween, RowFixed } from '../../components/Row' import { RowBetween, RowFixed } from '../../components/Row'
import { AutoColumn, ColumnCenter } from '../../components/Column' import { AutoColumn, ColumnCenter } from '../../components/Column'
import { ButtonPrimary, ButtonEmpty } from '../../components/Button'
import { useToken } from '../../contexts/Tokens' import { useToken } from '../../contexts/Tokens'
import { useWeb3React } from '../../hooks' import { useWeb3React } from '../../hooks'
...@@ -30,7 +28,6 @@ import { splitSignature } from '@ethersproject/bytes' ...@@ -30,7 +28,6 @@ import { splitSignature } from '@ethersproject/bytes'
import { TRANSACTION_TYPE } from '../../constants' import { TRANSACTION_TYPE } from '../../constants'
import { ROUTER_ADDRESSES } from '../../constants' import { ROUTER_ADDRESSES } from '../../constants'
import { getRouterContract, calculateGasMargin } from '../../utils' import { getRouterContract, calculateGasMargin } from '../../utils'
import TokenLogo from '../../components/TokenLogo'
// denominated in seconds // denominated in seconds
const DEADLINE_FROM_NOW = 60 * 15 const DEADLINE_FROM_NOW = 60 * 15
...@@ -73,54 +70,46 @@ const MaxButton = styled.button` ...@@ -73,54 +70,46 @@ const MaxButton = styled.button`
` `
enum Field { enum Field {
PERCENTAGE, LIQUIDITY,
POOL, TOKEN0,
INPUT, TOKEN1
OUTPUT
} }
interface RemoveState { interface RemoveState {
independentField: Field independentField: Field
typedValue: string typedValue: string
[Field.POOL]: { [Field.LIQUIDITY]: {
address: string | undefined address: string | undefined
} }
[Field.INPUT]: { [Field.TOKEN0]: {
address: string | undefined address: string | undefined
} }
[Field.OUTPUT]: { [Field.TOKEN1]: {
address: string | undefined address: string | undefined
} }
} }
function initializeRemoveState(inputAddress?: string, outputAddress?: string): RemoveState { function initializeRemoveState(liquidity, inputAddress?: string, outputAddress?: string): RemoveState {
return { return {
independentField: Field.PERCENTAGE, independentField: Field.LIQUIDITY,
typedValue: '', typedValue: liquidity || '',
[Field.POOL]: { [Field.LIQUIDITY]: {
address: '' address: ''
}, },
[Field.INPUT]: { [Field.TOKEN0]: {
address: inputAddress address: inputAddress
}, },
[Field.OUTPUT]: { [Field.TOKEN1]: {
address: outputAddress address: outputAddress
} }
} }
} }
enum RemoveAction { enum RemoveAction {
SELECT_TOKEN,
SWITCH_TOKENS,
TYPE TYPE
} }
interface Payload { interface Payload {
[RemoveAction.SELECT_TOKEN]: {
field: Field
address: string
}
[RemoveAction.SWITCH_TOKENS]: undefined
[RemoveAction.TYPE]: { [RemoveAction.TYPE]: {
field: Field field: Field
typedValue: string typedValue: string
...@@ -149,27 +138,28 @@ function reducer( ...@@ -149,27 +138,28 @@ function reducer(
} }
} }
export default function RemoveLiquidity({ token0, token1 }) { // todo
// console.log('DEBUG: Rendering') // add exchange address to initial state
// remove stateful slider in advanced mode, just show a sig fig value based on pool tokens burned
// try to fully derive percentageAmount from state
// at the very least, move that state into the reducer
export default function RemoveLiquidity({ token0, token1 }) {
const { account, chainId, library } = useWeb3React() const { account, chainId, library } = useWeb3React()
const routerAddress = ROUTER_ADDRESSES[chainId] const routerAddress = ROUTER_ADDRESSES[chainId]
// modal state const [showConfirm, setShowConfirm] = useState(false)
const [showSearch, toggleSearch] = useState(false) const [showAdvanced, setShowAdvanced] = useState(false)
const [pendingConfirmation, setPendingConfirmation] = useState(true)
// input state
const [state, dispatch] = useReducer(reducer, initializeRemoveState(token0, token1))
const { independentField, typedValue, ...fieldData } = state
const inputToken = useToken(fieldData[Field.INPUT].address) const inputToken = useToken(token0)
const outputToken = useToken(fieldData[Field.OUTPUT].address) const outputToken = useToken(token1)
// get basic SDK entities // get basic SDK entities
const tokens = { const tokens = {
[Field.INPUT]: inputToken, [Field.TOKEN0]: inputToken,
[Field.OUTPUT]: outputToken [Field.TOKEN1]: outputToken
} }
const exchange = useExchange(inputToken, outputToken) const exchange = useExchange(inputToken, outputToken)
...@@ -181,210 +171,136 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -181,210 +171,136 @@ export default function RemoveLiquidity({ token0, token1 }) {
const allBalances = useAllBalances() const allBalances = useAllBalances()
const userLiquidity = allBalances?.[account]?.[exchange?.liquidityToken?.address] const userLiquidity = allBalances?.[account]?.[exchange?.liquidityToken?.address]
// state for confirmation popup // input state
const [showConfirm, setShowConfirm] = useState(false) const [state, dispatch] = useReducer(reducer, initializeRemoveState(userLiquidity?.toExact(), token0, token1))
const { independentField, typedValue } = state
const TokensDeposited = { const TokensDeposited = {
[Field.INPUT]: [Field.TOKEN0]:
exchange && exchange &&
totalPoolTokens && totalPoolTokens &&
userLiquidity && userLiquidity &&
exchange.getLiquidityValue(tokens[Field.INPUT], totalPoolTokens, userLiquidity, false), exchange.getLiquidityValue(tokens[Field.TOKEN0], totalPoolTokens, userLiquidity, false),
[Field.OUTPUT]: [Field.TOKEN1]:
exchange && exchange &&
totalPoolTokens && totalPoolTokens &&
userLiquidity && userLiquidity &&
exchange.getLiquidityValue(tokens[Field.OUTPUT], totalPoolTokens, userLiquidity, false) exchange.getLiquidityValue(tokens[Field.TOKEN1], totalPoolTokens, userLiquidity, false)
} }
const route = exchange const route = exchange
? new Route( ? new Route([exchange], independentField !== Field.LIQUIDITY ? tokens[independentField] : tokens[Field.TOKEN1])
[exchange],
independentField === Field.POOL || independentField === Field.PERCENTAGE
? tokens[Field.OUTPUT]
: tokens[independentField]
)
: undefined : undefined
const onTokenSelection = useCallback((field: Field, address: string) => {
dispatch({
type: RemoveAction.SELECT_TOKEN,
payload: { field, address }
})
}, [])
// update input value when user types // update input value when user types
const onUserInput = useCallback((field: Field, typedValue: string) => { const onUserInput = useCallback((field: Field, typedValue: string) => {
dispatch({ type: RemoveAction.TYPE, payload: { field, typedValue } }) dispatch({ type: RemoveAction.TYPE, payload: { field, typedValue } })
}, []) }, [])
// used for percentage based amount setting const handleSliderChange = (event, newPercent) => {
const [percentageAmount, setPercentageAmount] = useState(100) onUserInput(
const handleSliderChange = (event, newValue) => { Field.LIQUIDITY,
setPercentageAmount(newValue) new TokenAmount(
onUserInput(Field.PERCENTAGE, undefined) exchange?.liquidityToken,
JSBI.divide(JSBI.multiply(userLiquidity.raw, JSBI.BigInt(newPercent)), JSBI.BigInt(100))
).toExact()
)
} }
// parse the amounts based on input
const parsedAmounts: { [field: number]: TokenAmount } = {} const parsedAmounts: { [field: number]: TokenAmount } = {}
if ( let poolTokenAmount
independentField === Field.PERCENTAGE &&
userLiquidity &&
exchange &&
totalPoolTokens &&
tokens[Field.INPUT] &&
tokens[Field.OUTPUT]
) {
const formattedPercentage = JSBI.BigInt(percentageAmount)
const liquidityAmount = JSBI.divide(JSBI.multiply(userLiquidity.raw, formattedPercentage), JSBI.BigInt(100))
parsedAmounts[Field.POOL] = new TokenAmount(exchange?.liquidityToken, liquidityAmount)
parsedAmounts[Field.INPUT] = exchange.getLiquidityValue(
tokens[Field.INPUT],
totalPoolTokens,
parsedAmounts[Field.POOL],
false
)
parsedAmounts[Field.OUTPUT] = exchange.getLiquidityValue(
tokens[Field.OUTPUT],
totalPoolTokens,
parsedAmounts[Field.POOL],
false
)
} else if (independentField === Field.INPUT) {
if (typedValue !== '' && typedValue !== '.' && tokens[Field.INPUT] && exchange && userLiquidity) {
try { try {
const typedValueParsed = parseUnits(typedValue, tokens[Field.INPUT].decimals).toString() if (typedValue !== '' && typedValue !== '.' && tokens[Field.TOKEN0] && tokens[Field.TOKEN1] && userLiquidity) {
if (independentField === Field.TOKEN0) {
const typedValueParsed = parseUnits(typedValue, tokens[Field.TOKEN0].decimals).toString()
if (typedValueParsed !== '0') { if (typedValueParsed !== '0') {
// first get the exact percentage of tokens deposited const tokenAmount = new TokenAmount(tokens[Field.TOKEN0], typedValueParsed)
const inputTokenAmount = new TokenAmount(tokens[Field.INPUT], typedValueParsed) poolTokenAmount = JSBI.divide(
const ratio = new Percent(inputTokenAmount.raw, TokensDeposited[Field.INPUT].raw) JSBI.multiply(tokenAmount.raw, userLiquidity.raw),
const partialLiquidity = ratio.multiply(userLiquidity) TokensDeposited[Field.TOKEN0].raw
const liquidityTokenAmount = new TokenAmount(exchange.liquidityToken, partialLiquidity)
parsedAmounts[Field.POOL] = liquidityTokenAmount
parsedAmounts[Field.OUTPUT] = exchange.getLiquidityValue(
tokens[Field.OUTPUT],
totalPoolTokens,
parsedAmounts[Field.POOL],
false
) )
} }
} catch (error) {
// should only fail if the user specifies too many decimal places of precision (or maybe exceed max uint?)
console.error(error)
}
} }
} else if (independentField === Field.OUTPUT) { if (independentField === Field.TOKEN1) {
if (typedValue !== '' && typedValue !== '.' && tokens[Field.OUTPUT]) { const typedValueParsed = parseUnits(typedValue, tokens[Field.TOKEN1].decimals).toString()
try {
const typedValueParsed = parseUnits(typedValue, tokens[Field.OUTPUT].decimals).toString()
if (typedValueParsed !== '0') { if (typedValueParsed !== '0') {
const inputTokenAmount = new TokenAmount(tokens[Field.OUTPUT], typedValueParsed) const tokenAmount = new TokenAmount(tokens[Field.TOKEN1], typedValueParsed)
const ratio = JSBI.divide(inputTokenAmount.raw, TokensDeposited[Field.OUTPUT].raw) poolTokenAmount = JSBI.divide(
const partialLiquidity = JSBI.multiply(userLiquidity.raw, ratio) JSBI.multiply(tokenAmount.raw, userLiquidity.raw),
const liquidityTokenAmount = new TokenAmount(exchange.liquidityToken, partialLiquidity) TokensDeposited[Field.TOKEN1].raw
parsedAmounts[Field.POOL] = liquidityTokenAmount
parsedAmounts[Field.INPUT] = exchange.getLiquidityValue(
tokens[Field.INPUT],
totalPoolTokens,
parsedAmounts[Field.POOL],
false
) )
} }
} catch (error) {
// should only fail if the user specifies too many decimal places of precision (or maybe exceed max uint?)
console.error(error)
}
} }
} else if (independentField === Field.POOL) { if (independentField === Field.LIQUIDITY) {
if (typedValue !== '' && typedValue !== '.' && exchange) {
try {
const typedValueParsed = parseUnits(typedValue, exchange?.liquidityToken.decimals).toString() const typedValueParsed = parseUnits(typedValue, exchange?.liquidityToken.decimals).toString()
const formattedAmount = new TokenAmount(exchange?.liquidityToken, typedValueParsed)
if (typedValueParsed !== '0') { if (typedValueParsed !== '0') {
parsedAmounts[Field.POOL] = new TokenAmount(exchange?.liquidityToken, typedValueParsed) if (JSBI.greaterThan(formattedAmount.raw, userLiquidity?.raw)) {
if (
(parsedAmounts[Field.POOL] &&
totalPoolTokens &&
!JSBI.lessThanOrEqual(parsedAmounts[Field.POOL].raw, totalPoolTokens.raw)) ||
!JSBI.lessThanOrEqual(parsedAmounts[Field.POOL].raw, userLiquidity.raw)
) {
/** /**
* do some error catching on amount? * error state for incorrect liquidity valye
*
*/ */
} else { } else {
parsedAmounts[Field.INPUT] = exchange.getLiquidityValue( poolTokenAmount = typedValueParsed
tokens[Field.INPUT], }
totalPoolTokens, }
parsedAmounts[Field.POOL],
false
)
parsedAmounts[Field.OUTPUT] = exchange.getLiquidityValue(
tokens[Field.OUTPUT],
totalPoolTokens,
parsedAmounts[Field.POOL],
false
)
} }
} }
} catch (error) { } catch (error) {
// should only fail if the user specifies too many decimal places of precision (or maybe exceed max uint?) // should only fail if the user specifies too many decimal places of precision (or maybe exceed max uint?)
console.error(error) console.error(error)
} }
}
} // set parsed amounts based on live amount of liquidity
parsedAmounts[Field.LIQUIDITY] =
exchange && poolTokenAmount && new TokenAmount(exchange.liquidityToken, poolTokenAmount)
parsedAmounts[Field.TOKEN0] =
totalPoolTokens &&
exchange &&
parsedAmounts[Field.LIQUIDITY] &&
exchange.getLiquidityValue(tokens[Field.TOKEN0], totalPoolTokens, parsedAmounts[Field.LIQUIDITY], false)
parsedAmounts[Field.TOKEN1] =
totalPoolTokens &&
exchange &&
parsedAmounts[Field.LIQUIDITY] &&
exchange.getLiquidityValue(tokens[Field.TOKEN1], totalPoolTokens, parsedAmounts[Field.LIQUIDITY], false)
// derived percent for advanced mode
const derivedPerecent =
userLiquidity &&
parsedAmounts[Field.LIQUIDITY] &&
new Percent(parsedAmounts[Field.LIQUIDITY]?.raw, userLiquidity.raw).toFixed(0)
// get formatted amounts // get formatted amounts
const formattedAmounts = { const formattedAmounts = {
[Field.POOL]: [Field.LIQUIDITY]:
independentField === Field.POOL independentField === Field.LIQUIDITY
? typedValue ? typedValue
: parsedAmounts[Field.POOL] : parsedAmounts[Field.LIQUIDITY]
? parsedAmounts[Field.POOL].toSignificant(8) ? parsedAmounts[Field.LIQUIDITY].toSignificant(8)
: '', : '',
[Field.INPUT]: [Field.TOKEN0]:
independentField === Field.INPUT independentField === Field.TOKEN0
? typedValue ? typedValue
: parsedAmounts[Field.INPUT] : parsedAmounts[Field.TOKEN0]
? parsedAmounts[Field.INPUT].toSignificant(8) ? parsedAmounts[Field.TOKEN0].toSignificant(8)
: '', : '',
[Field.OUTPUT]: [Field.TOKEN1]:
independentField === Field.OUTPUT independentField === Field.TOKEN1
? typedValue ? typedValue
: parsedAmounts[Field.OUTPUT] : parsedAmounts[Field.TOKEN1]
? parsedAmounts[Field.OUTPUT].toSignificant(8) ? parsedAmounts[Field.TOKEN1].toSignificant(8)
: '' : ''
} }
const onMax = useCallback((typedValue: string, field) => { const onMax = () => {
dispatch({ onUserInput(Field.LIQUIDITY, userLiquidity.toExact())
type: RemoveAction.TYPE,
payload: {
field: field,
typedValue
} }
})
}, [])
// get the max amounts user can add
const maxAmountPoolToken = userLiquidity
const [maxAmountInput, maxAmountOutput] = [Field.INPUT, Field.OUTPUT].map(index => {
const field = Field[index]
return !!TokensDeposited[Field[field]] && JSBI.greaterThan(TokensDeposited[Field[field]].raw, JSBI.BigInt(0))
? TokensDeposited[Field[field]]
: undefined
})
const [atMaxAmountInput, atMaxAmountOutput] = [Field.INPUT, Field.OUTPUT].map(index => {
const field = Field[index]
const maxAmount = index === Field.INPUT ? maxAmountInput : maxAmountOutput
return !!maxAmount && !!parsedAmounts[Field[field]]
? JSBI.lessThanOrEqual(maxAmount.raw, parsedAmounts[Field[field]].raw)
: undefined
})
const atMaxAmountPoolToken = const atMaxAmount =
!!maxAmountOutput && !!parsedAmounts[Field.POOL] !!userLiquidity && !!parsedAmounts[Field.LIQUIDITY]
? JSBI.lessThanOrEqual(maxAmountPoolToken.raw, parsedAmounts[Field.POOL].raw) ? JSBI.equal(userLiquidity.raw, parsedAmounts[Field.LIQUIDITY].raw)
: undefined : false
// errors // errors
const [generalError, setGeneralError] = useState() const [generalError, setGeneralError] = useState()
...@@ -404,39 +320,38 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -404,39 +320,38 @@ export default function RemoveLiquidity({ token0, token1 }) {
setIsError(false) setIsError(false)
setIsValid(true) setIsValid(true)
if (!parsedAmounts[Field.INPUT]) { if (!parsedAmounts[Field.TOKEN0]) {
setGeneralError('Enter an amount to continue') setGeneralError('Enter an amount to continue')
setIsValid(false) setIsValid(false)
} }
if (!parsedAmounts[Field.OUTPUT]) { if (!parsedAmounts[Field.TOKEN1]) {
setGeneralError('Enter an amount to continue') setGeneralError('Enter an amount to continue')
setIsValid(false) setIsValid(false)
} }
if ( if (
totalPoolTokens && totalPoolTokens &&
userLiquidity && userLiquidity &&
parsedAmounts[Field.POOL] && parsedAmounts[Field.LIQUIDITY] &&
(!JSBI.lessThanOrEqual(parsedAmounts[Field.POOL].raw, totalPoolTokens.raw) || (!JSBI.lessThanOrEqual(parsedAmounts[Field.LIQUIDITY].raw, totalPoolTokens.raw) ||
!JSBI.lessThanOrEqual(parsedAmounts[Field.POOL].raw, userLiquidity.raw)) !JSBI.lessThanOrEqual(parsedAmounts[Field.LIQUIDITY].raw, userLiquidity.raw))
) { ) {
setPoolTokenError('Input a liquidity amount less than or equal to your balance.') setPoolTokenError('Input a liquidity amount less than or equal to your balance.')
setIsError(true) setIsError(true)
setIsValid(false) setIsValid(false)
} }
// if ( // if (
// parsedAmounts?.[Field.INPUT] && // parsedAmounts?.[Field.TOKEN0] &&
// userBalances?.[Field.INPUT] && // userBalances?.[Field.TOKEN0] &&
// JSBI.greaterThan(parsedAmounts?.[Field.INPUT]?.raw, userBalances?.[Field.INPUT]?.raw) // JSBI.greaterThan(parsedAmounts?.[Field.TOKEN0]?.raw, userBalances?.[Field.TOKEN0]?.raw)
// ) { // ) {
// setInputError('Insufficient balance.') // setInputError('Insufficient balance.')
// setIsError(true) // setIsError(true)
// setIsValid(false) // setIsValid(false)
// } // }
// if ( // if (
// parsedAmounts?.[Field.OUTPUT] && // parsedAmounts?.[Field.TOKEN1] &&
// userBalances?.[Field.OUTPUT] && // userBalances?.[Field.TOKEN1] &&
// parseFloat(parsedAmounts?.[Field.OUTPUT]?.toExact()) > parseFloat(userBalances?.[Field.OUTPUT]?.toExact()) // parseFloat(parsedAmounts?.[Field.TOKEN1]?.toExact()) > parseFloat(userBalances?.[Field.TOKEN1]?.toExact())
// ) { // ) {
// setOutputError('Insufficient balance.') // setOutputError('Insufficient balance.')
// setIsError(true) // setIsError(true)
...@@ -444,15 +359,14 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -444,15 +359,14 @@ export default function RemoveLiquidity({ token0, token1 }) {
// } // }
}, [parsedAmounts, totalPoolTokens, userLiquidity]) }, [parsedAmounts, totalPoolTokens, userLiquidity])
// error state for button
// state for txn // state for txn
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
const [txHash, setTxHash] = useState() const [txHash, setTxHash] = useState()
const [sigInputs, setSigInputs] = useState([]) const [sigInputs, setSigInputs] = useState([])
const [signed, setSigned] = useState(false)
const [attemptedRemoval, setAttemptedRemoval] = useState(false)
const [deadline, setDeadline] = useState() const [deadline, setDeadline] = useState()
const [signed, setSigned] = useState(false) // waiting for signature sign
const [attemptedRemoval, setAttemptedRemoval] = useState(false) // clicke confirm
const [pendingConfirmation, setPendingConfirmation] = useState(true) // waiting for
async function onSign() { async function onSign() {
const nonce = await exchangeContract.nonces(account) const nonce = await exchangeContract.nonces(account)
...@@ -484,7 +398,7 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -484,7 +398,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
const message = { const message = {
owner: account, owner: account,
spender: routerAddress, spender: routerAddress,
value: parsedAmounts[Field.POOL].raw.toString(), value: parsedAmounts[Field.LIQUIDITY].raw.toString(),
nonce: nonce.toHexString(), nonce: nonce.toHexString(),
deadline: newDeadline deadline: newDeadline
} }
...@@ -511,18 +425,18 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -511,18 +425,18 @@ export default function RemoveLiquidity({ token0, token1 }) {
let method, args, estimate let method, args, estimate
// removal with ETH // removal with ETH
if (tokens[Field.INPUT] === WETH[chainId] || tokens[Field.OUTPUT] === WETH[chainId]) { if (tokens[Field.TOKEN0] === WETH[chainId] || tokens[Field.TOKEN1] === WETH[chainId]) {
method = router.removeLiquidityETHWithPermit method = router.removeLiquidityETHWithPermit
estimate = router.estimate.removeLiquidityETHWithPermit estimate = router.estimate.removeLiquidityETHWithPermit
args = [ args = [
tokens[Field.OUTPUT] === WETH[chainId] ? tokens[Field.INPUT].address : tokens[Field.OUTPUT].address, tokens[Field.TOKEN1] === WETH[chainId] ? tokens[Field.TOKEN0].address : tokens[Field.TOKEN1].address,
parsedAmounts[Field.POOL].raw.toString(), parsedAmounts[Field.LIQUIDITY].raw.toString(),
tokens[Field.OUTPUT] === WETH[chainId] tokens[Field.TOKEN1] === WETH[chainId]
? parsedAmounts[Field.INPUT].raw.toString() ? parsedAmounts[Field.TOKEN0].raw.toString()
: parsedAmounts[Field.OUTPUT].raw.toString(), : parsedAmounts[Field.TOKEN1].raw.toString(),
tokens[Field.OUTPUT] === WETH[chainId] tokens[Field.TOKEN1] === WETH[chainId]
? parsedAmounts[Field.OUTPUT].raw.toString() ? parsedAmounts[Field.TOKEN1].raw.toString()
: parsedAmounts[Field.INPUT].raw.toString(), : parsedAmounts[Field.TOKEN0].raw.toString(),
account, account,
deadline, deadline,
sigInputs[0], sigInputs[0],
...@@ -535,11 +449,11 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -535,11 +449,11 @@ export default function RemoveLiquidity({ token0, token1 }) {
method = router.removeLiquidityWithPermit method = router.removeLiquidityWithPermit
estimate = router.estimate.removeLiquidityWithPermit estimate = router.estimate.removeLiquidityWithPermit
args = [ args = [
tokens[Field.INPUT].address, tokens[Field.TOKEN0].address,
tokens[Field.OUTPUT].address, tokens[Field.TOKEN1].address,
parsedAmounts[Field.POOL].raw.toString(), parsedAmounts[Field.LIQUIDITY].raw.toString(),
parsedAmounts[Field.INPUT].raw.toString(), parsedAmounts[Field.TOKEN0].raw.toString(),
parsedAmounts[Field.OUTPUT].raw.toString(), parsedAmounts[Field.TOKEN1].raw.toString(),
account, account,
deadline, deadline,
sigInputs[0], sigInputs[0],
...@@ -569,6 +483,12 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -569,6 +483,12 @@ export default function RemoveLiquidity({ token0, token1 }) {
}) })
} }
/**
* @todo
* if the input values stay the same,
* we should probably not reset the signature values,
* move to an effect
*/
function resetModalState() { function resetModalState() {
setSigned(false) setSigned(false)
setSigInputs(null) setSigInputs(null)
...@@ -576,9 +496,6 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -576,9 +496,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
setPendingConfirmation(true) setPendingConfirmation(true)
} }
// show advanced mode or not
const [showAdvanced, setShowAdvanced] = useState(false)
return ( return (
<Wrapper> <Wrapper>
<ConfirmationModal <ConfirmationModal
...@@ -587,10 +504,10 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -587,10 +504,10 @@ export default function RemoveLiquidity({ token0, token1 }) {
resetModalState() resetModalState()
setShowConfirm(false) setShowConfirm(false)
}} }}
amount0={parsedAmounts[Field.INPUT]} amount0={parsedAmounts[Field.TOKEN0]}
amount1={parsedAmounts[Field.OUTPUT]} amount1={parsedAmounts[Field.TOKEN1]}
price={route?.midPrice} price={route?.midPrice}
liquidityAmount={parsedAmounts[Field.POOL]} liquidityAmount={parsedAmounts[Field.LIQUIDITY]}
transactionType={TRANSACTION_TYPE.REMOVE} transactionType={TRANSACTION_TYPE.REMOVE}
contractCall={onRemove} contractCall={onRemove}
extraCall={onSign} extraCall={onSign}
...@@ -599,34 +516,11 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -599,34 +516,11 @@ export default function RemoveLiquidity({ token0, token1 }) {
pendingConfirmation={pendingConfirmation} pendingConfirmation={pendingConfirmation}
hash={txHash ? txHash : ''} hash={txHash ? txHash : ''}
/> />
<SearchModal
isOpen={showSearch}
onDismiss={() => {
toggleSearch(false)
}}
/>
<AutoColumn gap="20px"> <AutoColumn gap="20px">
<ButtonEmpty
padding={'1rem'}
onClick={() => {
toggleSearch(true)
}}
>
<RowBetween>
<DoubleLogo a0={exchange?.token0?.address || ''} a1={exchange?.token1?.address || ''} size={24} />
<Text fontSize={20}>
{exchange?.token0?.symbol && exchange?.token1?.symbol
? exchange?.token0?.symbol + ' / ' + exchange?.token1?.symbol + ' Pool'
: ''}
</Text>
<ChevronDown size={24} />
</RowBetween>
</ButtonEmpty>
<LightCard> <LightCard>
<AutoColumn gap="20px"> <AutoColumn gap="20px">
<RowBetween> <RowBetween>
<Text fontWeight={500}>Amount To Remove</Text> <Text fontWeight={500}>Amount</Text>
<ClickableText <ClickableText
fontWeight={500} fontWeight={500}
onClick={() => { onClick={() => {
...@@ -634,23 +528,16 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -634,23 +528,16 @@ export default function RemoveLiquidity({ token0, token1 }) {
}} }}
color="#2172E5" color="#2172E5"
> >
{showAdvanced ? 'Minimal' : 'Advanced'} {showAdvanced ? 'Hide Advanced' : 'Show Advanced'}
</ClickableText> </ClickableText>
</RowBetween> </RowBetween>
<RowBetween style={{ alignItems: 'flex-end' }}> <RowBetween style={{ alignItems: 'flex-end' }}>
<Text fontSize={72} fontWeight={500}> <Text fontSize={72} fontWeight={500}>
{percentageAmount}% {derivedPerecent ? derivedPerecent : '0'}%
</Text> </Text>
<MaxButton {!showAdvanced && <MaxButton onClick={e => handleSliderChange(e, 100)}>Max</MaxButton>}
onClick={() => {
setPercentageAmount(100)
}}
>
Max
</MaxButton>
</RowBetween> </RowBetween>
<Slider value={percentageAmount} onChange={handleSliderChange} /> {!showAdvanced && <Slider value={parseFloat(derivedPerecent)} onChange={handleSliderChange} />}
</AutoColumn> </AutoColumn>
</LightCard> </LightCard>
{!showAdvanced && ( {!showAdvanced && (
...@@ -662,23 +549,23 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -662,23 +549,23 @@ export default function RemoveLiquidity({ token0, token1 }) {
<AutoColumn gap="10px"> <AutoColumn gap="10px">
<RowBetween> <RowBetween>
<Text fontSize={24} fontWeight={500}> <Text fontSize={24} fontWeight={500}>
{formattedAmounts[Field.INPUT]} {formattedAmounts[Field.TOKEN0] ? formattedAmounts[Field.TOKEN0] : '-'}
</Text> </Text>
<RowFixed> <RowFixed>
<TokenLogo address={tokens[Field.INPUT]?.address || ''} style={{ marginRight: '12px' }} /> <TokenLogo address={tokens[Field.TOKEN0]?.address || ''} style={{ marginRight: '12px' }} />
<Text fontSize={24} fontWeight={500}> <Text fontSize={24} fontWeight={500}>
{tokens[Field.INPUT]?.symbol} {tokens[Field.TOKEN0]?.symbol}
</Text> </Text>
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
<RowBetween> <RowBetween>
<Text fontSize={24} fontWeight={500}> <Text fontSize={24} fontWeight={500}>
{formattedAmounts[Field.OUTPUT]} {formattedAmounts[Field.TOKEN1] ? formattedAmounts[Field.TOKEN1] : '-'}
</Text> </Text>
<RowFixed> <RowFixed>
<TokenLogo address={tokens[Field.OUTPUT]?.address || ''} style={{ marginRight: '12px' }} /> <TokenLogo address={tokens[Field.TOKEN1]?.address || ''} style={{ marginRight: '12px' }} />
<Text fontSize={24} fontWeight={500}> <Text fontSize={24} fontWeight={500}>
{tokens[Field.OUTPUT]?.symbol} {tokens[Field.TOKEN1]?.symbol}
</Text> </Text>
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
...@@ -690,15 +577,12 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -690,15 +577,12 @@ export default function RemoveLiquidity({ token0, token1 }) {
{showAdvanced && ( {showAdvanced && (
<> <>
<CurrencyInputPanel <CurrencyInputPanel
field={Field.POOL} field={Field.LIQUIDITY}
value={formattedAmounts[Field.POOL]} value={formattedAmounts[Field.LIQUIDITY]}
onUserInput={onUserInput} onUserInput={onUserInput}
onMax={() => { onMax={onMax}
maxAmountPoolToken && onMax(maxAmountPoolToken.toExact(), Field.POOL) atMax={atMaxAmount}
}} title={'Burn'}
atMax={atMaxAmountPoolToken}
onTokenSelection={onTokenSelection}
title={'Deposit'}
error={poolTokenError} error={poolTokenError}
disableTokenSelect disableTokenSelect
token={exchange?.liquidityToken} token={exchange?.liquidityToken}
...@@ -709,37 +593,31 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -709,37 +593,31 @@ export default function RemoveLiquidity({ token0, token1 }) {
<ArrowDown size="16" color="#888D9B" /> <ArrowDown size="16" color="#888D9B" />
</ColumnCenter> </ColumnCenter>
<CurrencyInputPanel <CurrencyInputPanel
field={Field.INPUT} field={Field.TOKEN0}
value={formattedAmounts[Field.INPUT]} value={formattedAmounts[Field.TOKEN0]}
onUserInput={onUserInput} onUserInput={onUserInput}
onMax={() => { onMax={onMax}
maxAmountInput && onMax(maxAmountInput.toExact(), Field.INPUT) atMax={atMaxAmount}
}} token={tokens[Field.TOKEN0]}
atMax={atMaxAmountInput} title={'Withdraw'}
token={tokens[Field.INPUT]}
onTokenSelection={onTokenSelection}
title={'Deposit'}
error={inputError} error={inputError}
disableTokenSelect disableTokenSelect
customBalance={TokensDeposited[Field.INPUT]} customBalance={TokensDeposited[Field.TOKEN0]}
/> />
<ColumnCenter> <ColumnCenter>
<Plus size="16" color="#888D9B" /> <Plus size="16" color="#888D9B" />
</ColumnCenter> </ColumnCenter>
<CurrencyInputPanel <CurrencyInputPanel
field={Field.OUTPUT} field={Field.TOKEN1}
value={formattedAmounts[Field.OUTPUT]} value={formattedAmounts[Field.TOKEN1]}
onUserInput={onUserInput} onUserInput={onUserInput}
onMax={() => { onMax={onMax}
maxAmountOutput && onMax(maxAmountOutput.toExact(), Field.OUTPUT) atMax={atMaxAmount}
}} token={tokens[Field.TOKEN1]}
atMax={atMaxAmountOutput} title={'Withdraw'}
token={tokens[Field.OUTPUT]}
onTokenSelection={onTokenSelection}
title={'Deposit'}
error={outputError} error={outputError}
disableTokenSelect disableTokenSelect
customBalance={TokensDeposited[Field.OUTPUT]} customBalance={TokensDeposited[Field.TOKEN1]}
/> />
</> </>
)} )}
...@@ -747,7 +625,7 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -747,7 +625,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
Rate: Rate:
<div> <div>
1 {exchange?.token0.symbol} ={' '} 1 {exchange?.token0.symbol} ={' '}
{independentField === Field.INPUT || independentField === Field.POOL {independentField === Field.TOKEN0 || independentField === Field.LIQUIDITY
? route?.midPrice.toSignificant(6) ? route?.midPrice.toSignificant(6)
: route?.midPrice.invert().toSignificant(6)}{' '} : route?.midPrice.invert().toSignificant(6)}{' '}
{exchange?.token1.symbol} {exchange?.token1.symbol}
...@@ -765,9 +643,9 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -765,9 +643,9 @@ export default function RemoveLiquidity({ token0, token1 }) {
</ButtonPrimary> </ButtonPrimary>
<FixedBottom> <FixedBottom>
<PositionCard <PositionCard
exchangeAddress={exchange.liquidityToken.address} exchangeAddress={exchange?.liquidityToken.address}
token0={exchange.token0} token0={exchange?.token0}
token1={exchange.token1} token1={exchange?.token1}
minimal={true} minimal={true}
/> />
</FixedBottom> </FixedBottom>
......
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