Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
interface
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
LuckySwap
interface
Commits
7f61b679
Unverified
Commit
7f61b679
authored
Apr 26, 2021
by
Moody Salem
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first pass v3 routing code
parent
466c0b01
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
251 additions
and
57 deletions
+251
-57
index.ts
src/constants/index.ts
+1
-1
useAllV3Routes.ts
src/hooks/useAllV3Routes.ts
+6
-5
useApproveCallback.ts
src/hooks/useApproveCallback.ts
+8
-5
useBestV3Trade.ts
src/hooks/useBestV3Trade.ts
+179
-0
useToggledVersion.ts
src/hooks/useToggledVersion.ts
+9
-2
index.tsx
src/pages/AddLiquidityV2/index.tsx
+3
-3
index.tsx
src/pages/RemoveLiquidity/index.tsx
+3
-3
index.tsx
src/pages/Swap/index.tsx
+14
-6
hooks.ts
src/state/swap/hooks.ts
+20
-26
index.ts
src/utils/index.ts
+2
-2
prices.ts
src/utils/prices.ts
+6
-4
No files found.
src/constants/index.ts
View file @
7f61b679
...
@@ -18,7 +18,7 @@ export const MULTICALL2_ADDRESSES: { [chainId in ChainId]: string } = {
...
@@ -18,7 +18,7 @@ export const MULTICALL2_ADDRESSES: { [chainId in ChainId]: string } = {
[
ChainId
.
G
Ö
RLI
]:
'
0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696
'
,
[
ChainId
.
G
Ö
RLI
]:
'
0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696
'
,
}
}
export
const
ROUTER_ADDRESS
=
'
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
'
export
const
V2_
ROUTER_ADDRESS
=
'
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
'
export
const
ZERO_ADDRESS
=
'
0x0000000000000000000000000000000000000000
'
export
const
ZERO_ADDRESS
=
'
0x0000000000000000000000000000000000000000
'
...
...
src/hooks/useAllV3Routes.ts
View file @
7f61b679
...
@@ -50,13 +50,14 @@ function computeAllRoutes(
...
@@ -50,13 +50,14 @@ function computeAllRoutes(
* @param currencyIn the input currency
* @param currencyIn the input currency
* @param currencyOut the output currency
* @param currencyOut the output currency
*/
*/
export
function
useAllV3Routes
(
currencyIn
?:
Currency
,
currencyOut
?:
Currency
):
Route
[]
{
export
function
useAllV3Routes
(
currencyIn
?:
Currency
,
currencyOut
?:
Currency
):
{
loading
:
boolean
;
routes
:
Route
[]
}
{
const
{
chainId
}
=
useActiveWeb3React
()
const
{
chainId
}
=
useActiveWeb3React
()
const
{
pools
}
=
useV3SwapPools
(
currencyIn
,
currencyOut
)
const
{
pools
,
loading
:
poolsLoading
}
=
useV3SwapPools
(
currencyIn
,
currencyOut
)
return
useMemo
(()
=>
{
return
useMemo
(()
=>
{
if
(
!
chainId
||
!
pools
||
!
currencyIn
||
!
currencyOut
)
return
[]
if
(
poolsLoading
||
!
chainId
||
!
pools
||
!
currencyIn
||
!
currencyOut
)
return
{
loading
:
true
,
routes
:
[]
}
return
computeAllRoutes
(
currencyIn
,
currencyOut
,
pools
,
chainId
)
const
routes
=
computeAllRoutes
(
currencyIn
,
currencyOut
,
pools
,
chainId
)
},
[
chainId
,
currencyIn
,
currencyOut
,
pools
])
return
{
loading
:
false
,
routes
}
},
[
chainId
,
currencyIn
,
currencyOut
,
pools
,
poolsLoading
])
}
}
src/hooks/useApproveCallback.ts
View file @
7f61b679
import
{
MaxUint256
}
from
'
@ethersproject/constants
'
import
{
MaxUint256
}
from
'
@ethersproject/constants
'
import
{
TransactionResponse
}
from
'
@ethersproject/providers
'
import
{
TransactionResponse
}
from
'
@ethersproject/providers
'
import
{
TokenAmount
,
CurrencyAmount
,
ETHER
}
from
'
@uniswap/sdk-core
'
import
{
TokenAmount
,
CurrencyAmount
,
ETHER
,
ChainId
}
from
'
@uniswap/sdk-core
'
import
{
Trade
}
from
'
@uniswap/v2-sdk
'
import
{
Trade
as
V2Trade
}
from
'
@uniswap/v2-sdk
'
import
{
SWAP_ROUTER_ADDRESS
,
Trade
as
V3Trade
}
from
'
@uniswap/v3-sdk
'
import
{
useCallback
,
useMemo
}
from
'
react
'
import
{
useCallback
,
useMemo
}
from
'
react
'
import
{
ROUTER_ADDRESS
}
from
'
../constants
'
import
{
V2_
ROUTER_ADDRESS
}
from
'
../constants
'
import
{
Field
}
from
'
../state/swap/actions
'
import
{
Field
}
from
'
../state/swap/actions
'
import
{
useTransactionAdder
,
useHasPendingApproval
}
from
'
../state/transactions/hooks
'
import
{
useTransactionAdder
,
useHasPendingApproval
}
from
'
../state/transactions/hooks
'
import
{
computeSlippageAdjustedAmounts
}
from
'
../utils/prices
'
import
{
computeSlippageAdjustedAmounts
}
from
'
../utils/prices
'
...
@@ -99,10 +100,12 @@ export function useApproveCallback(
...
@@ -99,10 +100,12 @@ export function useApproveCallback(
}
}
// wraps useApproveCallback in the context of a swap
// wraps useApproveCallback in the context of a swap
export
function
useApproveCallbackFromTrade
(
trade
?:
Trade
,
allowedSlippage
=
0
)
{
export
function
useApproveCallbackFromTrade
(
trade
?:
V2Trade
|
V3Trade
,
allowedSlippage
=
0
)
{
const
{
chainId
}
=
useActiveWeb3React
()
const
swapRouterAddress
=
SWAP_ROUTER_ADDRESS
[
chainId
as
ChainId
]
const
amountToApprove
=
useMemo
(
const
amountToApprove
=
useMemo
(
()
=>
(
trade
?
computeSlippageAdjustedAmounts
(
trade
,
allowedSlippage
)[
Field
.
INPUT
]
:
undefined
),
()
=>
(
trade
?
computeSlippageAdjustedAmounts
(
trade
,
allowedSlippage
)[
Field
.
INPUT
]
:
undefined
),
[
trade
,
allowedSlippage
]
[
trade
,
allowedSlippage
]
)
)
return
useApproveCallback
(
amountToApprove
,
ROUTER_ADDRESS
)
return
useApproveCallback
(
amountToApprove
,
trade
instanceof
V2Trade
?
V2_ROUTER_ADDRESS
:
swapRouterAddress
)
}
}
src/hooks/useBestV3
Rout
e.ts
→
src/hooks/useBestV3
Trad
e.ts
View file @
7f61b679
import
{
Token
,
Currency
,
CurrencyAmount
,
TokenAmount
}
from
'
@uniswap/sdk-core
'
import
{
Token
,
Currency
,
CurrencyAmount
,
TokenAmount
,
TradeType
}
from
'
@uniswap/sdk-core
'
import
{
encodeRouteToPath
,
Route
}
from
'
@uniswap/v3-sdk
'
import
{
encodeRouteToPath
,
Route
,
Trade
}
from
'
@uniswap/v3-sdk
'
import
{
BigNumber
}
from
'
ethers
'
import
{
useMemo
}
from
'
react
'
import
{
useMemo
}
from
'
react
'
import
{
useSingleContractMultipleData
}
from
'
../state/multicall/hooks
'
import
{
useSingleContractMultipleData
}
from
'
../state/multicall/hooks
'
import
{
useActiveWeb3React
}
from
'
./index
'
import
{
useAllV3Routes
}
from
'
./useAllV3Routes
'
import
{
useAllV3Routes
}
from
'
./useAllV3Routes
'
import
{
useV3Quoter
}
from
'
./useContract
'
import
{
useV3Quoter
}
from
'
./useContract
'
import
{
BigNumber
}
from
'
ethers
'
enum
V3TradeState
{
LOADING
,
INVALID
,
NO_ROUTE_FOUND
,
VALID
,
SYNCING
,
}
/**
/**
* Returns the best
route for a given exact input swap, and the amount received for it
* Returns the best
v3 trade for a desired exact input swap
* @param amountIn the amount to swap in
* @param amountIn the amount to swap in
* @param currencyOut the desired output currency
* @param currencyOut the desired output currency
*/
*/
export
function
useBestV3
Rout
eExactIn
(
export
function
useBestV3
Trad
eExactIn
(
amountIn
?:
CurrencyAmount
,
amountIn
?:
CurrencyAmount
,
currencyOut
?:
Currency
currencyOut
?:
Currency
):
{
route
:
Route
;
amountOut
:
CurrencyAmount
}
|
null
{
):
{
state
:
V3TradeState
;
trade
:
Trade
|
null
}
{
const
{
chainId
}
=
useActiveWeb3React
()
const
quoter
=
useV3Quoter
()
const
quoter
=
useV3Quoter
()
const
routes
=
useAllV3Routes
(
amountIn
?.
currency
,
currencyOut
)
const
{
routes
,
loading
:
routesLoading
}
=
useAllV3Routes
(
amountIn
?.
currency
,
currencyOut
)
const
paths
=
useMemo
(()
=>
{
if
(
!
chainId
)
return
[]
return
routes
.
map
((
route
)
=>
encodeRouteToPath
(
route
,
false
))
},
[
chainId
,
routes
])
const
quoteExactInInputs
=
useMemo
(()
=>
{
const
quoteExactInInputs
=
useMemo
(()
=>
{
return
paths
.
map
((
path
)
=>
[
path
,
amountIn
?
`0x
${
amountIn
.
raw
.
toString
(
16
)}
`
:
undefined
])
return
routes
.
map
((
route
)
=>
[
},
[
amountIn
,
paths
])
encodeRouteToPath
(
route
,
false
),
amountIn
?
`0x
${
amountIn
.
raw
.
toString
(
16
)}
`
:
undefined
,
])
},
[
amountIn
,
routes
])
const
quotesResults
=
useSingleContractMultipleData
(
quoter
,
'
quoteExactInput
'
,
quoteExactInInputs
)
const
quotesResults
=
useSingleContractMultipleData
(
quoter
,
'
quoteExactInput
'
,
quoteExactInInputs
)
return
useMemo
(()
=>
{
return
useMemo
(()
=>
{
if
(
!
amountIn
||
!
currencyOut
||
quotesResults
.
some
(({
valid
})
=>
!
valid
))
{
return
{
state
:
V3TradeState
.
INVALID
,
trade
:
null
,
}
}
if
(
routesLoading
||
quotesResults
.
some
(({
loading
})
=>
loading
))
{
return
{
state
:
V3TradeState
.
LOADING
,
trade
:
null
,
}
}
const
{
bestRoute
,
amountOut
}
=
quotesResults
.
reduce
(
const
{
bestRoute
,
amountOut
}
=
quotesResults
.
reduce
(
(
best
:
{
bestRoute
:
Route
|
null
;
amountOut
:
BigNumber
|
null
},
{
valid
,
loading
,
result
},
i
)
=>
{
(
currentBest
:
{
bestRoute
:
Route
|
null
;
amountOut
:
BigNumber
|
null
},
{
result
},
i
)
=>
{
if
(
loading
||
!
valid
||
!
result
)
return
b
est
if
(
!
result
)
return
currentB
est
if
(
b
est
.
amountOut
===
null
)
{
if
(
currentB
est
.
amountOut
===
null
)
{
return
{
return
{
bestRoute
:
routes
[
i
],
bestRoute
:
routes
[
i
],
amountOut
:
result
.
amountOut
,
amountOut
:
result
.
amountOut
,
}
}
}
else
if
(
b
est
.
amountOut
.
lt
(
result
.
amountOut
))
{
}
else
if
(
currentB
est
.
amountOut
.
lt
(
result
.
amountOut
))
{
return
{
return
{
bestRoute
:
routes
[
i
],
bestRoute
:
routes
[
i
],
amountOut
:
result
.
amountOut
,
amountOut
:
result
.
amountOut
,
}
}
}
}
return
b
est
return
currentB
est
},
},
{
{
bestRoute
:
null
,
bestRoute
:
null
,
amountOut
:
null
,
amountOut
:
null
,
}
}
)
)
if
(
!
bestRoute
||
!
amountOut
)
return
null
if
(
!
bestRoute
||
!
amountOut
)
{
return
{
return
{
state
:
V3TradeState
.
NO_ROUTE_FOUND
,
trade
:
null
,
}
}
return
{
state
:
V3TradeState
.
VALID
,
trade
:
new
Trade
({
route
:
bestRoute
,
route
:
bestRoute
,
amountOut
:
tradeType
:
TradeType
.
EXACT_INPUT
,
inputAmount
:
amountIn
,
outputAmount
:
currencyOut
instanceof
Token
currencyOut
instanceof
Token
?
new
TokenAmount
(
currencyOut
,
amountOut
.
toString
())
?
new
TokenAmount
(
currencyOut
,
amountOut
.
toString
())
:
CurrencyAmount
.
ether
(
amountOut
.
toString
()),
:
CurrencyAmount
.
ether
(
amountOut
.
toString
()),
}),
}
}
},
[
currencyOut
,
quotesResults
,
routes
])
},
[
amountIn
,
currencyOut
,
quotesResults
,
routes
,
routesLoading
])
}
}
/**
/**
* Returns the best
route for a given exact output swap, and the amount required for it
* Returns the best
v3 trade for a desired exact output swap
* @param currencyIn the
current to swap in
* @param currencyIn the
desired input currency
* @param amountOut the
desired amount
out
* @param amountOut the
amount to swap
out
*/
*/
export
function
useBestV3
Rout
eExactOut
(
export
function
useBestV3
Trad
eExactOut
(
currencyIn
?:
Currency
,
currencyIn
?:
Currency
,
amountOut
?:
CurrencyAmount
amountOut
?:
CurrencyAmount
):
{
route
:
Route
;
amountIn
:
CurrencyAmount
}
|
null
{
):
{
state
:
V3TradeState
;
trade
:
Trade
|
null
}
{
const
{
chainId
}
=
useActiveWeb3React
()
const
quoter
=
useV3Quoter
()
const
quoter
=
useV3Quoter
()
const
routes
=
useAllV3Routes
(
currencyIn
,
amountOut
?.
currency
)
const
{
routes
,
loading
:
routesLoading
}
=
useAllV3Routes
(
currencyIn
,
amountOut
?.
currency
)
const
paths
=
useMemo
(()
=>
{
if
(
!
chainId
)
return
[]
return
routes
.
map
((
route
)
=>
encodeRouteToPath
(
route
,
true
))
},
[
chainId
,
routes
])
const
quoteExactOutInputs
=
useMemo
(()
=>
{
const
quoteExactOutInputs
=
useMemo
(()
=>
{
const
amountOutEncoded
=
amountOut
?
`0x
${
amountOut
.
raw
.
toString
(
16
)}
`
:
undefined
return
routes
.
map
((
route
)
=>
[
return
paths
.
map
((
path
)
=>
[
path
,
amountOutEncoded
])
encodeRouteToPath
(
route
,
true
),
},
[
amountOut
,
paths
])
amountOut
?
`0x
${
amountOut
.
raw
.
toString
(
16
)}
`
:
undefined
,
])
},
[
amountOut
,
routes
])
const
quotesResults
=
useSingleContractMultipleData
(
quoter
,
'
quoteExactInput
'
,
quoteExactOutInputs
)
const
quotesResults
=
useSingleContractMultipleData
(
quoter
,
'
quoteExactInput
'
,
quoteExactOutInputs
)
return
useMemo
(()
=>
{
return
useMemo
(()
=>
{
if
(
!
amountOut
||
!
currencyIn
||
quotesResults
.
some
(({
valid
})
=>
!
valid
))
{
return
{
state
:
V3TradeState
.
INVALID
,
trade
:
null
,
}
}
if
(
routesLoading
||
quotesResults
.
some
(({
loading
})
=>
loading
))
{
return
{
state
:
V3TradeState
.
LOADING
,
trade
:
null
,
}
}
const
{
bestRoute
,
amountIn
}
=
quotesResults
.
reduce
(
const
{
bestRoute
,
amountIn
}
=
quotesResults
.
reduce
(
(
best
:
{
bestRoute
:
Route
|
null
;
amountIn
:
BigNumber
|
null
},
{
valid
,
loading
,
result
},
i
)
=>
{
(
currentBest
:
{
bestRoute
:
Route
|
null
;
amountIn
:
BigNumber
|
null
},
{
result
},
i
)
=>
{
if
(
loading
||
!
valid
||
!
result
)
return
b
est
if
(
!
result
)
return
currentB
est
if
(
b
est
.
amountIn
===
null
)
{
if
(
currentB
est
.
amountIn
===
null
)
{
return
{
return
{
bestRoute
:
routes
[
i
],
bestRoute
:
routes
[
i
],
amountIn
:
result
.
amountIn
,
amountIn
:
result
.
amountIn
,
}
}
}
else
if
(
b
est
.
amountIn
.
gt
(
result
.
amountIn
))
{
}
else
if
(
currentB
est
.
amountIn
.
gt
(
result
.
amountIn
))
{
return
{
return
{
bestRoute
:
routes
[
i
],
bestRoute
:
routes
[
i
],
amountIn
:
result
.
amountIn
,
amountIn
:
result
.
amountIn
,
}
}
}
}
return
b
est
return
currentB
est
},
},
{
{
bestRoute
:
null
,
bestRoute
:
null
,
amountIn
:
null
,
amountIn
:
null
,
}
}
)
)
if
(
!
bestRoute
||
!
amountIn
)
return
null
if
(
!
bestRoute
||
!
amountIn
)
{
return
{
state
:
V3TradeState
.
NO_ROUTE_FOUND
,
trade
:
null
,
}
}
return
{
return
{
state
:
V3TradeState
.
VALID
,
trade
:
new
Trade
({
route
:
bestRoute
,
route
:
bestRoute
,
amountIn
:
tradeType
:
TradeType
.
EXACT_INPUT
,
inputAmount
:
currencyIn
instanceof
Token
currencyIn
instanceof
Token
?
new
TokenAmount
(
currencyIn
,
amountIn
.
toString
())
?
new
TokenAmount
(
currencyIn
,
amountIn
.
toString
())
:
CurrencyAmount
.
ether
(
amountIn
.
toString
()),
:
CurrencyAmount
.
ether
(
amountIn
.
toString
()),
outputAmount
:
amountOut
,
}),
}
}
},
[
currencyIn
,
quotesResults
,
routes
])
},
[
amountOut
,
currencyIn
,
quotesResults
,
routes
,
routesLoading
])
}
}
src/hooks/useToggledVersion.ts
View file @
7f61b679
...
@@ -5,12 +5,19 @@ export enum Version {
...
@@ -5,12 +5,19 @@ export enum Version {
v3
=
'
v3
'
,
v3
=
'
v3
'
,
}
}
export
const
DEFAULT_VERSION
:
Version
=
Version
.
v
2
export
const
DEFAULT_VERSION
:
Version
=
Version
.
v
3
export
default
function
useToggledVersion
():
Version
{
export
default
function
useToggledVersion
():
Version
{
const
{
use
}
=
useParsedQueryString
()
const
{
use
}
=
useParsedQueryString
()
if
(
typeof
use
!==
'
string
'
)
{
if
(
typeof
use
!==
'
string
'
)
{
return
DEFAULT_VERSION
return
DEFAULT_VERSION
}
}
return
DEFAULT_VERSION
switch
(
use
.
toLowerCase
())
{
case
'
v2
'
:
return
Version
.
v2
case
'
v3
'
:
return
Version
.
v3
default
:
return
Version
.
v3
}
}
}
src/pages/AddLiquidityV2/index.tsx
View file @
7f61b679
...
@@ -17,7 +17,7 @@ import { AddRemoveTabs } from '../../components/NavigationTabs'
...
@@ -17,7 +17,7 @@ import { AddRemoveTabs } from '../../components/NavigationTabs'
import
{
MinimalPositionCard
}
from
'
../../components/PositionCard
'
import
{
MinimalPositionCard
}
from
'
../../components/PositionCard
'
import
Row
,
{
RowBetween
,
RowFlat
}
from
'
../../components/Row
'
import
Row
,
{
RowBetween
,
RowFlat
}
from
'
../../components/Row
'
import
{
ROUTER_ADDRESS
}
from
'
../../constants
'
import
{
V2_
ROUTER_ADDRESS
}
from
'
../../constants
'
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
'
...
@@ -121,8 +121,8 @@ export default function AddLiquidity({
...
@@ -121,8 +121,8 @@ export default function AddLiquidity({
)
)
// check whether the user has approved the router on the tokens
// check whether the user has approved the router on the tokens
const
[
approvalA
,
approveACallback
]
=
useApproveCallback
(
parsedAmounts
[
Field
.
CURRENCY_A
],
ROUTER_ADDRESS
)
const
[
approvalA
,
approveACallback
]
=
useApproveCallback
(
parsedAmounts
[
Field
.
CURRENCY_A
],
V2_
ROUTER_ADDRESS
)
const
[
approvalB
,
approveBCallback
]
=
useApproveCallback
(
parsedAmounts
[
Field
.
CURRENCY_B
],
ROUTER_ADDRESS
)
const
[
approvalB
,
approveBCallback
]
=
useApproveCallback
(
parsedAmounts
[
Field
.
CURRENCY_B
],
V2_
ROUTER_ADDRESS
)
const
addTransaction
=
useTransactionAdder
()
const
addTransaction
=
useTransactionAdder
()
...
...
src/pages/RemoveLiquidity/index.tsx
View file @
7f61b679
...
@@ -20,7 +20,7 @@ import Row, { RowBetween, RowFixed } from '../../components/Row'
...
@@ -20,7 +20,7 @@ import Row, { RowBetween, RowFixed } from '../../components/Row'
import
Slider
from
'
../../components/Slider
'
import
Slider
from
'
../../components/Slider
'
import
CurrencyLogo
from
'
../../components/CurrencyLogo
'
import
CurrencyLogo
from
'
../../components/CurrencyLogo
'
import
{
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
}
from
'
../../hooks/useContract
'
...
@@ -100,7 +100,7 @@ export default function RemoveLiquidity({
...
@@ -100,7 +100,7 @@ export default function RemoveLiquidity({
// allowance handling
// allowance handling
const
[
signatureData
,
setSignatureData
]
=
useState
<
{
v
:
number
;
r
:
string
;
s
:
string
;
deadline
:
number
}
|
null
>
(
null
)
const
[
signatureData
,
setSignatureData
]
=
useState
<
{
v
:
number
;
r
:
string
;
s
:
string
;
deadline
:
number
}
|
null
>
(
null
)
const
[
approval
,
approveCallback
]
=
useApproveCallback
(
parsedAmounts
[
Field
.
LIQUIDITY
],
ROUTER_ADDRESS
)
const
[
approval
,
approveCallback
]
=
useApproveCallback
(
parsedAmounts
[
Field
.
LIQUIDITY
],
V2_
ROUTER_ADDRESS
)
const
isArgentWallet
=
useIsArgentWallet
()
const
isArgentWallet
=
useIsArgentWallet
()
...
@@ -137,7 +137,7 @@ export default function RemoveLiquidity({
...
@@ -137,7 +137,7 @@ export default function RemoveLiquidity({
]
]
const
message
=
{
const
message
=
{
owner
:
account
,
owner
:
account
,
spender
:
ROUTER_ADDRESS
,
spender
:
V2_
ROUTER_ADDRESS
,
value
:
liquidityAmount
.
raw
.
toString
(),
value
:
liquidityAmount
.
raw
.
toString
(),
nonce
:
nonce
.
toHexString
(),
nonce
:
nonce
.
toHexString
(),
deadline
:
deadline
.
toNumber
(),
deadline
:
deadline
.
toNumber
(),
...
...
src/pages/Swap/index.tsx
View file @
7f61b679
...
@@ -89,7 +89,14 @@ export default function Swap({ history }: RouteComponentProps) {
...
@@ -89,7 +89,14 @@ export default function Swap({ history }: RouteComponentProps) {
// swap state
// swap state
const
{
independentField
,
typedValue
,
recipient
}
=
useSwapState
()
const
{
independentField
,
typedValue
,
recipient
}
=
useSwapState
()
const
{
v2Trade
,
currencyBalances
,
parsedAmount
,
currencies
,
inputError
:
swapInputError
}
=
useDerivedSwapInfo
()
const
{
v2Trade
,
currencyBalances
,
parsedAmount
,
currencies
,
inputError
:
swapInputError
,
v3Trade
,
}
=
useDerivedSwapInfo
()
const
{
wrapType
,
execute
:
onWrap
,
inputError
:
wrapInputError
}
=
useWrapCallback
(
const
{
wrapType
,
execute
:
onWrap
,
inputError
:
wrapInputError
}
=
useWrapCallback
(
currencies
[
Field
.
INPUT
],
currencies
[
Field
.
INPUT
],
...
@@ -99,11 +106,12 @@ export default function Swap({ history }: RouteComponentProps) {
...
@@ -99,11 +106,12 @@ export default function Swap({ history }: RouteComponentProps) {
const
showWrap
:
boolean
=
wrapType
!==
WrapType
.
NOT_APPLICABLE
const
showWrap
:
boolean
=
wrapType
!==
WrapType
.
NOT_APPLICABLE
const
{
address
:
recipientAddress
}
=
useENSAddress
(
recipient
)
const
{
address
:
recipientAddress
}
=
useENSAddress
(
recipient
)
const
toggledVersion
=
useToggledVersion
()
const
toggledVersion
=
useToggledVersion
()
const
tradesByVersion
=
{
const
trade
=
showWrap
?
undefined
:
v2Trade
/*{
[Version.v2]: v2Trade,
[Version.v2]: v2Trade,
[
Version
.
v3
]:
undefined
,
[Version.v3]: v3Trade,
}
}[toggledVersion]*/
const
trade
=
showWrap
?
undefined
:
tradesByVersion
[
toggledVersion
]
const
parsedAmounts
=
showWrap
const
parsedAmounts
=
showWrap
?
{
?
{
...
...
src/state/swap/hooks.ts
View file @
7f61b679
import
{
Rout
e
}
from
'
@uniswap/v3-sdk
'
import
{
Trade
as
V3Trad
e
}
from
'
@uniswap/v3-sdk
'
import
{
useBestV3
RouteExactIn
,
useBestV3RouteExactOut
}
from
'
../../hooks/useBestV3Rout
e
'
import
{
useBestV3
TradeExactIn
,
useBestV3TradeExactOut
}
from
'
../../hooks/useBestV3Trad
e
'
import
useENS
from
'
../../hooks/useENS
'
import
useENS
from
'
../../hooks/useENS
'
import
{
parseUnits
}
from
'
@ethersproject/units
'
import
{
parseUnits
}
from
'
@ethersproject/units
'
import
{
Currency
,
CurrencyAmount
,
ETHER
,
Token
,
TokenAmount
}
from
'
@uniswap/sdk-core
'
import
{
Currency
,
CurrencyAmount
,
ETHER
,
Token
,
TokenAmount
}
from
'
@uniswap/sdk-core
'
import
{
JSBI
,
Trade
}
from
'
@uniswap/v2-sdk
'
import
{
JSBI
,
Trade
as
V2Trade
}
from
'
@uniswap/v2-sdk
'
import
{
ParsedQs
}
from
'
qs
'
import
{
ParsedQs
}
from
'
qs
'
import
{
useCallback
,
useEffect
,
useState
}
from
'
react
'
import
{
useCallback
,
useEffect
,
useState
}
from
'
react
'
import
{
useDispatch
,
useSelector
}
from
'
react-redux
'
import
{
useDispatch
,
useSelector
}
from
'
react-redux
'
...
@@ -99,10 +99,13 @@ const BAD_RECIPIENT_ADDRESSES: { [address: string]: true } = {
...
@@ -99,10 +99,13 @@ const BAD_RECIPIENT_ADDRESSES: { [address: string]: true } = {
* @param trade to check for the given address
* @param trade to check for the given address
* @param checksummedAddress address to check in the pairs and tokens
* @param checksummedAddress address to check in the pairs and tokens
*/
*/
function
involvesAddress
(
trade
:
Trade
,
checksummedAddress
:
string
):
boolean
{
function
involvesAddress
(
trade
:
V2Trade
|
V3Trade
,
checksummedAddress
:
string
):
boolean
{
const
path
=
trade
instanceof
V2Trade
?
trade
.
route
.
path
:
trade
.
route
.
tokenPath
return
(
return
(
trade
.
route
.
path
.
some
((
token
)
=>
token
.
address
===
checksummedAddress
)
||
path
.
some
((
token
)
=>
token
.
address
===
checksummedAddress
)
||
trade
.
route
.
pairs
.
some
((
pair
)
=>
pair
.
liquidityToken
.
address
===
checksummedAddress
)
(
trade
instanceof
V2Trade
?
trade
.
route
.
pairs
.
some
((
pair
)
=>
pair
.
liquidityToken
.
address
===
checksummedAddress
)
:
false
)
)
)
}
}
...
@@ -111,18 +114,9 @@ export function useDerivedSwapInfo(): {
...
@@ -111,18 +114,9 @@ export function useDerivedSwapInfo(): {
currencies
:
{
[
field
in
Field
]?:
Currency
}
currencies
:
{
[
field
in
Field
]?:
Currency
}
currencyBalances
:
{
[
field
in
Field
]?:
CurrencyAmount
}
currencyBalances
:
{
[
field
in
Field
]?:
CurrencyAmount
}
parsedAmount
:
CurrencyAmount
|
undefined
parsedAmount
:
CurrencyAmount
|
undefined
v2Trade
:
Trade
|
undefined
v2Trade
:
V2
Trade
|
undefined
inputError
?:
string
inputError
?:
string
v3Route
:
v3Trade
:
V3Trade
|
undefined
|
{
route
:
Route
amountIn
:
CurrencyAmount
}
|
{
route
:
Route
amountOut
:
CurrencyAmount
}
|
undefined
}
{
}
{
const
{
account
}
=
useActiveWeb3React
()
const
{
account
}
=
useActiveWeb3React
()
...
@@ -147,14 +141,14 @@ export function useDerivedSwapInfo(): {
...
@@ -147,14 +141,14 @@ export function useDerivedSwapInfo(): {
const
isExactIn
:
boolean
=
independentField
===
Field
.
INPUT
const
isExactIn
:
boolean
=
independentField
===
Field
.
INPUT
const
parsedAmount
=
tryParseAmount
(
typedValue
,
(
isExactIn
?
inputCurrency
:
outputCurrency
)
??
undefined
)
const
parsedAmount
=
tryParseAmount
(
typedValue
,
(
isExactIn
?
inputCurrency
:
outputCurrency
)
??
undefined
)
const
bestTradeExactIn
=
useV2TradeExactIn
(
isExactIn
?
parsedAmount
:
undefined
,
outputCurrency
??
undefined
)
const
best
V2
TradeExactIn
=
useV2TradeExactIn
(
isExactIn
?
parsedAmount
:
undefined
,
outputCurrency
??
undefined
)
const
bestTradeExactOut
=
useV2TradeExactOut
(
inputCurrency
??
undefined
,
!
isExactIn
?
parsedAmount
:
undefined
)
const
best
V2
TradeExactOut
=
useV2TradeExactOut
(
inputCurrency
??
undefined
,
!
isExactIn
?
parsedAmount
:
undefined
)
const
best
RouteExactInV3
=
useBestV3Rout
eExactIn
(
isExactIn
?
parsedAmount
:
undefined
,
outputCurrency
??
undefined
)
const
best
V3TradeExactIn
=
useBestV3Trad
eExactIn
(
isExactIn
?
parsedAmount
:
undefined
,
outputCurrency
??
undefined
)
const
best
RouteExactOutV3
=
useBestV3Rout
eExactOut
(
inputCurrency
??
undefined
,
!
isExactIn
?
parsedAmount
:
undefined
)
const
best
V3TradeExactOut
=
useBestV3Trad
eExactOut
(
inputCurrency
??
undefined
,
!
isExactIn
?
parsedAmount
:
undefined
)
const
v2Trade
=
isExactIn
?
best
TradeExactIn
:
best
TradeExactOut
const
v2Trade
=
isExactIn
?
best
V2TradeExactIn
:
bestV2
TradeExactOut
const
v3
Route
=
(
isExactIn
?
bestRouteExactInV3
:
bestRouteExactOutV3
)
??
undefined
const
v3
Trade
=
(
isExactIn
?
bestV3TradeExactIn
:
bestV3TradeExactOut
)
??
undefined
const
currencyBalances
=
{
const
currencyBalances
=
{
[
Field
.
INPUT
]:
relevantTokenBalances
[
0
],
[
Field
.
INPUT
]:
relevantTokenBalances
[
0
],
...
@@ -185,8 +179,8 @@ export function useDerivedSwapInfo(): {
...
@@ -185,8 +179,8 @@ export function useDerivedSwapInfo(): {
}
else
{
}
else
{
if
(
if
(
BAD_RECIPIENT_ADDRESSES
[
formattedTo
]
||
BAD_RECIPIENT_ADDRESSES
[
formattedTo
]
||
(
best
TradeExactIn
&&
involvesAddress
(
best
TradeExactIn
,
formattedTo
))
||
(
best
V2TradeExactIn
&&
involvesAddress
(
bestV2
TradeExactIn
,
formattedTo
))
||
(
best
TradeExactOut
&&
involvesAddress
(
best
TradeExactOut
,
formattedTo
))
(
best
V2TradeExactOut
&&
involvesAddress
(
bestV2
TradeExactOut
,
formattedTo
))
)
{
)
{
inputError
=
inputError
??
'
Invalid recipient
'
inputError
=
inputError
??
'
Invalid recipient
'
}
}
...
@@ -212,7 +206,7 @@ export function useDerivedSwapInfo(): {
...
@@ -212,7 +206,7 @@ export function useDerivedSwapInfo(): {
parsedAmount
,
parsedAmount
,
v2Trade
:
v2Trade
??
undefined
,
v2Trade
:
v2Trade
??
undefined
,
inputError
,
inputError
,
v3
Route
,
v3
Trade
:
v3Trade
.
trade
??
undefined
,
}
}
}
}
...
...
src/utils/index.ts
View file @
7f61b679
...
@@ -6,7 +6,7 @@ import { JsonRpcSigner, Web3Provider } from '@ethersproject/providers'
...
@@ -6,7 +6,7 @@ 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
{
abi
as
IUniswapV2Router02ABI
}
from
'
@uniswap/v2-periphery/build/IUniswapV2Router02.json
'
import
{
ROUTER_ADDRESS
}
from
'
../constants
'
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
{
TokenAddressMap
}
from
'
../state/lists/hooks
'
import
{
TokenAddressMap
}
from
'
../state/lists/hooks
'
...
@@ -102,7 +102,7 @@ export function getContract(address: string, ABI: any, library: Web3Provider, ac
...
@@ -102,7 +102,7 @@ export function getContract(address: string, ABI: any, library: Web3Provider, ac
// account is optional
// account is optional
export
function
getRouterContract
(
_
:
number
,
library
:
Web3Provider
,
account
?:
string
):
Contract
{
export
function
getRouterContract
(
_
:
number
,
library
:
Web3Provider
,
account
?:
string
):
Contract
{
return
getContract
(
ROUTER_ADDRESS
,
IUniswapV2Router02ABI
,
library
,
account
)
return
getContract
(
V2_
ROUTER_ADDRESS
,
IUniswapV2Router02ABI
,
library
,
account
)
}
}
export
function
escapeRegExp
(
string
:
string
):
string
{
export
function
escapeRegExp
(
string
:
string
):
string
{
...
...
src/utils/prices.ts
View file @
7f61b679
import
JSBI
from
'
jsbi
'
import
{
BLOCKED_PRICE_IMPACT_NON_EXPERT
}
from
'
../constants
'
import
{
BLOCKED_PRICE_IMPACT_NON_EXPERT
}
from
'
../constants
'
import
{
CurrencyAmount
,
Fraction
,
Percent
,
TokenAmount
}
from
'
@uniswap/sdk-core
'
import
{
CurrencyAmount
,
Fraction
,
Percent
,
TokenAmount
}
from
'
@uniswap/sdk-core
'
import
{
JSBI
,
Trade
}
from
'
@uniswap/v2-sdk
'
import
{
Trade
as
V2Trade
}
from
'
@uniswap/v2-sdk
'
import
{
Trade
as
V3Trade
}
from
'
@uniswap/v3-sdk
'
import
{
ALLOWED_PRICE_IMPACT_HIGH
,
ALLOWED_PRICE_IMPACT_LOW
,
ALLOWED_PRICE_IMPACT_MEDIUM
}
from
'
../constants
'
import
{
ALLOWED_PRICE_IMPACT_HIGH
,
ALLOWED_PRICE_IMPACT_LOW
,
ALLOWED_PRICE_IMPACT_MEDIUM
}
from
'
../constants
'
import
{
Field
}
from
'
../state/swap/actions
'
import
{
Field
}
from
'
../state/swap/actions
'
...
@@ -12,7 +14,7 @@ const INPUT_FRACTION_AFTER_FEE = ONE_HUNDRED_PERCENT.subtract(BASE_FEE)
...
@@ -12,7 +14,7 @@ const INPUT_FRACTION_AFTER_FEE = ONE_HUNDRED_PERCENT.subtract(BASE_FEE)
// computes price breakdown for the trade
// computes price breakdown for the trade
export
function
computeTradePriceBreakdown
(
export
function
computeTradePriceBreakdown
(
trade
?:
Trade
|
null
trade
?:
V2
Trade
|
null
):
{
priceImpactWithoutFee
:
Percent
|
undefined
;
realizedLPFee
:
CurrencyAmount
|
undefined
|
null
}
{
):
{
priceImpactWithoutFee
:
Percent
|
undefined
;
realizedLPFee
:
CurrencyAmount
|
undefined
|
null
}
{
// for each hop in our trade, take away the x*y=k price impact from 0.3% fees
// for each hop in our trade, take away the x*y=k price impact from 0.3% fees
// e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03))
// e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03))
...
@@ -46,7 +48,7 @@ export function computeTradePriceBreakdown(
...
@@ -46,7 +48,7 @@ export function computeTradePriceBreakdown(
// computes the minimum amount out and maximum amount in for a trade given a user specified allowed slippage in bips
// computes the minimum amount out and maximum amount in for a trade given a user specified allowed slippage in bips
export
function
computeSlippageAdjustedAmounts
(
export
function
computeSlippageAdjustedAmounts
(
trade
:
Trade
|
undefined
,
trade
:
V2Trade
|
V3
Trade
|
undefined
,
allowedSlippage
:
number
allowedSlippage
:
number
):
{
[
field
in
Field
]?:
CurrencyAmount
}
{
):
{
[
field
in
Field
]?:
CurrencyAmount
}
{
const
pct
=
basisPointsToPercent
(
allowedSlippage
)
const
pct
=
basisPointsToPercent
(
allowedSlippage
)
...
@@ -64,7 +66,7 @@ export function warningSeverity(priceImpact: Percent | undefined): 0 | 1 | 2 | 3
...
@@ -64,7 +66,7 @@ export function warningSeverity(priceImpact: Percent | undefined): 0 | 1 | 2 | 3
return
0
return
0
}
}
export
function
formatExecutionPrice
(
trade
?:
Trade
,
inverted
?:
boolean
):
string
{
export
function
formatExecutionPrice
(
trade
:
V2Trade
|
V3Trade
|
undefined
,
inverted
:
boolean
|
undefined
):
string
{
if
(
!
trade
)
{
if
(
!
trade
)
{
return
''
return
''
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment