Skip to content

Commit

Permalink
fix: revert detect smart contracts for every evm chains (#7356)
Browse files Browse the repository at this point in the history
This reverts commit 3e70f29.
  • Loading branch information
woodenfurniture committed Jul 10, 2024
1 parent b2c6293 commit 1a36c1f
Show file tree
Hide file tree
Showing 13 changed files with 35 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,10 @@ export const TradeInput = ({ isCompact, tradeInputRef }: TradeInputProps) => {
const receiveAddress = manualReceiveAddress ?? walletReceiveAddress

const { data: _isSmartContractSellAddress, isLoading: isSellAddressByteCodeLoading } =
useIsSmartContractAddress(userAddress, sellAsset.chainId)
useIsSmartContractAddress(userAddress)

const { data: _isSmartContractReceiveAddress, isLoading: isReceiveAddressByteCodeLoading } =
useIsSmartContractAddress(receiveAddress ?? '', buyAsset.chainId)
useIsSmartContractAddress(receiveAddress ?? '')

const disableSmartContractSwap = useMemo(() => {
// Swappers other than THORChain shouldn't be affected by this limitation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ export const Confirm: React.FC<ConfirmProps> = ({ accountId, onNext }) => {
)

const { data: _isSmartContractAddress, isLoading: isAddressByteCodeLoading } =
useIsSmartContractAddress(fromAddress ?? '', chainId)
useIsSmartContractAddress(fromAddress ?? '')

const disableSmartContractDeposit = useMemo(() => {
// This is either a smart contract address, or the bytecode is still loading - disable confirm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ export const Confirm: React.FC<ConfirmProps> = ({ accountId, onNext }) => {
)

const { data: _isSmartContractAddress, isLoading: isAddressByteCodeLoading } =
useIsSmartContractAddress(userAddress, chainId)
useIsSmartContractAddress(userAddress)

const disableSmartContractWithdraw = useMemo(() => {
// This is either a smart contract address, or the bytecode is still loading - disable confirm
Expand Down
33 changes: 16 additions & 17 deletions src/hooks/useIsSmartContractAddress/useIsSmartContractAddress.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
import type { ChainId } from '@shapeshiftoss/caip'
import { isEvmChainId } from '@shapeshiftoss/chain-adapters'
import { skipToken, useQuery } from '@tanstack/react-query'
import { useQuery } from '@tanstack/react-query'
import { useMemo } from 'react'
import { isSmartContractAddress } from 'lib/address/utils'

export const useIsSmartContractAddress = (address: string, chainId: ChainId) => {
export const useIsSmartContractAddress = (address: string) => {
// Lowercase the address to ensure proper caching
const userAddress = useMemo(() => address.toLowerCase(), [address])

const query = useQuery({
queryKey: [
'isSmartContractAddress',
{
userAddress,
chainId,
},
],
queryFn:
isEvmChainId(chainId) && Boolean(userAddress.length)
? () => isSmartContractAddress(userAddress, chainId)
: skipToken,
})
const queryParams = useMemo(() => {
return {
queryKey: [
'isSmartContractAddress',
{
userAddress,
},
],
queryFn: () => isSmartContractAddress(userAddress),
enabled: Boolean(userAddress.length),
}
}, [userAddress])

const query = useQuery(queryParams)

return query
}
10 changes: 2 additions & 8 deletions src/lib/address/utils.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import type { ChainId } from '@shapeshiftoss/caip'
import { isEvmChainId } from '@shapeshiftoss/chain-adapters'
import { isAddress } from 'viem'
import { getEthersProvider } from 'lib/ethersProviderSingleton'

export const isEthAddress = (address: string): boolean => /^0x[0-9A-Fa-f]{40}$/.test(address)

export const isSmartContractAddress = async (
address: string,
chainId: ChainId,
): Promise<boolean> => {
export const isSmartContractAddress = async (address: string): Promise<boolean> => {
if (!isAddress(address)) return false
if (!isEvmChainId(chainId)) return false
const bytecode = await getEthersProvider(chainId).getCode(address)
const bytecode = await getEthersProvider().getCode(address)
return bytecode !== '0x'
}
4 changes: 3 additions & 1 deletion src/lib/ethersProviderSingleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ export const rpcUrlByChainId = (chainId: EvmChainId): string => {
const ethersProviders: Map<ChainId, JsonRpcProvider> = new Map()
const ethersV5Providers: Map<ChainId, ethersV5.providers.StaticJsonRpcProvider> = new Map()

export const getEthersProvider = (chainId: EvmChainId): JsonRpcProvider => {
export const getEthersProvider = (
chainId: EvmChainId = KnownChainIds.EthereumMainnet,
): JsonRpcProvider => {
if (!ethersProviders.has(chainId)) {
const provider = new JsonRpcProvider(rpcUrlByChainId(chainId), undefined, {
staticNetwork: true,
Expand Down
3 changes: 1 addition & 2 deletions src/lib/fees/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { KnownChainIds } from '@shapeshiftoss/types'
import type { Block } from 'ethers'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { getEthersProvider } from 'lib/ethersProviderSingleton'
Expand All @@ -7,7 +6,7 @@ import { findClosestFoxDiscountDelayBlockNumber } from './utils'

vi.unmock('ethers')

const getBlockSpy = vi.spyOn(getEthersProvider(KnownChainIds.EthereumMainnet), 'getBlock')
const getBlockSpy = vi.spyOn(getEthersProvider(), 'getBlock')

describe('findClosestFoxDiscountDelayBlockNumber', () => {
beforeEach(() => {
Expand Down
7 changes: 3 additions & 4 deletions src/lib/fees/utils.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { KnownChainIds } from '@shapeshiftoss/types'
import { getEthersProvider } from 'lib/ethersProviderSingleton'

export const AVERAGE_BLOCK_TIME_BLOCKS = 1000

export const findClosestFoxDiscountDelayBlockNumber = async (
delayHours: number,
): Promise<number> => {
const latestBlock = await getEthersProvider(KnownChainIds.EthereumMainnet).getBlock('latest')
const latestBlock = await getEthersProvider().getBlock('latest')
if (!latestBlock) throw new Error('Could not get latest block')

// No-op - if delay is zero, we don't need to perform any logic to find the closest FOX discounts delay block number
// Since the block we're interested in is the current one
if (delayHours === 0) return latestBlock.number

const historicalBlock = await getEthersProvider(KnownChainIds.EthereumMainnet).getBlock(
const historicalBlock = await getEthersProvider().getBlock(
latestBlock.number - AVERAGE_BLOCK_TIME_BLOCKS,
)
if (!historicalBlock)
Expand All @@ -28,7 +27,7 @@ export const findClosestFoxDiscountDelayBlockNumber = async (

let blockNumber = latestBlock.number - targetBlocksToMove
while (true) {
const block = await getEthersProvider(KnownChainIds.EthereumMainnet).getBlock(blockNumber)
const block = await getEthersProvider().getBlock(blockNumber)
if (!block) throw new Error(`Could not get block ${blockNumber}`)

const timeDifference = targetTimestamp - block.timestamp
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Lending/Pool/components/Borrow/BorrowInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ export const BorrowInput = ({
}, [collateralAccountId])

const { data: _isSmartContractAddress, isLoading: isAddressByteCodeLoading } =
useIsSmartContractAddress(userAddress, borrowAsset?.chainId ?? '')
useIsSmartContractAddress(userAddress)

const disableSmartContractDeposit = useMemo(() => {
// This is either a smart contract address, or the bytecode is still loading - disable confirm
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Lending/Pool/components/Repay/RepayInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ export const RepayInput = ({
])

const { data: _isSmartContractAddress, isLoading: isAddressByteCodeLoading } =
useIsSmartContractAddress(userAddress, repaymentAsset?.chainId ?? '')
useIsSmartContractAddress(userAddress)

const disableSmartContractRepayment = useMemo(() => {
// This is either a smart contract address, or the bytecode is still loading - disable confirm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export const AddLiquidityInput: React.FC<AddLiquidityInputProps> = ({
})

const { data: isSmartContractAccountAddress, isLoading: isSmartContractAccountAddressLoading } =
useIsSmartContractAddress(poolAssetAccountAddress ?? '', poolAsset?.chainId ?? '')
useIsSmartContractAddress(poolAssetAccountAddress ?? '')

const accountIdsByAssetId = useAppSelector(selectPortfolioAccountIdsByAssetId)

Expand Down
10 changes: 2 additions & 8 deletions src/state/apis/swapper/helpers/validateTradeQuote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,8 @@ export const validateTradeQuote = async (
if (swapperName !== SwapperName.Thorchain) return false

// This is either a smart contract address, or the bytecode is still loading - disable confirm
const _isSmartContractSellAddress = await isSmartContractAddress(
sendAddress,
firstHop.sellAsset.chainId,
)
const _isSmartContractReceiveAddress = await isSmartContractAddress(
quote.receiveAddress,
firstHop.buyAsset.chainId,
)
const _isSmartContractSellAddress = await isSmartContractAddress(sendAddress)
const _isSmartContractReceiveAddress = await isSmartContractAddress(quote.receiveAddress)
// For long-tails, the *destination* address cannot be a smart contract
// https://dev.thorchain.org/aggregators/aggregator-overview.html#admonition-warning
// This doesn't apply to regular THOR swaps however, which docs have no mention of *destination* having to be an EOA
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { calculateAPRFromToken0 } from './utils'

let _blockNumber: number | null = null
const getBlockNumber = async () => {
const ethersProvider = getEthersProvider(KnownChainIds.EthereumMainnet)
const ethersProvider = getEthersProvider()
if (_blockNumber) return _blockNumber
const blockNumber = await ethersProvider.getBlockNumber()
_blockNumber = blockNumber
Expand Down

0 comments on commit 1a36c1f

Please sign in to comment.