fix(optimism): Optimism regenesis support (#2703)

* feat(optimism): optimistic kovan local regenesis changes

* use the regenesis version of the sdk

* remove the override no longer necessary

* diff rpc url

* back to kovan url

* lint error

* Optimism mainnet regenesis test (#2695)

* remove the optimism mainnet specific code and point to the mainnet regenesis rpc url

* point at the old mainnet multicall address

* bump the sdk version

* copy the list

* multicall address regenesis change

* revert the gas limit special casing for optimism

* bump the sdk version

* remove a couple other temporary edits

* unused test case

* specific version of v3-sdk
This commit is contained in:
Moody Salem 2021-11-11 15:40:12 -05:00 committed by GitHub
parent 1903a16097
commit ccad45d24e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 67 additions and 153 deletions

@ -66,7 +66,7 @@
"@uniswap/v2-sdk": "^3.0.0-alpha.2", "@uniswap/v2-sdk": "^3.0.0-alpha.2",
"@uniswap/v3-core": "1.0.0", "@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1", "@uniswap/v3-periphery": "^1.1.1",
"@uniswap/v3-sdk": "^3.4.1", "@uniswap/v3-sdk": "3.6.3",
"@web3-react/core": "^6.0.9", "@web3-react/core": "^6.0.9",
"@web3-react/fortmatic-connector": "^6.0.9", "@web3-react/fortmatic-connector": "^6.0.9",
"@web3-react/injected-connector": "^6.0.7", "@web3-react/injected-connector": "^6.0.7",

@ -8,8 +8,10 @@ type AddressMap = { [chainId: number]: string }
export const UNI_ADDRESS: AddressMap = constructSameAddressMap('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984') export const UNI_ADDRESS: AddressMap = constructSameAddressMap('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
export const MULTICALL_ADDRESS: AddressMap = { export const MULTICALL_ADDRESS: AddressMap = {
...constructSameAddressMap('0x1F98415757620B543A52E61c46B32eB19261F984', [SupportedChainId.OPTIMISTIC_KOVAN]), ...constructSameAddressMap('0x1F98415757620B543A52E61c46B32eB19261F984', [
[SupportedChainId.OPTIMISM]: '0x90f872b3d8f33f305e0250db6A2761B354f7710A', SupportedChainId.OPTIMISTIC_KOVAN,
SupportedChainId.OPTIMISM,
]),
[SupportedChainId.ARBITRUM_ONE]: '0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB', [SupportedChainId.ARBITRUM_ONE]: '0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB',
[SupportedChainId.ARBITRUM_RINKEBY]: '0xa501c031958F579dB7676fF1CE78AD305794d579', [SupportedChainId.ARBITRUM_RINKEBY]: '0xa501c031958F579dB7676fF1CE78AD305794d579',
} }

@ -87,7 +87,7 @@ export function useApproveCallback(
return tokenContract return tokenContract
.approve(spender, useExact ? amountToApprove.quotient.toString() : MaxUint256, { .approve(spender, useExact ? amountToApprove.quotient.toString() : MaxUint256, {
gasLimit: calculateGasMargin(chainId, estimatedGas), gasLimit: calculateGasMargin(estimatedGas),
}) })
.then((response: TransactionResponse) => { .then((response: TransactionResponse) => {
addTransaction(response, { type: TransactionType.APPROVAL, tokenAddress: token.address, spender }) addTransaction(response, { type: TransactionType.APPROVAL, tokenAddress: token.address, spender })

@ -11,8 +11,6 @@ import { useV3Quoter } from './useContract'
import { useActiveWeb3React } from './web3' import { useActiveWeb3React } from './web3'
const QUOTE_GAS_OVERRIDES: { [chainId: number]: number } = { const QUOTE_GAS_OVERRIDES: { [chainId: number]: number } = {
[SupportedChainId.OPTIMISM]: 6_000_000,
[SupportedChainId.OPTIMISTIC_KOVAN]: 6_000_000,
[SupportedChainId.ARBITRUM_ONE]: 25_000_000, [SupportedChainId.ARBITRUM_ONE]: 25_000_000,
[SupportedChainId.ARBITRUM_RINKEBY]: 25_000_000, [SupportedChainId.ARBITRUM_RINKEBY]: 25_000_000,
} }

@ -363,9 +363,7 @@ export function useSwapCallback(
to: address, to: address,
data: calldata, data: calldata,
// let the wallet try if we can't estimate the gas // let the wallet try if we can't estimate the gas
...('gasEstimate' in bestCallOption ...('gasEstimate' in bestCallOption ? { gasLimit: calculateGasMargin(bestCallOption.gasEstimate) } : {}),
? { gasLimit: calculateGasMargin(chainId, bestCallOption.gasEstimate) }
: {}),
...(value && !isZero(value) ? { value } : {}), ...(value && !isZero(value) ? { value } : {}),
}) })
.then((response) => { .then((response) => {

@ -34,7 +34,6 @@ import Row, { AutoRow, RowBetween, RowFixed } from '../../components/Row'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink' import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import TransactionConfirmationModal, { ConfirmationModalContent } from '../../components/TransactionConfirmationModal' import TransactionConfirmationModal, { ConfirmationModalContent } from '../../components/TransactionConfirmationModal'
import { NONFUNGIBLE_POSITION_MANAGER_ADDRESSES } from '../../constants/addresses' import { NONFUNGIBLE_POSITION_MANAGER_ADDRESSES } from '../../constants/addresses'
import { CHAIN_INFO, SupportedChainId } from '../../constants/chains'
import { ZERO_PERCENT } from '../../constants/misc' import { ZERO_PERCENT } from '../../constants/misc'
import { WETH9_EXTENDED } from '../../constants/tokens' import { WETH9_EXTENDED } from '../../constants/tokens'
import { useCurrency } from '../../hooks/Tokens' import { useCurrency } from '../../hooks/Tokens'
@ -205,60 +204,6 @@ export default function AddLiquidity({
outOfRange ? ZERO_PERCENT : DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE outOfRange ? ZERO_PERCENT : DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE
) )
// only called on optimism, atm
async function onCreate() {
if (!chainId || !library) return
if (chainId && library && position && account && deadline && baseCurrency && quoteCurrency && positionManager) {
const { calldata, value } = NonfungiblePositionManager.createCallParameters(position.pool)
const txn: { to: string; data: string; value: string } = {
to: NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId],
data: calldata,
value,
}
setAttemptingTxn(true)
library
.getSigner()
.estimateGas(txn)
.then((estimate) => {
const newTxn = {
...txn,
gasLimit: calculateGasMargin(chainId, estimate),
}
return library
.getSigner()
.sendTransaction(newTxn)
.then((response: TransactionResponse) => {
setAttemptingTxn(false)
addTransaction(response, {
type: TransactionType.CREATE_V3_POOL,
baseCurrencyId: currencyId(baseCurrency),
quoteCurrencyId: currencyId(quoteCurrency),
})
// dont set txn hash as we dont want submitted txn screen for create
ReactGA.event({
category: 'Liquidity',
action: 'Create',
label: [currencies[Field.CURRENCY_A]?.symbol, currencies[Field.CURRENCY_B]?.symbol].join('/'),
})
})
})
.catch((error) => {
console.error('Failed to send transaction', error)
setAttemptingTxn(false)
// we only care if the error is something _other_ than the user rejected the tx
if (error?.code !== 4001) {
console.error(error)
}
})
} else {
return
}
}
async function onAdd() { async function onAdd() {
if (!chainId || !library || !account) return if (!chainId || !library || !account) return
@ -322,7 +267,7 @@ export default function AddLiquidity({
.then((estimate) => { .then((estimate) => {
const newTxn = { const newTxn = {
...txn, ...txn,
gasLimit: calculateGasMargin(chainId, estimate), gasLimit: calculateGasMargin(estimate),
} }
return library return library
@ -418,22 +363,16 @@ export default function AddLiquidity({
[currencyIdA, currencyIdB, history, onLeftRangeInput, onRightRangeInput] [currencyIdA, currencyIdB, history, onLeftRangeInput, onRightRangeInput]
) )
// flag for whether pool creation must be a separate tx
const mustCreateSeparately =
noLiquidity && (chainId === SupportedChainId.OPTIMISM || chainId === SupportedChainId.OPTIMISTIC_KOVAN)
const handleDismissConfirmation = useCallback(() => { const handleDismissConfirmation = useCallback(() => {
setShowConfirm(false) setShowConfirm(false)
// if there was a tx hash, we want to clear the input // if there was a tx hash, we want to clear the input
if (txHash) { if (txHash) {
onFieldAInput('') onFieldAInput('')
// dont jump to pool page if creating // dont jump to pool page if creating
if (!mustCreateSeparately) { history.push('/pool')
history.push('/pool')
}
} }
setTxHash('') setTxHash('')
}, [history, mustCreateSeparately, onFieldAInput, txHash]) }, [history, onFieldAInput, txHash])
const addIsUnsupported = useIsSwapUnsupported(currencies?.CURRENCY_A, currencies?.CURRENCY_B) const addIsUnsupported = useIsSwapUnsupported(currencies?.CURRENCY_A, currencies?.CURRENCY_B)
@ -458,15 +397,11 @@ export default function AddLiquidity({
const showApprovalB = const showApprovalB =
!argentWalletContract && approvalB !== ApprovalState.APPROVED && !!parsedAmounts[Field.CURRENCY_B] !argentWalletContract && approvalB !== ApprovalState.APPROVED && !!parsedAmounts[Field.CURRENCY_B]
const pendingText = mustCreateSeparately const pendingText = `Supplying ${!depositADisabled ? parsedAmounts[Field.CURRENCY_A]?.toSignificant(6) : ''} ${
? `Creating ${currencies[Field.CURRENCY_A]?.symbol}/${currencies[Field.CURRENCY_B]?.symbol} ${ !depositADisabled ? currencies[Field.CURRENCY_A]?.symbol : ''
feeAmount ? feeAmount / 10000 : '' } ${!outOfRange ? 'and' : ''} ${!depositBDisabled ? parsedAmounts[Field.CURRENCY_B]?.toSignificant(6) : ''} ${
}% Pool` !depositBDisabled ? currencies[Field.CURRENCY_B]?.symbol : ''
: `Supplying ${!depositADisabled ? parsedAmounts[Field.CURRENCY_A]?.toSignificant(6) : ''} ${ }`
!depositADisabled ? currencies[Field.CURRENCY_A]?.symbol : ''
} ${!outOfRange ? 'and' : ''} ${!depositBDisabled ? parsedAmounts[Field.CURRENCY_B]?.toSignificant(6) : ''} ${
!depositBDisabled ? currencies[Field.CURRENCY_B]?.symbol : ''
}`
const Buttons = () => const Buttons = () =>
addIsUnsupported ? ( addIsUnsupported ? (
@ -519,32 +454,18 @@ export default function AddLiquidity({
)} )}
</RowBetween> </RowBetween>
)} )}
{mustCreateSeparately && (
<ButtonError onClick={onCreate} disabled={!isValid || attemptingTxn || !position}>
{attemptingTxn ? (
<Dots>
<Trans>Confirm Create</Trans>
</Dots>
) : (
<Text fontWeight={500}>{errorMessage ? errorMessage : <Trans>Create</Trans>}</Text>
)}
</ButtonError>
)}
<ButtonError <ButtonError
onClick={() => { onClick={() => {
expertMode ? onAdd() : setShowConfirm(true) expertMode ? onAdd() : setShowConfirm(true)
}} }}
disabled={ disabled={
mustCreateSeparately ||
!isValid || !isValid ||
(!argentWalletContract && approvalA !== ApprovalState.APPROVED && !depositADisabled) || (!argentWalletContract && approvalA !== ApprovalState.APPROVED && !depositADisabled) ||
(!argentWalletContract && approvalB !== ApprovalState.APPROVED && !depositBDisabled) (!argentWalletContract && approvalB !== ApprovalState.APPROVED && !depositBDisabled)
} }
error={!isValid && !!parsedAmounts[Field.CURRENCY_A] && !!parsedAmounts[Field.CURRENCY_B]} error={!isValid && !!parsedAmounts[Field.CURRENCY_A] && !!parsedAmounts[Field.CURRENCY_B]}
> >
<Text fontWeight={500}> <Text fontWeight={500}>{errorMessage ? errorMessage : <Trans>Preview</Trans>}</Text>
{mustCreateSeparately ? <Trans>Add</Trans> : errorMessage ? errorMessage : <Trans>Preview</Trans>}
</Text>
</ButtonError> </ButtonError>
</AutoColumn> </AutoColumn>
) )
@ -793,19 +714,11 @@ export default function AddLiquidity({
textAlign="left" textAlign="left"
color={theme.primaryText1} color={theme.primaryText1}
> >
{mustCreateSeparately ? ( <Trans>
<Trans> This pool must be initialized before you can add liquidity. To initialize, select a
{`This pool must be initialized on ${ starting price for the pool. Then, enter your liquidity price range and deposit
chainId && CHAIN_INFO ? CHAIN_INFO[chainId].label : '' amount. Gas fees will be higher than usual due to the initialization transaction.
} before you can add liquidity. To initialize, select a starting price for the pool. Then, enter your liquidity price range and deposit amount.`} </Trans>
</Trans>
) : (
<Trans>
This pool must be initialized before you can add liquidity. To initialize, select a
starting price for the pool. Then, enter your liquidity price range and deposit
amount. Gas fees will be higher than usual due to the initialization transaction.
</Trans>
)}
</TYPE.body> </TYPE.body>
</BlueCard> </BlueCard>
)} )}

@ -184,7 +184,7 @@ export default function AddLiquidity({
.then((estimatedGasLimit) => .then((estimatedGasLimit) =>
method(...args, { method(...args, {
...(value ? { value } : {}), ...(value ? { value } : {}),
gasLimit: calculateGasMargin(chainId, estimatedGasLimit), gasLimit: calculateGasMargin(estimatedGasLimit),
}).then((response) => { }).then((response) => {
setAttemptingTxn(false) setAttemptingTxn(false)

@ -334,7 +334,7 @@ function V2PairMigration({
.multicall(data) .multicall(data)
.then((gasEstimate) => { .then((gasEstimate) => {
return migrator return migrator
.multicall(data, { gasLimit: calculateGasMargin(chainId, gasEstimate) }) .multicall(data, { gasLimit: calculateGasMargin(gasEstimate) })
.then((response: TransactionResponse) => { .then((response: TransactionResponse) => {
ReactGA.event({ ReactGA.event({
category: 'Migrate', category: 'Migrate',

@ -14,7 +14,6 @@ import { RowBetween, RowFixed } from 'components/Row'
import { Dots } from 'components/swap/styleds' import { Dots } from 'components/swap/styleds'
import Toggle from 'components/Toggle' import Toggle from 'components/Toggle'
import TransactionConfirmationModal, { ConfirmationModalContent } from 'components/TransactionConfirmationModal' import TransactionConfirmationModal, { ConfirmationModalContent } from 'components/TransactionConfirmationModal'
import { SupportedChainId } from 'constants/chains'
import { useToken } from 'hooks/Tokens' import { useToken } from 'hooks/Tokens'
import { useV3NFTPositionManagerContract } from 'hooks/useContract' import { useV3NFTPositionManagerContract } from 'hooks/useContract'
import useIsTickAtLimit from 'hooks/useIsTickAtLimit' import useIsTickAtLimit from 'hooks/useIsTickAtLimit'
@ -443,7 +442,7 @@ export function PositionPage({
.then((estimate) => { .then((estimate) => {
const newTxn = { const newTxn = {
...txn, ...txn,
gasLimit: calculateGasMargin(chainId, estimate), gasLimit: calculateGasMargin(estimate),
} }
return library return library
@ -514,15 +513,13 @@ export function PositionPage({
) )
} }
const onOptimisticChain = chainId && [SupportedChainId.OPTIMISM, SupportedChainId.OPTIMISTIC_KOVAN].includes(chainId)
const showCollectAsWeth = Boolean( const showCollectAsWeth = Boolean(
ownsNFT && ownsNFT &&
(feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) && (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) &&
currency0 && currency0 &&
currency1 && currency1 &&
(currency0.isNative || currency1.isNative) && (currency0.isNative || currency1.isNative) &&
!collectMigrationHash && !collectMigrationHash
!onOptimisticChain
) )
return loading || poolState === PoolState.LOADING || !feeAmount ? ( return loading || poolState === PoolState.LOADING || !feeAmount ? (

@ -16,7 +16,6 @@ import { AddRemoveTabs } from 'components/NavigationTabs'
import { AutoRow, RowBetween, RowFixed } from 'components/Row' import { AutoRow, RowBetween, RowFixed } from 'components/Row'
import Slider from 'components/Slider' import Slider from 'components/Slider'
import Toggle from 'components/Toggle' import Toggle from 'components/Toggle'
import { SupportedChainId } from 'constants/chains'
import { useV3NFTPositionManagerContract } from 'hooks/useContract' import { useV3NFTPositionManagerContract } from 'hooks/useContract'
import useDebouncedChangeHandler from 'hooks/useDebouncedChangeHandler' import useDebouncedChangeHandler from 'hooks/useDebouncedChangeHandler'
import useTheme from 'hooks/useTheme' import useTheme from 'hooks/useTheme'
@ -140,7 +139,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
.then((estimate) => { .then((estimate) => {
const newTxn = { const newTxn = {
...txn, ...txn,
gasLimit: calculateGasMargin(chainId, estimate), gasLimit: calculateGasMargin(estimate),
} }
return library return library
@ -262,10 +261,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
) )
} }
const onOptimisticChain = chainId && [SupportedChainId.OPTIMISM, SupportedChainId.OPTIMISTIC_KOVAN].includes(chainId)
const showCollectAsWeth = Boolean( const showCollectAsWeth = Boolean(
!onOptimisticChain && liquidityValue0?.currency &&
liquidityValue0?.currency &&
liquidityValue1?.currency && liquidityValue1?.currency &&
(liquidityValue0.currency.isNative || (liquidityValue0.currency.isNative ||
liquidityValue1.currency.isNative || liquidityValue1.currency.isNative ||

@ -239,7 +239,7 @@ export default function RemoveLiquidity({
const safeGasEstimates: (BigNumber | undefined)[] = await Promise.all( const safeGasEstimates: (BigNumber | undefined)[] = await Promise.all(
methodNames.map((methodName) => methodNames.map((methodName) =>
router.estimateGas[methodName](...args) router.estimateGas[methodName](...args)
.then((estimateGas) => calculateGasMargin(chainId, estimateGas)) .then((estimateGas) => calculateGasMargin(estimateGas))
.catch((error) => { .catch((error) => {
console.error(`estimateGas failed`, methodName, args, error) console.error(`estimateGas failed`, methodName, args, error)
return undefined return undefined

@ -164,7 +164,7 @@ export function useClaimCallback(account: string | null | undefined): {
return distributorContract.estimateGas['claim'](...args, {}).then((estimatedGasLimit) => { return distributorContract.estimateGas['claim'](...args, {}).then((estimatedGasLimit) => {
return distributorContract return distributorContract
.claim(...args, { value: null, gasLimit: calculateGasMargin(chainId, estimatedGasLimit) }) .claim(...args, { value: null, gasLimit: calculateGasMargin(estimatedGasLimit) })
.then((response: TransactionResponse) => { .then((response: TransactionResponse) => {
addTransaction(response, { addTransaction(response, {
type: TransactionType.CLAIM, type: TransactionType.CLAIM,

@ -306,7 +306,7 @@ export function useDelegateCallback(): (delegatee: string | undefined) => undefi
if (!uniContract) throw new Error('No UNI Contract!') if (!uniContract) throw new Error('No UNI Contract!')
return uniContract.estimateGas.delegate(...args, {}).then((estimatedGasLimit) => { return uniContract.estimateGas.delegate(...args, {}).then((estimatedGasLimit) => {
return uniContract return uniContract
.delegate(...args, { value: null, gasLimit: calculateGasMargin(chainId, estimatedGasLimit) }) .delegate(...args, { value: null, gasLimit: calculateGasMargin(estimatedGasLimit) })
.then((response: TransactionResponse) => { .then((response: TransactionResponse) => {
addTransaction(response, { addTransaction(response, {
type: TransactionType.DELEGATE, type: TransactionType.DELEGATE,
@ -335,7 +335,7 @@ export function useVoteCallback(): {
const args = [proposalId, voteOption === VoteOption.Against ? 0 : voteOption === VoteOption.For ? 1 : 2] const args = [proposalId, voteOption === VoteOption.Against ? 0 : voteOption === VoteOption.For ? 1 : 2]
return latestGovernanceContract.estimateGas.castVote(...args, {}).then((estimatedGasLimit) => { return latestGovernanceContract.estimateGas.castVote(...args, {}).then((estimatedGasLimit) => {
return latestGovernanceContract return latestGovernanceContract
.castVote(...args, { value: null, gasLimit: calculateGasMargin(chainId, estimatedGasLimit) }) .castVote(...args, { value: null, gasLimit: calculateGasMargin(estimatedGasLimit) })
.then((response: TransactionResponse) => { .then((response: TransactionResponse) => {
addTransaction(response, { addTransaction(response, {
type: TransactionType.VOTE, type: TransactionType.VOTE,
@ -375,7 +375,7 @@ export function useCreateProposalCallback(): (
return latestGovernanceContract.estimateGas.propose(...args).then((estimatedGasLimit) => { return latestGovernanceContract.estimateGas.propose(...args).then((estimatedGasLimit) => {
return latestGovernanceContract return latestGovernanceContract
.propose(...args, { gasLimit: calculateGasMargin(chainId, estimatedGasLimit) }) .propose(...args, { gasLimit: calculateGasMargin(estimatedGasLimit) })
.then((response: TransactionResponse) => { .then((response: TransactionResponse) => {
addTransaction(response, { addTransaction(response, {
type: TransactionType.SUBMIT_PROPOSAL, type: TransactionType.SUBMIT_PROPOSAL,

@ -2,7 +2,6 @@ import { Interface } from '@ethersproject/abi'
import { Currency, CurrencyAmount, Ether, Token } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, Ether, Token } from '@uniswap/sdk-core'
import ERC20ABI from 'abis/erc20.json' import ERC20ABI from 'abis/erc20.json'
import { Erc20Interface } from 'abis/types/Erc20' import { Erc20Interface } from 'abis/types/Erc20'
import { SupportedChainId } from 'constants/chains'
import JSBI from 'jsbi' import JSBI from 'jsbi'
import { useMemo } from 'react' import { useMemo } from 'react'
@ -52,11 +51,6 @@ export function useETHBalances(uncheckedAddresses?: (string | undefined)[]): {
) )
} }
const TOKEN_BALANCE_GAS_OVERRIDE: { [chainId: number]: number } = {
[SupportedChainId.OPTIMISM]: 250_000,
[SupportedChainId.OPTIMISTIC_KOVAN]: 250_000,
}
/** /**
* Returns a map of token addresses to their eventually consistent token balances for a single account. * Returns a map of token addresses to their eventually consistent token balances for a single account.
*/ */
@ -69,12 +63,10 @@ export function useTokenBalancesWithLoadingIndicator(
[tokens] [tokens]
) )
const { chainId } = useActiveWeb3React()
const validatedTokenAddresses = useMemo(() => validatedTokens.map((vt) => vt.address), [validatedTokens]) const validatedTokenAddresses = useMemo(() => validatedTokens.map((vt) => vt.address), [validatedTokens])
const ERC20Interface = new Interface(ERC20ABI) as Erc20Interface const ERC20Interface = new Interface(ERC20ABI) as Erc20Interface
const balances = useMultipleContractSingleData(validatedTokenAddresses, ERC20Interface, 'balanceOf', [address], { const balances = useMultipleContractSingleData(validatedTokenAddresses, ERC20Interface, 'balanceOf', [address], {
gasRequired: (chainId && TOKEN_BALANCE_GAS_OVERRIDE[chainId]) ?? 100_000, gasRequired: 100_000,
}) })
const anyLoading: boolean = useMemo(() => balances.some((callState) => callState.loading), [balances]) const anyLoading: boolean = useMemo(() => balances.some((callState) => callState.loading), [balances])

@ -4,12 +4,7 @@ import { calculateGasMargin } from './calculateGasMargin'
describe('#calculateGasMargin', () => { describe('#calculateGasMargin', () => {
it('adds 20%', () => { it('adds 20%', () => {
expect(calculateGasMargin(1, BigNumber.from(1000)).toString()).toEqual('1200') expect(calculateGasMargin(BigNumber.from(1000)).toString()).toEqual('1200')
expect(calculateGasMargin(1, BigNumber.from(50)).toString()).toEqual('60') expect(calculateGasMargin(BigNumber.from(50)).toString()).toEqual('60')
})
it('optimism - returns exact value', () => {
expect(calculateGasMargin(69, BigNumber.from(1000)).toString()).toEqual('1000')
expect(calculateGasMargin(69, BigNumber.from(50)).toString()).toEqual('50')
}) })
}) })

@ -1,9 +1,9 @@
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { SupportedChainId } from 'constants/chains'
// add 20% (except on optimism) /**
export function calculateGasMargin(chainId: number, value: BigNumber): BigNumber { * Returns the gas value plus a margin for unexpected or variable gas costs
return chainId === SupportedChainId.OPTIMISM || chainId === SupportedChainId.OPTIMISTIC_KOVAN * @param value the gas value to pad
? value */
: value.mul(BigNumber.from(10000 + 2000)).div(BigNumber.from(10000)) export function calculateGasMargin(value: BigNumber): BigNumber {
return value.mul(120).div(100)
} }

@ -4642,6 +4642,18 @@
resolved "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0.tgz" resolved "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0.tgz"
integrity sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA== integrity sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==
"@uniswap/v3-periphery@^1.0.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.2.1.tgz#7775630bea774a2cf989ab87ce3c328ac52e0d50"
integrity sha512-45W8hT8X1j9ZcXa+y3NSVao90hMZtgtoJyDlMOg91wmUGi2idXAiGivOQYdB7+7Lq8Gc6Upv/ggFZknixZrv7g==
dependencies:
"@openzeppelin/contracts" "3.4.1-solc-0.7-2"
"@uniswap/lib" "^4.0.1-alpha"
"@uniswap/v2-core" "1.0.1"
"@uniswap/v3-core" "1.0.0"
base64-sol "1.0.1"
hardhat-watcher "^2.1.1"
"@uniswap/v3-periphery@^1.1.1": "@uniswap/v3-periphery@^1.1.1":
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.1.1.tgz#be6dfca7b29318ea0d76a7baf15d3b33c3c5e90a" resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.1.1.tgz#be6dfca7b29318ea0d76a7baf15d3b33c3c5e90a"
@ -4654,18 +4666,28 @@
base64-sol "1.0.1" base64-sol "1.0.1"
hardhat-watcher "^2.1.1" hardhat-watcher "^2.1.1"
"@uniswap/v3-sdk@^3.4.1": "@uniswap/v3-sdk@3.6.3":
version "3.4.1" version "3.6.3"
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.4.1.tgz#2cf9b5f4dd826d6600245254e7bc7d2d4a4282ee" resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.6.3.tgz#f2fca86cfde1450976581028195fc0ee4b11036d"
integrity sha512-P0zcgOgpSqEbI/2DVESm8kf8OydagMEAzZR7qqLOe4JsUyhK1A4u1dy8tYDgWUBW0WeruEXSPNGiEL0pYPy3HQ== integrity sha512-nepNTZMpM1uwLJAlQaUUEDMFrSujS1sOqyVD739zoPWsVHAUPvqVAKQN0GlgZcLXOqeCMKjO3lteaNHEXef1XA==
dependencies: dependencies:
"@ethersproject/abi" "^5.0.12" "@ethersproject/abi" "^5.0.12"
"@ethersproject/solidity" "^5.0.9" "@ethersproject/solidity" "^5.0.9"
"@uniswap/sdk-core" "^3.0.1" "@uniswap/sdk-core" "^3.0.1"
"@uniswap/v3-periphery" "^1.1.1" "@uniswap/v3-periphery" "^1.1.1"
"@uniswap/v3-staker" "1.0.0"
tiny-invariant "^1.1.0" tiny-invariant "^1.1.0"
tiny-warning "^1.0.3" tiny-warning "^1.0.3"
"@uniswap/v3-staker@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@uniswap/v3-staker/-/v3-staker-1.0.0.tgz#9a6915ec980852479dfc903f50baf822ff8fa66e"
integrity sha512-JV0Qc46Px5alvg6YWd+UIaGH9lDuYG/Js7ngxPit1SPaIP30AlVer1UYB7BRYeUVVxE+byUyIeN5jeQ7LLDjIw==
dependencies:
"@openzeppelin/contracts" "3.4.1-solc-0.7-2"
"@uniswap/v3-core" "1.0.0"
"@uniswap/v3-periphery" "^1.0.1"
"@vibrant/color@^3.2.1-alpha.1": "@vibrant/color@^3.2.1-alpha.1":
version "3.2.1-alpha.1" version "3.2.1-alpha.1"
resolved "https://registry.yarnpkg.com/@vibrant/color/-/color-3.2.1-alpha.1.tgz#1bcee4545d2276d36f9a1acb42ab3485a9b489ec" resolved "https://registry.yarnpkg.com/@vibrant/color/-/color-3.2.1-alpha.1.tgz#1bcee4545d2276d36f9a1acb42ab3485a9b489ec"