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
ccab6f01
Unverified
Commit
ccab6f01
authored
May 20, 2020
by
Moody Salem
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More tests for add/remove liquidity and fix the automatic loading of tokens in those pages
parent
384c3cad
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
64 additions
and
34 deletions
+64
-34
add-liquidity.test.ts
cypress/integration/add-liquidity.test.ts
+14
-5
remove-liquidity.test.ts
cypress/integration/remove-liquidity.test.ts
+19
-0
Tokens.ts
src/hooks/Tokens.ts
+11
-8
index.tsx
src/pages/AddLiquidity/index.tsx
+11
-6
index.tsx
src/pages/RemoveLiquidity/index.tsx
+5
-13
hooks.tsx
src/state/user/hooks.tsx
+4
-2
No files found.
cypress/integration/add-liquidity.test.ts
View file @
ccab6f01
describe
(
'
Add Liquidity
'
,
()
=>
{
describe
(
'
Add Liquidity
'
,
()
=>
{
beforeEach
(()
=>
it
(
'
loads the two correct tokens
'
,
()
=>
{
cy
.
visit
(
'
/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85-0xc778417E063141139Fce010982780140Aa0cD5Ab
'
)
cy
.
visit
(
'
/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85-0xc778417E063141139Fce010982780140Aa0cD5Ab
'
)
)
cy
.
get
(
'
#add-liquidity-input-token0 .token-symbol-container
'
).
should
(
'
contain.text
'
,
'
MKR
'
)
cy
.
get
(
'
#add-liquidity-input-token1 .token-symbol-container
'
).
should
(
'
contain.text
'
,
'
ETH
'
)
})
it
(
'
loads the two correct tokens
'
,
()
=>
{
it
(
'
does not crash if ETH is duplicated
'
,
()
=>
{
cy
.
get
(
'
#add-liquidity-input-token0 .token-symbol-container
'
).
should
(
'
contain
'
,
'
MKR
'
)
cy
.
visit
(
'
/add/0xc778417E063141139Fce010982780140Aa0cD5Ab-0xc778417E063141139Fce010982780140Aa0cD5Ab
'
)
cy
.
get
(
'
#add-liquidity-input-token1 .token-symbol-container
'
).
should
(
'
contain
'
,
'
ETH
'
)
cy
.
get
(
'
#add-liquidity-input-token0 .token-symbol-container
'
).
should
(
'
contain.text
'
,
'
ETH
'
)
cy
.
get
(
'
#add-liquidity-input-token1 .token-symbol-container
'
).
should
(
'
not.contain.text
'
,
'
ETH
'
)
})
it
(
'
token not in storage is loaded
'
,
()
=>
{
cy
.
visit
(
'
/add/0xb290b2f9f8f108d03ff2af3ac5c8de6de31cdf6d-0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85
'
)
cy
.
get
(
'
#add-liquidity-input-token0 .token-symbol-container
'
).
should
(
'
contain.text
'
,
'
SKL
'
)
cy
.
get
(
'
#add-liquidity-input-token1 .token-symbol-container
'
).
should
(
'
contain.text
'
,
'
MKR
'
)
})
})
})
})
cypress/integration/remove-liquidity.test.ts
0 → 100644
View file @
ccab6f01
describe
(
'
Remove Liquidity
'
,
()
=>
{
it
(
'
loads the two correct tokens
'
,
()
=>
{
cy
.
visit
(
'
/remove/0xc778417E063141139Fce010982780140Aa0cD5Ab-0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85
'
)
cy
.
get
(
'
#remove-liquidity-token0-symbol
'
).
should
(
'
contain.text
'
,
'
ETH
'
)
cy
.
get
(
'
#remove-liquidity-token1-symbol
'
).
should
(
'
contain.text
'
,
'
MKR
'
)
})
it
(
'
does not crash if ETH is duplicated
'
,
()
=>
{
cy
.
visit
(
'
/remove/0xc778417E063141139Fce010982780140Aa0cD5Ab-0xc778417E063141139Fce010982780140Aa0cD5Ab
'
)
cy
.
get
(
'
#remove-liquidity-token0-symbol
'
).
should
(
'
contain.text
'
,
'
ETH
'
)
cy
.
get
(
'
#remove-liquidity-token1-symbol
'
).
should
(
'
not.contain.text
'
,
'
ETH
'
)
})
it
(
'
token not in storage is loaded
'
,
()
=>
{
cy
.
visit
(
'
/remove/0xb290b2f9f8f108d03ff2af3ac5c8de6de31cdf6d-0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85
'
)
cy
.
get
(
'
#remove-liquidity-token0-symbol
'
).
should
(
'
contain.text
'
,
'
SKL
'
)
cy
.
get
(
'
#remove-liquidity-token1-symbol
'
).
should
(
'
contain.text
'
,
'
MKR
'
)
})
})
src/hooks/Tokens.ts
View file @
ccab6f01
...
@@ -35,10 +35,13 @@ export function useAllTokens(): { [address: string]: Token } {
...
@@ -35,10 +35,13 @@ export function useAllTokens(): { [address: string]: Token } {
},
[
userAddedTokens
,
chainId
])
},
[
userAddedTokens
,
chainId
])
}
}
export
function
useToken
(
tokenAddress
:
string
):
Token
{
export
function
useToken
(
tokenAddress
?:
string
):
Token
|
undefined
{
const
tokens
=
useAllTokens
()
const
tokens
=
useAllTokens
()
return
useMemo
(()
=>
{
return
tokens
?.[
tokenAddress
]
const
validatedAddress
=
isAddress
(
tokenAddress
)
if
(
!
validatedAddress
)
return
return
tokens
[
validatedAddress
]
},
[
tokens
,
tokenAddress
])
}
}
// gets token information by address (typically user input) and
// gets token information by address (typically user input) and
...
@@ -46,22 +49,22 @@ export function useToken(tokenAddress: string): Token {
...
@@ -46,22 +49,22 @@ export function useToken(tokenAddress: string): Token {
export
function
useTokenByAddressAndAutomaticallyAdd
(
tokenAddress
?:
string
):
Token
|
undefined
{
export
function
useTokenByAddressAndAutomaticallyAdd
(
tokenAddress
?:
string
):
Token
|
undefined
{
const
fetchTokenByAddress
=
useFetchTokenByAddress
()
const
fetchTokenByAddress
=
useFetchTokenByAddress
()
const
addToken
=
useAddUserToken
()
const
addToken
=
useAddUserToken
()
const
allTokens
=
useAllTokens
(
)
const
token
=
useToken
(
tokenAddress
)
const
{
chainId
}
=
useActiveWeb3React
()
const
{
chainId
}
=
useActiveWeb3React
()
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
!
chainId
)
return
if
(
!
chainId
||
!
isAddress
(
tokenAddress
)
)
return
const
weth
=
WETH
[
chainId
as
ChainId
]
const
weth
=
WETH
[
chainId
as
ChainId
]
if
(
weth
&&
weth
.
address
===
isAddress
(
tokenAddress
))
return
if
(
weth
&&
weth
.
address
===
isAddress
(
tokenAddress
))
return
if
(
tokenAddress
&&
!
allTokens
?.[
tokenAddress
]
)
{
if
(
tokenAddress
&&
!
token
)
{
fetchTokenByAddress
(
tokenAddress
).
then
(
token
=>
{
fetchTokenByAddress
(
tokenAddress
).
then
(
token
=>
{
if
(
token
!==
null
)
{
if
(
token
!==
null
)
{
addToken
(
token
)
addToken
(
token
)
}
}
})
})
}
}
},
[
tokenAddress
,
allTokens
,
fetchTokenByAddress
,
addToken
,
chainId
])
},
[
tokenAddress
,
token
,
fetchTokenByAddress
,
addToken
,
chainId
])
return
token
Address
?
allTokens
?.[
tokenAddress
]
:
undefined
return
token
}
}
src/pages/AddLiquidity/index.tsx
View file @
ccab6f01
...
@@ -27,11 +27,11 @@ import { usePair } from '../../data/Reserves'
...
@@ -27,11 +27,11 @@ import { usePair } from '../../data/Reserves'
import
{
useTotalSupply
}
from
'
../../data/TotalSupply
'
import
{
useTotalSupply
}
from
'
../../data/TotalSupply
'
import
{
useTokenContract
,
useActiveWeb3React
}
from
'
../../hooks
'
import
{
useTokenContract
,
useActiveWeb3React
}
from
'
../../hooks
'
import
{
useToken
}
from
'
../../hooks/Tokens
'
import
{
useToken
ByAddressAndAutomaticallyAdd
}
from
'
../../hooks/Tokens
'
import
{
useHasPendingApproval
,
useTransactionAdder
}
from
'
../../state/transactions/hooks
'
import
{
useHasPendingApproval
,
useTransactionAdder
}
from
'
../../state/transactions/hooks
'
import
{
useTokenBalanceTreatingWETHasETH
}
from
'
../../state/wallet/hooks
'
import
{
useTokenBalanceTreatingWETHasETH
}
from
'
../../state/wallet/hooks
'
import
{
TYPE
}
from
'
../../theme
'
import
{
TYPE
}
from
'
../../theme
'
import
{
calculateGasMargin
,
calculateSlippageAmount
,
getRouterContract
}
from
'
../../utils
'
import
{
calculateGasMargin
,
calculateSlippageAmount
,
getRouterContract
,
isAddress
}
from
'
../../utils
'
import
AppBody
from
'
../AppBody
'
import
AppBody
from
'
../AppBody
'
import
{
Dots
,
Wrapper
}
from
'
../Pool/styleds
'
import
{
Dots
,
Wrapper
}
from
'
../Pool/styleds
'
...
@@ -64,14 +64,16 @@ interface AddState {
...
@@ -64,14 +64,16 @@ interface AddState {
}
}
function
initializeAddState
(
inputAddress
?:
string
,
outputAddress
?:
string
):
AddState
{
function
initializeAddState
(
inputAddress
?:
string
,
outputAddress
?:
string
):
AddState
{
const
validatedInput
=
isAddress
(
inputAddress
)
const
validatedOutput
=
isAddress
(
outputAddress
)
return
{
return
{
independentField
:
Field
.
INPUT
,
independentField
:
Field
.
INPUT
,
typedValue
:
''
,
typedValue
:
''
,
[
Field
.
INPUT
]:
{
[
Field
.
INPUT
]:
{
address
:
inputAddress
address
:
validatedInput
||
''
},
},
[
Field
.
OUTPUT
]:
{
[
Field
.
OUTPUT
]:
{
address
:
outputAddress
address
:
validatedOutput
&&
validatedOutput
!==
validatedInput
?
validatedOutput
:
''
}
}
}
}
}
}
...
@@ -152,10 +154,13 @@ export default function AddLiquidity({ match: { params } }: RouteComponentProps<
...
@@ -152,10 +154,13 @@ export default function AddLiquidity({ match: { params } }: RouteComponentProps<
const
{
independentField
,
typedValue
,
...
fieldData
}
=
state
const
{
independentField
,
typedValue
,
...
fieldData
}
=
state
const
dependentField
:
Field
=
independentField
===
Field
.
INPUT
?
Field
.
OUTPUT
:
Field
.
INPUT
const
dependentField
:
Field
=
independentField
===
Field
.
INPUT
?
Field
.
OUTPUT
:
Field
.
INPUT
const
inputToken
=
useTokenByAddressAndAutomaticallyAdd
(
fieldData
[
Field
.
INPUT
].
address
)
const
outputToken
=
useTokenByAddressAndAutomaticallyAdd
(
fieldData
[
Field
.
OUTPUT
].
address
)
// get basic SDK entities
// get basic SDK entities
const
tokens
:
{
[
field
in
Field
]:
Token
}
=
{
const
tokens
:
{
[
field
in
Field
]:
Token
}
=
{
[
Field
.
INPUT
]:
useToken
(
fieldData
[
Field
.
INPUT
].
address
)
,
[
Field
.
INPUT
]:
inputToken
,
[
Field
.
OUTPUT
]:
useToken
(
fieldData
[
Field
.
OUTPUT
].
address
)
[
Field
.
OUTPUT
]:
outputToken
}
}
// token contracts for approvals and direct sends
// token contracts for approvals and direct sends
...
...
src/pages/RemoveLiquidity/index.tsx
View file @
ccab6f01
...
@@ -106,14 +106,6 @@ function reducer(
...
@@ -106,14 +106,6 @@ function reducer(
}
}
}
}
function
useTokenByAddressOrETHAndAutomaticallyAdd
(
tokenId
?:
string
,
chainId
?:
number
):
Token
|
undefined
{
const
isWETH
=
tokenId
?.
toUpperCase
()
===
'
ETH
'
||
tokenId
?.
toUpperCase
()
===
'
WETH
'
const
tokenByAddress
=
useTokenByAddressAndAutomaticallyAdd
(
isWETH
?
null
:
tokenId
)
return
isWETH
?
WETH
[
chainId
]
:
tokenByAddress
}
export
default
function
RemoveLiquidity
({
match
:
{
params
}
}:
RouteComponentProps
<
{
tokens
:
string
}
>
)
{
export
default
function
RemoveLiquidity
({
match
:
{
params
}
}:
RouteComponentProps
<
{
tokens
:
string
}
>
)
{
const
[
token0
,
token1
]
=
params
.
tokens
.
split
(
'
-
'
)
const
[
token0
,
token1
]
=
params
.
tokens
.
split
(
'
-
'
)
...
@@ -123,13 +115,13 @@ export default function RemoveLiquidity({ match: { params } }: RouteComponentPro
...
@@ -123,13 +115,13 @@ export default function RemoveLiquidity({ match: { params } }: RouteComponentPro
const
[
showConfirm
,
setShowConfirm
]
=
useState
<
boolean
>
(
false
)
const
[
showConfirm
,
setShowConfirm
]
=
useState
<
boolean
>
(
false
)
const
[
showAdvanced
,
setShowAdvanced
]
=
useState
<
boolean
>
(
false
)
const
[
showAdvanced
,
setShowAdvanced
]
=
useState
<
boolean
>
(
false
)
const
inputToken
:
Token
=
useTokenByAddress
OrETHAndAutomaticallyAdd
(
token0
,
chainId
)
const
inputToken
:
Token
=
useTokenByAddress
AndAutomaticallyAdd
(
token0
)
const
outputToken
:
Token
=
useTokenByAddress
OrETHAndAutomaticallyAdd
(
token1
,
chainId
)
const
outputToken
:
Token
=
useTokenByAddress
AndAutomaticallyAdd
(
token1
)
// get basic SDK entities
// get basic SDK entities
const
tokens
:
{
[
field
in
Field
]?:
Token
}
=
{
const
tokens
:
{
[
field
in
Field
]?:
Token
}
=
{
[
Field
.
TOKEN0
]:
inputToken
,
[
Field
.
TOKEN0
]:
inputToken
,
[
Field
.
TOKEN1
]:
outputToken
[
Field
.
TOKEN1
]:
outputToken
&&
inputToken
&&
outputToken
.
equals
(
inputToken
)
?
undefined
:
outputToken
}
}
const
pair
=
usePair
(
inputToken
,
outputToken
)
const
pair
=
usePair
(
inputToken
,
outputToken
)
...
@@ -726,7 +718,7 @@ export default function RemoveLiquidity({ match: { params } }: RouteComponentPro
...
@@ -726,7 +718,7 @@ export default function RemoveLiquidity({ match: { params } }: RouteComponentPro
</Text>
</Text>
<RowFixed>
<RowFixed>
<TokenLogo address={tokens[Field.TOKEN0]?.address} style={{ marginRight: '12px' }} />
<TokenLogo address={tokens[Field.TOKEN0]?.address} style={{ marginRight: '12px' }} />
<Text fontSize={24} fontWeight={500}>
<Text fontSize={24} fontWeight={500}
id="remove-liquidity-token0-symbol"
>
{tokens[Field.TOKEN0]?.symbol}
{tokens[Field.TOKEN0]?.symbol}
</Text>
</Text>
</RowFixed>
</RowFixed>
...
@@ -737,7 +729,7 @@ export default function RemoveLiquidity({ match: { params } }: RouteComponentPro
...
@@ -737,7 +729,7 @@ export default function RemoveLiquidity({ match: { params } }: RouteComponentPro
</Text>
</Text>
<RowFixed>
<RowFixed>
<TokenLogo address={tokens[Field.TOKEN1]?.address} style={{ marginRight: '12px' }} />
<TokenLogo address={tokens[Field.TOKEN1]?.address} style={{ marginRight: '12px' }} />
<Text fontSize={24} fontWeight={500}>
<Text fontSize={24} fontWeight={500}
id="remove-liquidity-token1-symbol"
>
{tokens[Field.TOKEN1]?.symbol}
{tokens[Field.TOKEN1]?.symbol}
</Text>
</Text>
</RowFixed>
</RowFixed>
...
...
src/state/user/hooks.tsx
View file @
ccab6f01
...
@@ -3,7 +3,7 @@ import { useActiveWeb3React } from '../../hooks'
...
@@ -3,7 +3,7 @@ import { useActiveWeb3React } from '../../hooks'
import
{
useCallback
,
useMemo
}
from
'
react
'
import
{
useCallback
,
useMemo
}
from
'
react
'
import
{
shallowEqual
,
useDispatch
,
useSelector
}
from
'
react-redux
'
import
{
shallowEqual
,
useDispatch
,
useSelector
}
from
'
react-redux
'
import
{
useAllTokens
}
from
'
../../hooks/Tokens
'
import
{
useAllTokens
}
from
'
../../hooks/Tokens
'
import
{
getTokenDecimals
,
getTokenName
,
getTokenSymbol
}
from
'
../../utils
'
import
{
getTokenDecimals
,
getTokenName
,
getTokenSymbol
,
isAddress
}
from
'
../../utils
'
import
{
AppDispatch
,
AppState
}
from
'
../index
'
import
{
AppDispatch
,
AppState
}
from
'
../index
'
import
{
import
{
addSerializedPair
,
addSerializedPair
,
...
@@ -67,6 +67,8 @@ export function useFetchTokenByAddress(): (address: string) => Promise<Token | n
...
@@ -67,6 +67,8 @@ export function useFetchTokenByAddress(): (address: string) => Promise<Token | n
return
useCallback
(
return
useCallback
(
async
(
address
:
string
):
Promise
<
Token
|
null
>
=>
{
async
(
address
:
string
):
Promise
<
Token
|
null
>
=>
{
if
(
!
library
||
!
chainId
)
return
null
if
(
!
library
||
!
chainId
)
return
null
const
validatedAddress
=
isAddress
(
address
)
if
(
!
validatedAddress
)
return
null
const
[
decimals
,
symbol
,
name
]
=
await
Promise
.
all
([
const
[
decimals
,
symbol
,
name
]
=
await
Promise
.
all
([
getTokenDecimals
(
address
,
library
).
catch
(()
=>
null
),
getTokenDecimals
(
address
,
library
).
catch
(()
=>
null
),
getTokenSymbol
(
address
,
library
).
catch
(()
=>
'
UNKNOWN
'
),
getTokenSymbol
(
address
,
library
).
catch
(()
=>
'
UNKNOWN
'
),
...
@@ -76,7 +78,7 @@ export function useFetchTokenByAddress(): (address: string) => Promise<Token | n
...
@@ -76,7 +78,7 @@ export function useFetchTokenByAddress(): (address: string) => Promise<Token | n
if
(
decimals
===
null
)
{
if
(
decimals
===
null
)
{
return
null
return
null
}
else
{
}
else
{
return
new
Token
(
chainId
,
a
ddress
,
decimals
,
symbol
,
name
)
return
new
Token
(
chainId
,
validatedA
ddress
,
decimals
,
symbol
,
name
)
}
}
},
},
[
library
,
chainId
]
[
library
,
chainId
]
...
...
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