Commit d265b120 authored by ian-jh's avatar ian-jh

Merge remote-tracking branch 'upstream/beta' into beta

parents 870b3f7e 30887ef1
......@@ -80,5 +80,6 @@
"symbol": "Symbol",
"decimals": "Decimals",
"enterTokenCont": "Enter a token address to continue",
"priceChange": "This trade will cause the price to change by"
"priceChange": "Expected price slippage",
"forAtLeast" : "for at least "
}
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="9" cy="9" r="9" fill="#E1E1E1"/>
<path d="M8.06493 10.8317H9.15706V10.7592C9.17233 9.88089 9.42436 9.48757 10.0735 9.08662C10.7571 8.67421 11.1771 8.09378 11.1771 7.23459C11.1771 5.99354 10.2377 5.15344 8.83629 5.15344C7.54942 5.15344 6.51839 5.90571 6.46875 7.28041H7.62961C7.67543 6.47086 8.25204 6.11573 8.83629 6.11573C9.48546 6.11573 10.0124 6.54724 10.0124 7.22313C10.0124 7.79211 9.65729 8.19306 9.20288 8.47564C8.49262 8.91096 8.07257 9.34246 8.06493 10.7592V10.8317ZM8.64154 13.1534C9.05777 13.1534 9.40527 12.8136 9.40527 12.3897C9.40527 11.9735 9.05777 11.6298 8.64154 11.6298C8.22149 11.6298 7.87782 11.9735 7.87782 12.3897C7.87782 12.8136 8.22149 13.1534 8.64154 13.1534Z" fill="#737373"/>
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="8" cy="8" r="8" fill="#E1E1E1"/>
<path d="M7.09618 9.67828H8.18831V9.60573C8.20358 8.72745 8.45561 8.33413 9.10477 7.93317C9.78831 7.52076 10.2084 6.94033 10.2084 6.08115C10.2084 4.8401 9.26897 4 7.86754 4C6.58067 4 5.54964 4.75227 5.5 6.12697H6.66086C6.70668 5.31742 7.28329 4.96229 7.86754 4.96229C8.51671 4.96229 9.04368 5.39379 9.04368 6.06969C9.04368 6.63866 8.68854 7.03962 8.23413 7.3222C7.52387 7.75752 7.10382 8.18902 7.09618 9.60573V9.67828ZM7.67279 12C8.08902 12 8.43652 11.6601 8.43652 11.2363C8.43652 10.82 8.08902 10.4764 7.67279 10.4764C7.25274 10.4764 6.90907 10.82 6.90907 11.2363C6.90907 11.6601 7.25274 12 7.67279 12Z" fill="#737373"/>
</svg>
......@@ -21,7 +21,7 @@ const ContainerRow = styled.div`
justify-content: center;
align-items: center;
border-radius: 1.25rem;
box-shadow: 0 0 0 0.5px ${({ error, theme }) => (error ? theme.salmonRed : theme.mercuryGray)};
box-shadow: 0 0 0 1px ${({ error, theme }) => (error ? theme.salmonRed : theme.mercuryGray)};
background-color: ${({ theme }) => theme.white};
transition: box-shadow 200ms ease-in-out;
`
......
......@@ -32,10 +32,10 @@ const SummaryWrapperContainer = styled.div`
const Details = styled.div`
background-color: ${({ theme }) => theme.concreteGray};
padding: 1.5rem;
/* padding: 1.25rem 1.25rem 1rem 1.25rem; */
border-radius: 1rem;
font-size: 0.75rem;
margin-top: 1rem;
margin: 1rem 0.5rem 0 0.5rem;
`
const ErrorSpan = styled.span`
......@@ -89,13 +89,12 @@ export default function ContextualInfo({
closeDetailsText = 'Hide Details',
contextualInfo = '',
allowExpand = false,
renderTransactionDetails = () => {},
isError = false,
slippageWarning,
highSlippageWarning
highSlippageWarning,
dropDownContent
}) {
const [showDetails, setShowDetails] = useState(false)
return !allowExpand ? (
<SummaryWrapper>{contextualInfo}</SummaryWrapper>
) : (
......@@ -117,7 +116,7 @@ export default function ContextualInfo({
)}
</>
</SummaryWrapperContainer>
{showDetails && <Details>{renderTransactionDetails()}</Details>}
{showDetails && <Details>{dropDownContent()}</Details>}
</>
)
}
......@@ -70,7 +70,7 @@ const CurrencySelect = styled.button`
}
:focus {
box-shadow: 0 0 0.5px 0.5px ${({ theme }) => theme.malibuBlue};
box-shadow: 0 0 1px 1px ${({ theme }) => theme.malibuBlue};
}
:active {
......@@ -104,12 +104,12 @@ const InputPanel = styled.div`
const Container = styled.div`
border-radius: 1.25rem;
box-shadow: 0 0 0 0.5px ${({ error, theme }) => (error ? theme.salmonRed : theme.mercuryGray)};
box-shadow: 0 0 0 1px ${({ error, theme }) => (error ? theme.salmonRed : theme.mercuryGray)};
background-color: ${({ theme }) => theme.white};
transition: box-shadow 200ms ease-in-out;
:focus-within {
box-shadow: 0 0 0.5px 0.5px ${({ theme }) => theme.malibuBlue};
box-shadow: 0 0 1px 1px ${({ theme }) => theme.malibuBlue};
}
`
......
......@@ -5,7 +5,8 @@ import { DialogOverlay, DialogContent } from '@reach/dialog'
import '@reach/dialog/styles.css'
const AnimatedDialogOverlay = animated(DialogOverlay)
const StyledDialogOverlay = styled(AnimatedDialogOverlay).attrs({
const WrappedDialogOverlay = ({ suppressClassNameWarning, ...rest }) => <AnimatedDialogOverlay {...rest} />
const StyledDialogOverlay = styled(WrappedDialogOverlay).attrs({
suppressClassNameWarning: true
})`
&[data-reach-dialog-overlay] {
......
......@@ -5,7 +5,7 @@ import styled from 'styled-components'
import { transparentize, darken } from 'polished'
import { useBodyKeyDown } from '../../hooks'
import { useBetaMessageManager } from '../../contexts/Application'
import { useBetaMessageManager } from '../../contexts/LocalStorage'
const tabOrder = [
{
......@@ -84,11 +84,11 @@ const StyledNavLink = styled(NavLink).attrs({
&.${activeClassName} {
background-color: ${({ theme }) => theme.white};
border-radius: 3rem;
box-shadow: 0 0 0.5px 1px ${({ theme }) => theme.mercuryGray};
box-shadow: 0 0 1px 1px ${({ theme }) => theme.mercuryGray};
font-weight: 500;
color: ${({ theme }) => theme.royalBlue};
:hover {
box-shadow: 0 0 0.5px 1px ${({ theme }) => darken(0.1, theme.mercuryGray)};
box-shadow: 0 0 1px 1px ${({ theme }) => darken(0.1, theme.mercuryGray)};
}
}
......
This diff is collapsed.
......@@ -5,7 +5,7 @@ import { useWeb3Context, Connectors } from 'web3-react'
import { darken, transparentize } from 'polished'
import Jazzicon from 'jazzicon'
import { ethers } from 'ethers'
import { Activity, ArrowRight } from 'react-feather'
import { Activity } from 'react-feather'
import { shortenAddress } from '../../utils'
import { useENSName } from '../../hooks'
......@@ -91,13 +91,6 @@ const NetworkIcon = styled(Activity)`
height: 16px;
`
const ArrowIcon = styled(ArrowRight)`
margin-left: 0.25rem;
margin-right: 0.5rem;
width: 16px;
height: 16px;
`
const SpinnerWrapper = styled(Spinner)`
margin: 0 0.25rem 0 0.25rem;
`
......@@ -251,7 +244,6 @@ export default function Web3Status() {
return (
<Web3StatusConnect onClick={onClick}>
<Text>{t('Connect')}</Text>
<ArrowIcon />
</Web3StatusConnect>
)
} else {
......
......@@ -2,10 +2,8 @@ import React, { createContext, useContext, useReducer, useMemo, useCallback, use
import { useWeb3Context } from 'web3-react'
import { safeAccess } from '../utils'
const SHOW_BETA_MESSAGE = 'SHOW_BETA_MESSAGE'
const BLOCK_NUMBERS = 'BLOCK_NUMBERS'
const DISMISS_BETA_MESSAGE = 'DISMISS_BETA_MESSAGE'
const UPDATE_BLOCK_NUMBER = 'UPDATE_BLOCK_NUMBER'
const ApplicationContext = createContext()
......@@ -16,12 +14,6 @@ function useApplicationContext() {
function reducer(state, { type, payload }) {
switch (type) {
case DISMISS_BETA_MESSAGE: {
return {
...state,
[SHOW_BETA_MESSAGE]: false
}
}
case UPDATE_BLOCK_NUMBER: {
const { networkId, blockNumber } = payload
return {
......@@ -40,25 +32,15 @@ function reducer(state, { type, payload }) {
export default function Provider({ children }) {
const [state, dispatch] = useReducer(reducer, {
[SHOW_BETA_MESSAGE]: true,
[BLOCK_NUMBERS]: {}
})
const dismissBetaMessage = useCallback(() => {
dispatch({ type: DISMISS_BETA_MESSAGE })
}, [])
const updateBlockNumber = useCallback((networkId, blockNumber) => {
dispatch({ type: UPDATE_BLOCK_NUMBER, payload: { networkId, blockNumber } })
}, [])
return (
<ApplicationContext.Provider
value={useMemo(() => [state, { dismissBetaMessage, updateBlockNumber }], [
state,
dismissBetaMessage,
updateBlockNumber
])}
>
<ApplicationContext.Provider value={useMemo(() => [state, { updateBlockNumber }], [state, updateBlockNumber])}>
{children}
</ApplicationContext.Provider>
)
......@@ -101,12 +83,6 @@ export function Updater() {
return null
}
export function useBetaMessageManager() {
const [state, { dismissBetaMessage }] = useApplicationContext()
return [safeAccess(state, [SHOW_BETA_MESSAGE]), dismissBetaMessage]
}
export function useBlockNumber() {
const { networkId } = useWeb3Context()
......
import React, { createContext, useContext, useReducer, useMemo, useCallback, useEffect } from 'react'
const UNISWAP = 'UNISWAP'
const VERSION = 'VERSION'
const CURRENT_VERSION = 0
const LAST_SAVED = 'LAST_SAVED'
const BETA_MESSAGE_DISMISSED = 'BETA_MESSAGE_DISMISSED'
const UPDATABLE_KEYS = [BETA_MESSAGE_DISMISSED]
const UPDATE_KEY = 'UPDATE_KEY'
const LocalStorageContext = createContext()
function useLocalStorageContext() {
return useContext(LocalStorageContext)
}
function reducer(state, { type, payload }) {
switch (type) {
case UPDATE_KEY: {
const { key, value } = payload
if (!UPDATABLE_KEYS.some(k => k === key)) {
throw Error(`Unexpected key in LocalStorageContext reducer: '${key}'.`)
} else {
return {
...state,
[key]: value
}
}
}
default: {
throw Error(`Unexpected action type in LocalStorageContext reducer: '${type}'.`)
}
}
}
function init() {
const defaultLocalStorage = {
[VERSION]: CURRENT_VERSION,
[BETA_MESSAGE_DISMISSED]: false
}
try {
const parsed = JSON.parse(window.localStorage.getItem(UNISWAP))
if (parsed[VERSION] !== CURRENT_VERSION) {
// this is where we could run migration logic
return defaultLocalStorage
} else {
return parsed
}
} catch {
return defaultLocalStorage
}
}
export default function Provider({ children }) {
const [state, dispatch] = useReducer(reducer, undefined, init)
const updateKey = useCallback((key, value) => {
dispatch({ type: UPDATE_KEY, payload: { key, value } })
}, [])
return (
<LocalStorageContext.Provider value={useMemo(() => [state, { updateKey }], [state, updateKey])}>
{children}
</LocalStorageContext.Provider>
)
}
export function Updater() {
const [state] = useLocalStorageContext()
useEffect(() => {
window.localStorage.setItem(UNISWAP, JSON.stringify({ ...state, [LAST_SAVED]: Math.floor(Date.now() / 1000) }))
})
return null
}
export function useBetaMessageManager() {
const [state, { updateKey }] = useLocalStorageContext()
const dismissBetaMessage = useCallback(() => {
updateKey(BETA_MESSAGE_DISMISSED, true)
}, [updateKey])
return [!state[BETA_MESSAGE_DISMISSED], dismissBetaMessage]
}
......@@ -89,6 +89,14 @@ const INITIAL_TOKENS_CONTEXT = {
[DECIMALS]: 9,
[EXCHANGE_ADDRESS]: '0xb92dE8B30584392Af27726D5ce04Ef3c4e5c9924'
},
'0xc719d010B63E5bbF2C0551872CD5316ED26AcD83': {
[NAME]: 'Decentralized Insurance Protocol',
[SYMBOL]: 'DIP',
[DECIMALS]: 18,
[EXCHANGE_ADDRESS]: '0x61792F290e5100FBBcBb2309F03A1Bab869fb850'
},
'0x4946Fcea7C692606e8908002e55A582af44AC121': {
[NAME]: 'FOAM Token',
[SYMBOL]: 'FOAM',
......@@ -191,6 +199,12 @@ const INITIAL_TOKENS_CONTEXT = {
[DECIMALS]: 18,
[EXCHANGE_ADDRESS]: '0x2C4Bd064b998838076fa341A83d007FC2FA50957'
},
'0xec67005c4E498Ec7f55E092bd1d35cbC47C91892': {
[NAME]: 'Melon Token',
[SYMBOL]: 'MLN',
[DECIMALS]: 18,
[EXCHANGE_ADDRESS]: '0xA931F4eB165AC307fD7431b5EC6eADde53E14b0C'
},
'0x957c30aB0426e0C93CD8241E2c60392d08c6aC8e': {
[NAME]: 'Modum Token',
[SYMBOL]: 'MOD',
......
......@@ -4,6 +4,7 @@ import ReactGA from 'react-ga'
import Web3Provider, { Connectors } from 'web3-react'
import ThemeProvider, { GlobalStyle } from './theme'
import LocalStorageContextProvider, { Updater as LocalStorageContextUpdater } from './contexts/LocalStorage'
import ApplicationContextProvider, { Updater as ApplicationContextUpdater } from './contexts/Application'
import TransactionContextProvider, { Updater as TransactionContextUpdater } from './contexts/Transactions'
import TokensContextProvider from './contexts/Tokens'
......@@ -29,21 +30,24 @@ const connectors = { Injected, Network }
function ContextProviders({ children }) {
return (
<ApplicationContextProvider>
<TransactionContextProvider>
<TokensContextProvider>
<BalancesContextProvider>
<AllowancesContextProvider>{children}</AllowancesContextProvider>
</BalancesContextProvider>
</TokensContextProvider>
</TransactionContextProvider>
</ApplicationContextProvider>
<LocalStorageContextProvider>
<ApplicationContextProvider>
<TransactionContextProvider>
<TokensContextProvider>
<BalancesContextProvider>
<AllowancesContextProvider>{children}</AllowancesContextProvider>
</BalancesContextProvider>
</TokensContextProvider>
</TransactionContextProvider>
</ApplicationContextProvider>
</LocalStorageContextProvider>
)
}
function Updaters() {
return (
<>
<LocalStorageContextUpdater />
<ApplicationContextUpdater />
<TransactionContextUpdater />
</>
......
......@@ -362,6 +362,7 @@ export default function AddLiquidity() {
})
const deadline = Math.ceil(Date.now() / 1000) + DEADLINE_FROM_NOW
const estimatedGasLimit = await exchangeContract.estimate.addLiquidity(
isNewExchange ? ethers.constants.Zero : liquidityTokensMin,
isNewExchange ? outputValueParsed : outputValueMax,
......@@ -371,6 +372,8 @@ export default function AddLiquidity() {
}
)
const gasLimit = calculateGasMargin(estimatedGasLimit, GAS_MARGIN)
exchangeContract
.addLiquidity(
isNewExchange ? ethers.constants.Zero : liquidityTokensMin,
......@@ -378,7 +381,7 @@ export default function AddLiquidity() {
deadline,
{
value: inputValueParsed,
gasLimit: calculateGasMargin(estimatedGasLimit, GAS_MARGIN)
gasLimit
}
)
.then(response => {
......
......@@ -64,7 +64,7 @@ const StyledNavLink = styled(NavLink).attrs({
&.${activeClassName} {
background-color: ${({ theme }) => theme.white};
border-radius: 3rem;
box-shadow: 0 0 0.5px 0.5px ${({ theme }) => theme.mercuryGray};
box-shadow: 0 0 1px 1px ${({ theme }) => theme.mercuryGray};
font-weight: 500;
color: ${({ theme }) => theme.royalBlue};
}
......
......@@ -612,7 +612,7 @@ export default function Swap({ initialCurrency }) {
isError={isError}
slippageWarning={slippageWarning && slippageWarningText}
highSlippageWarning={highSlippageWarning && slippageWarningText}
renderTransactionDetails={renderTransactionDetails}
dropDownContent={renderTransactionDetails}
/>
)
}
......@@ -760,13 +760,13 @@ export default function Swap({ initialCurrency }) {
{inverted ? (
<span>
{exchangeRate
? `1 ${outputSymbol} = ${amountFormatter(exchangeRateInverted, 18, 4, false)} ${inputSymbol}`
? `1 ${inputSymbol} = ${amountFormatter(exchangeRate, 18, 4, false)} ${outputSymbol}`
: ' - '}
</span>
) : (
<span>
{exchangeRate
? `1 ${inputSymbol} = ${amountFormatter(exchangeRate, 18, 4, false)} ${outputSymbol}`
? `1 ${outputSymbol} = ${amountFormatter(exchangeRateInverted, 18, 4, false)} ${inputSymbol}`
: ' - '}
</span>
)}
......
......@@ -7,8 +7,8 @@ import styled from 'styled-components'
import { Button } from '../../theme'
import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import NewContextualInfo from '../../components/ContextualInfoNew'
import OversizedPanel from '../../components/OversizedPanel'
import TransactionDetails from '../../components/TransactionDetails'
import ArrowDownBlue from '../../assets/images/arrow-down-blue.svg'
import ArrowDownGrey from '../../assets/images/arrow-down-grey.svg'
import { amountFormatter, calculateGasMargin } from '../../utils'
......@@ -26,8 +26,8 @@ const TOKEN_TO_ETH = 1
const TOKEN_TO_TOKEN = 2
// denominated in bips
const ALLOWED_SLIPPAGE = ethers.utils.bigNumberify(200)
const TOKEN_ALLOWED_SLIPPAGE = ethers.utils.bigNumberify(400)
const ALLOWED_SLIPPAGE_DEFAULT = 100
const TOKEN_ALLOWED_SLIPPAGE_DEFAULT = 100
// denominated in seconds
const DEADLINE_FROM_NOW = 60 * 15
......@@ -35,14 +35,6 @@ const DEADLINE_FROM_NOW = 60 * 15
// denominated in bips
const GAS_MARGIN = ethers.utils.bigNumberify(1000)
const BlueSpan = styled.span`
color: ${({ theme }) => theme.royalBlue};
`
const LastSummaryText = styled.div`
margin-top: 1rem;
`
const DownArrowBackground = styled.div`
${({ theme }) => theme.flexRowNoWrap}
justify-content: center;
......@@ -81,9 +73,9 @@ const Flex = styled.div`
}
`
function calculateSlippageBounds(value, token = false) {
function calculateSlippageBounds(value, token = false, tokenAllowedSlippage, allowedSlippage) {
if (value) {
const offset = value.mul(token ? TOKEN_ALLOWED_SLIPPAGE : ALLOWED_SLIPPAGE).div(ethers.utils.bigNumberify(10000))
const offset = value.mul(token ? tokenAllowedSlippage : allowedSlippage).div(ethers.utils.bigNumberify(10000))
const minimum = value.sub(offset)
const maximum = value.add(offset)
return {
......@@ -244,12 +236,18 @@ export default function Swap({ initialCurrency }) {
const addTransaction = useTransactionAdder()
const [rawSlippage, setRawSlippage] = useState(ALLOWED_SLIPPAGE_DEFAULT)
const [rawTokenSlippage, setRawTokenSlippage] = useState(TOKEN_ALLOWED_SLIPPAGE_DEFAULT)
let allowedSlippageBig = ethers.utils.bigNumberify(rawSlippage)
let tokenAllowedSlippageBig = ethers.utils.bigNumberify(rawTokenSlippage)
// analytics
useEffect(() => {
ReactGA.pageview(window.location.pathname + window.location.search)
}, [])
// core swap state
// core swap state-
const [swapState, dispatchSwapState] = useReducer(swapStateReducer, initialCurrency, getInitialSwapState)
const { independentValue, dependentValue, independentField, inputCurrency, outputCurrency } = swapState
......@@ -326,7 +324,9 @@ export default function Swap({ initialCurrency }) {
// calculate slippage from target rate
const { minimum: dependentValueMinumum, maximum: dependentValueMaximum } = calculateSlippageBounds(
dependentValue,
swapType === TOKEN_TO_TOKEN
swapType === TOKEN_TO_TOKEN,
tokenAllowedSlippageBig,
allowedSlippageBig
)
// validate input allowance + balance
......@@ -496,118 +496,6 @@ export default function Swap({ initialCurrency }) {
return `Balance: ${value}`
}
function renderTransactionDetails() {
ReactGA.event({
category: 'TransactionDetail',
action: 'Open'
})
const b = text => <BlueSpan>{text}</BlueSpan>
if (independentField === INPUT) {
return (
<div>
<div>
{t('youAreSelling')}{' '}
{b(
`${amountFormatter(
independentValueParsed,
independentDecimals,
Math.min(4, independentDecimals)
)} ${inputSymbol}`
)}
.
</div>
<LastSummaryText>
{t('youWillReceive')}{' '}
{b(
`${amountFormatter(
dependentValueMinumum,
dependentDecimals,
Math.min(4, dependentDecimals)
)} ${outputSymbol}`
)}{' '}
{t('orTransFail')}
</LastSummaryText>
<LastSummaryText>
{(slippageWarning || highSlippageWarning) && (
<span role="img" aria-label="warning">
⚠️
</span>
)}
{t('priceChange')} {b(`${percentSlippageFormatted}%`)}.
</LastSummaryText>
</div>
)
} else {
return (
<div>
<div>
{t('youAreBuying')}{' '}
{b(
`${amountFormatter(
independentValueParsed,
independentDecimals,
Math.min(4, independentDecimals)
)} ${outputSymbol}`
)}
.
</div>
<LastSummaryText>
{t('itWillCost')}{' '}
{b(
`${amountFormatter(
dependentValueMaximum,
dependentDecimals,
Math.min(4, dependentDecimals)
)} ${inputSymbol}`
)}{' '}
{t('orTransFail')}
</LastSummaryText>
<LastSummaryText>
{t('priceChange')} {b(`${percentSlippageFormatted}%`)}.
</LastSummaryText>
</div>
)
}
}
function renderSummary() {
let contextualInfo = ''
let isError = false
if (inputError || independentError) {
contextualInfo = inputError || independentError
isError = true
} else if (!inputCurrency || !outputCurrency) {
contextualInfo = t('selectTokenCont')
} else if (!independentValue) {
contextualInfo = t('enterValueCont')
} else if (!account) {
contextualInfo = t('noWallet')
isError = true
}
const slippageWarningText = highSlippageWarning
? t('highSlippageWarning')
: slippageWarning
? t('slippageWarning')
: ''
return (
<NewContextualInfo
openDetailsText={t('transactionDetails')}
closeDetailsText={t('hideDetails')}
contextualInfo={contextualInfo ? contextualInfo : slippageWarningText}
allowExpand={!!(inputCurrency && outputCurrency && inputValueParsed && outputValueParsed)}
isError={isError}
slippageWarning={slippageWarning && !contextualInfo}
highSlippageWarning={highSlippageWarning && !contextualInfo}
renderTransactionDetails={renderTransactionDetails}
/>
)
}
async function onSwap() {
const deadline = Math.ceil(Date.now() / 1000) + DEADLINE_FROM_NOW
......@@ -664,6 +552,8 @@ export default function Swap({ initialCurrency }) {
})
}
const [customSlippageError, setcustomSlippageError] = useState('')
return (
<>
<CurrencyInputPanel
......@@ -731,22 +621,51 @@ export default function Swap({ initialCurrency }) {
{inverted ? (
<span>
{exchangeRate
? `1 ${outputSymbol} = ${amountFormatter(exchangeRateInverted, 18, 4, false)} ${inputSymbol}`
? `1 ${inputSymbol} = ${amountFormatter(exchangeRate, 18, 4, false)} ${outputSymbol}`
: ' - '}
</span>
) : (
<span>
{exchangeRate
? `1 ${inputSymbol} = ${amountFormatter(exchangeRate, 18, 4, false)} ${outputSymbol}`
? `1 ${outputSymbol} = ${amountFormatter(exchangeRateInverted, 18, 4, false)} ${inputSymbol}`
: ' - '}
</span>
)}
</ExchangeRateWrapper>
</OversizedPanel>
{renderSummary()}
<TransactionDetails
account={account}
setRawSlippage={setRawSlippage}
setRawTokenSlippage={setRawTokenSlippage}
rawSlippage={rawSlippage}
slippageWarning={slippageWarning}
highSlippageWarning={highSlippageWarning}
inputError={inputError}
independentError={independentError}
inputCurrency={inputCurrency}
outputCurrency={outputCurrency}
independentValue={independentValue}
independentValueParsed={independentValueParsed}
independentField={independentField}
INPUT={INPUT}
inputValueParsed={inputValueParsed}
outputValueParsed={outputValueParsed}
inputSymbol={inputSymbol}
outputSymbol={outputSymbol}
dependentValueMinumum={dependentValueMinumum}
dependentValueMaximum={dependentValueMaximum}
dependentDecimals={dependentDecimals}
independentDecimals={independentDecimals}
percentSlippageFormatted={percentSlippageFormatted}
setcustomSlippageError={setcustomSlippageError}
/>
<Flex>
<Button disabled={!isValid} onClick={onSwap} warning={highSlippageWarning}>
{highSlippageWarning ? t('swapAnyway') : t('swap')}
<Button
disabled={!isValid || customSlippageError === 'invalid'}
onClick={onSwap}
warning={highSlippageWarning || customSlippageError === 'warning'}
>
{highSlippageWarning || customSlippageError === 'warning' ? t('swapAnyway') : t('swap')}
</Button>
</Flex>
</>
......
......@@ -38,6 +38,9 @@ const theme = {
chaliceGray: '#AEAEAE',
doveGray: '#737373',
mineshaftGray: '#2B2B2B',
buttonOutlineGrey: '#f2f2f2',
//blacks
charcoalBlack: '#404040',
// blues
zumthorBlue: '#EBF4FF',
malibuBlue: '#5CA2FF',
......@@ -53,6 +56,7 @@ const theme = {
// pink
uniswapPink: '#DC6BE5',
connectedGreen: '#27AE60',
// media queries
mediaWidth: mediaWidthTemplates,
// css snippets
......
This diff is collapsed.
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