diff --git a/__mocks__/ethers.ts b/__mocks__/ethers.ts index 1f2617e84dd..248a5277331 100644 --- a/__mocks__/ethers.ts +++ b/__mocks__/ethers.ts @@ -1,72 +1,54 @@ -import { - BigNumber, - Bytes, - BytesLike, - ethers, - providers, - Signature, - Signer, - UnsignedTransaction, - utils, -} from 'ethers' +import { ethers } from 'ethers' import { vi } from 'vitest' +const Contract = vi.fn().mockImplementation(address => ({ + decimals: () => { + switch (address as string) { + case '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': + return 6 + case '0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d': + return 18 + case '0x470e8de2eBaef52014A47Cb5E6aF86884947F08c': + return 18 + case '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': + return 18 + default: + throw new Error(`no decimals mock for address: ${address}`) + } + }, + name: () => { + switch (address as string) { + case '0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d': + return 'FOX' + case '0x470e8de2eBaef52014A47Cb5E6aF86884947F08c': + return 'Uniswap V2' + case '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': + return 'Wrapped Ether' + default: + throw new Error(`no decimals mock for address: ${address}`) + } + }, + symbol: () => { + switch (address as string) { + case '0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d': + return 'FOX' + case '0x470e8de2eBaef52014A47Cb5E6aF86884947F08c': + return 'UNI-V2' + case '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': + return 'WETH' + default: + throw new Error(`no decimals mock for address: ${address}`) + } + }, +})) + +const JsonRpcProvider = vi.fn() + const ethersMock = { ...ethers, - providers: { - JsonRpcProvider: vi.fn(), - StaticJsonRpcProvider: vi.fn(), - }, - Contract: vi.fn().mockImplementation(address => ({ - decimals: () => { - switch (address as string) { - case '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': - return 6 - case '0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d': - return 18 - case '0x470e8de2eBaef52014A47Cb5E6aF86884947F08c': - return 18 - case '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': - return 18 - default: - throw new Error(`no decimals mock for address: ${address}`) - } - }, - name: () => { - switch (address as string) { - case '0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d': - return 'FOX' - case '0x470e8de2eBaef52014A47Cb5E6aF86884947F08c': - return 'Uniswap V2' - case '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': - return 'Wrapped Ether' - default: - throw new Error(`no decimals mock for address: ${address}`) - } - }, - symbol: () => { - switch (address as string) { - case '0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d': - return 'FOX' - case '0x470e8de2eBaef52014A47Cb5E6aF86884947F08c': - return 'UNI-V2' - case '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': - return 'WETH' - default: - throw new Error(`no decimals mock for address: ${address}`) - } - }, - })), + JsonRpcProvider, + Contract, } -export { - ethersMock as ethers, - BigNumber, - Bytes, - BytesLike, - Signature, - Signer, - UnsignedTransaction, - providers, - utils, -} +export * from 'ethers' +export { ethersMock as ethers, Contract, JsonRpcProvider } diff --git a/package.json b/package.json index 4df58afa68d..fc4190a78a3 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,8 @@ "envalid": "^7.3.1", "eslint-plugin-react-memo": "^0.0.3", "eth-url-parser": "^1.0.4", - "ethers": "^5.7.2", + "ethers": "^6.11.1", + "ethers5": "npm:ethers@5.7.2", "framer-motion": "^11.0.3", "friendly-challenge": "0.9.2", "grapheme-splitter": "^1.0.4", diff --git a/packages/caip/src/adapters/yearn/utils.ts b/packages/caip/src/adapters/yearn/utils.ts index 65dd160c843..4de04ea8830 100644 --- a/packages/caip/src/adapters/yearn/utils.ts +++ b/packages/caip/src/adapters/yearn/utils.ts @@ -1,6 +1,6 @@ import type { Token, Vault } from '@yfi/sdk' import { Yearn } from '@yfi/sdk' -import { ethers } from 'ethers' +import { ethers } from 'ethers5' import fs from 'fs' import toLower from 'lodash/toLower' import uniqBy from 'lodash/uniqBy' diff --git a/packages/chain-adapters/src/evm/EvmBaseAdapter.ts b/packages/chain-adapters/src/evm/EvmBaseAdapter.ts index a554c34613e..f6db31a8d30 100644 --- a/packages/chain-adapters/src/evm/EvmBaseAdapter.ts +++ b/packages/chain-adapters/src/evm/EvmBaseAdapter.ts @@ -21,7 +21,7 @@ import type { BIP44Params } from '@shapeshiftoss/types' import { KnownChainIds } from '@shapeshiftoss/types' import type * as unchained from '@shapeshiftoss/unchained-client' import BigNumber from 'bignumber.js' -import { utils } from 'ethers' +import { isAddress, toHex } from 'viem' import { numberToHex } from 'web3-utils' import type { ChainAdapter as IChainAdapter } from '../api' @@ -247,7 +247,7 @@ export abstract class EvmBaseAdapter implements IChainAdap }[this.chainId] await wallet.ethSwitchChain({ - chainId: utils.hexValue(adapterChainReference), + chainId: toHex(adapterChainReference), chainName: this.getDisplayName(), nativeCurrency: { name: targetNetwork.name, @@ -538,7 +538,7 @@ export abstract class EvmBaseAdapter implements IChainAdap // eslint-disable-next-line require-await async validateAddress(address: string): Promise { - const isValidAddress = utils.isAddress(address) + const isValidAddress = isAddress(address) if (isValidAddress) return { valid: true, result: ValidAddressResultType.Valid } return { valid: false, result: ValidAddressResultType.Invalid } } diff --git a/packages/chain-adapters/src/evm/gnosis/GnosisChainAdapter.test.ts b/packages/chain-adapters/src/evm/gnosis/GnosisChainAdapter.test.ts index 8452523f3bb..d494ef8879e 100644 --- a/packages/chain-adapters/src/evm/gnosis/GnosisChainAdapter.test.ts +++ b/packages/chain-adapters/src/evm/gnosis/GnosisChainAdapter.test.ts @@ -4,7 +4,6 @@ * Test GnosisChainAdapter * @group unit */ -import { AddressZero } from '@ethersproject/constants' import { ASSET_REFERENCE, fromChainId, gnosisAssetId, gnosisChainId } from '@shapeshiftoss/caip' import type { ETHSignMessage, ETHSignTx, ETHWallet } from '@shapeshiftoss/hdwallet-core' import type { NativeAdapterArgs } from '@shapeshiftoss/hdwallet-native' @@ -13,6 +12,7 @@ import type { BIP44Params } from '@shapeshiftoss/types' import { KnownChainIds } from '@shapeshiftoss/types' import type * as unchained from '@shapeshiftoss/unchained-client' import { merge } from 'lodash' +import { zeroAddress } from 'viem' import { describe, expect, it, vi } from 'vitest' import { numberToHex } from 'web3-utils' @@ -134,7 +134,7 @@ describe('GnosisChainAdapter', () => { to: '0x642F4Bda144C63f6DC47EE0fDfbac0a193e2eDb7', value: '123', chainSpecific: { - from: AddressZero, + from: zeroAddress, data: '0x', }, } @@ -460,7 +460,7 @@ describe('GnosisChainAdapter', () => { const adapter = new gnosis.ChainAdapter(args) const wallet = await getWallet() - wallet.ethGetAddress = async () => await Promise.resolve(AddressZero) + wallet.ethGetAddress = async () => await Promise.resolve(zeroAddress) const tx = { wallet, @@ -563,7 +563,7 @@ describe('GnosisChainAdapter', () => { const tx = { wallet: await getWallet(), accountNumber, - to: AddressZero, + to: zeroAddress, value, chainSpecific: makeChainSpecific({ contractAddress }), } as unknown as BuildSendTxInput diff --git a/packages/chain-adapters/src/utils/index.ts b/packages/chain-adapters/src/utils/index.ts index bf124950f89..203af283297 100644 --- a/packages/chain-adapters/src/utils/index.ts +++ b/packages/chain-adapters/src/utils/index.ts @@ -1,6 +1,5 @@ import type { AssetNamespace, ChainId } from '@shapeshiftoss/caip' import { CHAIN_NAMESPACE, CHAIN_REFERENCE, fromChainId } from '@shapeshiftoss/caip' -import { BigNumber } from 'ethers' export * from './bignumber' export * from './bip44' @@ -70,5 +69,3 @@ export const chainIdToChainLabel = (chainId: ChainId): string => { throw new Error(`chainNamespace ${chainNamespace} not supported.`) } } - -export const convertNumberToHex = (value: string): string => BigNumber.from(value).toHexString() diff --git a/packages/unchained-client/src/evm/bnbsmartchain/parser/abi/bep20.ts b/packages/unchained-client/src/evm/bnbsmartchain/parser/abi/bep20.ts index ffc32c1a580..9e93f6130e5 100644 --- a/packages/unchained-client/src/evm/bnbsmartchain/parser/abi/bep20.ts +++ b/packages/unchained-client/src/evm/bnbsmartchain/parser/abi/bep20.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -const bep20: JsonFragment[] = [ +const bep20: InterfaceAbi = [ { anonymous: false, inputs: [ diff --git a/packages/unchained-client/src/evm/bnbsmartchain/parser/bep20.ts b/packages/unchained-client/src/evm/bnbsmartchain/parser/bep20.ts index 75dd0009853..0b6ca29a340 100644 --- a/packages/unchained-client/src/evm/bnbsmartchain/parser/bep20.ts +++ b/packages/unchained-client/src/evm/bnbsmartchain/parser/bep20.ts @@ -1,6 +1,5 @@ import type { ChainId } from '@shapeshiftoss/caip' import { toAssetId } from '@shapeshiftoss/caip' -import type { BigNumber } from 'ethers' import { ethers } from 'ethers' import type { BaseTxMetadata } from '../../../types' @@ -16,17 +15,17 @@ export interface TxMetadata extends BaseTxMetadata { interface ParserArgs { chainId: ChainId - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider } export class Parser implements SubParser { - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider readonly chainId: ChainId - readonly abiInterface = new ethers.utils.Interface(bep20) + readonly abiInterface = new ethers.Interface(bep20) readonly supportedFunctions = { - approveSigHash: this.abiInterface.getSighash('approve'), + approveSigHash: this.abiInterface.getFunction('approve')!.selector, } constructor(args: ParserArgs) { @@ -58,9 +57,9 @@ export class Parser implements SubParser { switch (txSigHash) { case this.supportedFunctions.approveSigHash: { - const amount = decoded.args.amount as BigNumber + const amount = decoded.args.amount as BigInt const value = amount.toString() - if (amount.isZero()) { + if (amount === 0n) { return await Promise.resolve({ data: { ...data, method: 'revoke', value } }) } return await Promise.resolve({ data: { ...data, value } }) diff --git a/packages/unchained-client/src/evm/ethereum/parser/abi/foxyStaking.ts b/packages/unchained-client/src/evm/ethereum/parser/abi/foxyStaking.ts index 8d972140a3d..0dbb9d480ce 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/abi/foxyStaking.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/abi/foxyStaking.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -export const FOXY_STAKING_ABI: JsonFragment[] = [ +export const FOXY_STAKING_ABI: InterfaceAbi = [ { inputs: [ { diff --git a/packages/unchained-client/src/evm/ethereum/parser/abi/shapeShiftRouter.ts b/packages/unchained-client/src/evm/ethereum/parser/abi/shapeShiftRouter.ts index 6ca4c0c2cf2..bc07f0b3c6f 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/abi/shapeShiftRouter.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/abi/shapeShiftRouter.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -export const SHAPESHIFT_ROUTER_ABI: JsonFragment[] = [ +export const SHAPESHIFT_ROUTER_ABI: InterfaceAbi = [ { inputs: [ { diff --git a/packages/unchained-client/src/evm/ethereum/parser/abi/thorAvalanche.ts b/packages/unchained-client/src/evm/ethereum/parser/abi/thorAvalanche.ts index 9a8ae0c8db6..e02b59678ab 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/abi/thorAvalanche.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/abi/thorAvalanche.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -export const THOR_AVALANCHE_ABI: JsonFragment[] = [ +export const THOR_AVALANCHE_ABI: InterfaceAbi = [ { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, { anonymous: false, diff --git a/packages/unchained-client/src/evm/ethereum/parser/abi/thorEthereum.ts b/packages/unchained-client/src/evm/ethereum/parser/abi/thorEthereum.ts index 8ddff380ae8..53845c851bb 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/abi/thorEthereum.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/abi/thorEthereum.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -export const THOR_ETHEREUM_ABI: JsonFragment[] = [ +export const THOR_ETHEREUM_ABI: InterfaceAbi = [ { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, { anonymous: false, diff --git a/packages/unchained-client/src/evm/ethereum/parser/abi/uniV2.ts b/packages/unchained-client/src/evm/ethereum/parser/abi/uniV2.ts index 00956eb3565..d9f917623d1 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/abi/uniV2.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/abi/uniV2.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -export const UNIV2_ABI: JsonFragment[] = [ +export const UNIV2_ABI: InterfaceAbi = [ { inputs: [ { internalType: 'address', name: '_factory', type: 'address' }, diff --git a/packages/unchained-client/src/evm/ethereum/parser/abi/uniV2StakingRewards.ts b/packages/unchained-client/src/evm/ethereum/parser/abi/uniV2StakingRewards.ts index bddf6646d70..0cbce381741 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/abi/uniV2StakingRewards.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/abi/uniV2StakingRewards.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -export const UNIV2_STAKING_REWARDS_ABI: JsonFragment[] = [ +export const UNIV2_STAKING_REWARDS_ABI: InterfaceAbi = [ { inputs: [ { diff --git a/packages/unchained-client/src/evm/ethereum/parser/abi/weth.ts b/packages/unchained-client/src/evm/ethereum/parser/abi/weth.ts index 99458c96386..7cfecdecd57 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/abi/weth.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/abi/weth.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -export const WETH_ABI: JsonFragment[] = [ +export const WETH_ABI: InterfaceAbi = [ { constant: true, inputs: [], diff --git a/packages/unchained-client/src/evm/ethereum/parser/abi/yearnVault.ts b/packages/unchained-client/src/evm/ethereum/parser/abi/yearnVault.ts index 11b333f2b9b..e2cda5b22ee 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/abi/yearnVault.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/abi/yearnVault.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -export const YEARN_VAULT_ABI: JsonFragment[] = [ +export const YEARN_VAULT_ABI: InterfaceAbi = [ { name: 'Transfer', inputs: [ diff --git a/packages/unchained-client/src/evm/ethereum/parser/foxy.ts b/packages/unchained-client/src/evm/ethereum/parser/foxy.ts index 8e1bb38087f..b902685fbe0 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/foxy.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/foxy.ts @@ -12,13 +12,13 @@ export interface TxMetadata extends BaseTxMetadata { } export class Parser implements SubParser { - readonly abiInterface = new ethers.utils.Interface(FOXY_STAKING_ABI) + readonly abiInterface = new ethers.Interface(FOXY_STAKING_ABI) readonly supportedFunctions = { - stakeSigHash: this.abiInterface.getSighash('stake(uint256,address)'), - unstakeSigHash: this.abiInterface.getSighash('unstake'), - instantUnstakeSigHash: this.abiInterface.getSighash('instantUnstake'), - claimWithdrawSigHash: this.abiInterface.getSighash('claimWithdraw'), + stakeSigHash: this.abiInterface.getFunction('stake(uint256,address)')!.selector, + unstakeSigHash: this.abiInterface.getFunction('unstake')!.selector, + instantUnstakeSigHash: this.abiInterface.getFunction('instantUnstake')!.selector, + claimWithdrawSigHash: this.abiInterface.getFunction('claimWithdraw')!.selector, } async parse(tx: Tx): Promise { diff --git a/packages/unchained-client/src/evm/ethereum/parser/uniV2.ts b/packages/unchained-client/src/evm/ethereum/parser/uniV2.ts index 2ced225eb75..b244e39fd1f 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/uniV2.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/uniV2.ts @@ -1,6 +1,7 @@ import type { ChainId } from '@shapeshiftoss/caip' import { fromChainId, toAssetId } from '@shapeshiftoss/caip' -import { ethers } from 'ethers' +import type { JsonRpcProvider } from 'ethers' +import { Contract, getAddress, getCreate2Address, Interface, solidityPackedKeccak256 } from 'ethers' import type { Tx } from '../../../generated/ethereum' import type { BaseTxMetadata } from '../../../types' @@ -23,24 +24,24 @@ export interface TxMetadata extends BaseTxMetadata { export interface ParserArgs { chainId: ChainId - provider: ethers.providers.StaticJsonRpcProvider + provider: JsonRpcProvider } export class Parser implements SubParser { - provider: ethers.providers.StaticJsonRpcProvider + provider: JsonRpcProvider readonly chainId: ChainId readonly wethContract: string - readonly abiInterface = new ethers.utils.Interface(UNIV2_ABI) - readonly stakingRewardsInterface = new ethers.utils.Interface(UNIV2_STAKING_REWARDS_ABI) + readonly abiInterface = new Interface(UNIV2_ABI) + readonly stakingRewardsInterface = new Interface(UNIV2_STAKING_REWARDS_ABI) readonly supportedFunctions = { - addLiquidityEthSigHash: this.abiInterface.getSighash('addLiquidityETH'), - removeLiquidityEthSigHash: this.abiInterface.getSighash('removeLiquidityETH'), + addLiquidityEthSigHash: this.abiInterface.getFunction('addLiquidityETH')!.selector, + removeLiquidityEthSigHash: this.abiInterface.getFunction('removeLiquidityETH')!.selector, } readonly supportedStakingRewardsFunctions = { - stakeSigHash: this.stakingRewardsInterface.getSighash('stake'), - exitSigHash: this.stakingRewardsInterface.getSighash('exit'), + stakeSigHash: this.stakingRewardsInterface.getFunction('stake')!.selector, + exitSigHash: this.stakingRewardsInterface.getFunction('exit')!.selector, } constructor(args: ParserArgs) { @@ -81,13 +82,13 @@ export class Parser implements SubParser { }, } - const tokenAddress = ethers.utils.getAddress(decoded.args.token.toLowerCase()) + const tokenAddress = getAddress(decoded.args.token.toLowerCase()) const lpTokenAddress = Parser.pairFor(tokenAddress, this.wethContract) const transfers = await (async () => { switch (getSigHash(tx.inputData)) { case this.supportedFunctions.addLiquidityEthSigHash: { - const contract = new ethers.Contract(tokenAddress, ERC20_ABI, this.provider) + const contract = new Contract(tokenAddress, ERC20_ABI, this.provider) const decimals = await contract.decimals() const name = await contract.name() const symbol = await contract.symbol() @@ -112,7 +113,7 @@ export class Parser implements SubParser { ] } case this.supportedFunctions.removeLiquidityEthSigHash: { - const contract = new ethers.Contract(lpTokenAddress, ERC20_ABI, this.provider) + const contract = new Contract(lpTokenAddress, ERC20_ABI, this.provider) const decimals = await contract.decimals() const name = await contract.name() const symbol = await contract.symbol() @@ -188,8 +189,8 @@ export class Parser implements SubParser { private static pairFor(tokenA: string, tokenB: string): string { const [token0, token1] = tokenA < tokenB ? [tokenA, tokenB] : [tokenB, tokenA] const factoryContract = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f' - const salt = ethers.utils.solidityKeccak256(['address', 'address'], [token0, token1]) + const salt = solidityPackedKeccak256(['address', 'address'], [token0, token1]) const initCodeHash = '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // https://github.com/Uniswap/v2-periphery/blob/dda62473e2da448bc9cb8f4514dadda4aeede5f4/contracts/libraries/UniswapV2Library.sol#L24 - return ethers.utils.getCreate2Address(factoryContract, salt, initCodeHash) + return getCreate2Address(factoryContract, salt, initCodeHash) } } diff --git a/packages/unchained-client/src/evm/ethereum/parser/weth.ts b/packages/unchained-client/src/evm/ethereum/parser/weth.ts index cbb9458bf15..7294c354cbe 100644 --- a/packages/unchained-client/src/evm/ethereum/parser/weth.ts +++ b/packages/unchained-client/src/evm/ethereum/parser/weth.ts @@ -16,18 +16,18 @@ export interface TxMetadata extends BaseTxMetadata { export interface ParserArgs { chainId: ChainId - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider } export class Parser implements SubParser { - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider readonly chainId: ChainId readonly wethContract: string - readonly abiInterface = new ethers.utils.Interface(WETH_ABI) + readonly abiInterface = new ethers.Interface(WETH_ABI) readonly supportedFunctions = { - depositSigHash: this.abiInterface.getSighash('deposit'), - withdrawalSigHash: this.abiInterface.getSighash('withdraw'), + depositSigHash: this.abiInterface.getFunction('deposit')!.selector, + withdrawalSigHash: this.abiInterface.getFunction('withdraw')!.selector, } constructor(args: ParserArgs) { diff --git a/packages/unchained-client/src/evm/parser/abi/erc20.ts b/packages/unchained-client/src/evm/parser/abi/erc20.ts index ac5981b2719..95bfb666c95 100644 --- a/packages/unchained-client/src/evm/parser/abi/erc20.ts +++ b/packages/unchained-client/src/evm/parser/abi/erc20.ts @@ -1,6 +1,6 @@ -import type { JsonFragment } from '@ethersproject/abi/lib/fragments' +import type { InterfaceAbi } from 'ethers' -export const ERC20_ABI: JsonFragment[] = [ +export const ERC20_ABI: InterfaceAbi = [ { inputs: [ { internalType: 'string', name: 'name_', type: 'string' }, diff --git a/packages/unchained-client/src/evm/parser/erc20.ts b/packages/unchained-client/src/evm/parser/erc20.ts index 99f15b9885e..f0c575061ab 100644 --- a/packages/unchained-client/src/evm/parser/erc20.ts +++ b/packages/unchained-client/src/evm/parser/erc20.ts @@ -1,6 +1,5 @@ import type { ChainId } from '@shapeshiftoss/caip' import { toAssetId } from '@shapeshiftoss/caip' -import type { BigNumber } from 'ethers' import { ethers } from 'ethers' import type { BaseTxMetadata } from '../../types' @@ -16,17 +15,17 @@ export interface TxMetadata extends BaseTxMetadata { interface ParserArgs { chainId: ChainId - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider } export class Parser implements SubParser { - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider readonly chainId: ChainId - readonly abiInterface = new ethers.utils.Interface(ERC20_ABI) + readonly abiInterface = new ethers.Interface(ERC20_ABI) readonly supportedFunctions = { - approveSigHash: this.abiInterface.getSighash('approve'), + approveSigHash: this.abiInterface.getFunction('approve')!.selector, } constructor(args: ParserArgs) { @@ -58,9 +57,9 @@ export class Parser implements SubParser { switch (txSigHash) { case this.supportedFunctions.approveSigHash: { - const amount = decoded.args.amount as BigNumber + const amount = decoded.args.amount as BigInt const value = amount.toString() - if (amount.isZero()) { + if (amount === 0n) { return await Promise.resolve({ data: { ...data, method: 'revoke', value } }) } return await Promise.resolve({ data: { ...data, value: value.toString() } }) diff --git a/packages/unchained-client/src/evm/parser/index.ts b/packages/unchained-client/src/evm/parser/index.ts index ada84ef49d1..0a1d582476f 100644 --- a/packages/unchained-client/src/evm/parser/index.ts +++ b/packages/unchained-client/src/evm/parser/index.ts @@ -1,7 +1,7 @@ import type { AssetId, ChainId } from '@shapeshiftoss/caip' import { ASSET_NAMESPACE, ASSET_REFERENCE, ethChainId, toAssetId } from '@shapeshiftoss/caip' import { BigNumber } from 'bignumber.js' -import { ethers } from 'ethers' +import { getAddress, JsonRpcProvider } from 'ethers' import type { Token, TxStatus } from '../../types' import { TransferType } from '../../types' @@ -26,7 +26,7 @@ export class BaseTransactionParser { assetId: AssetId protected readonly api: Api - protected readonly provider: ethers.providers.StaticJsonRpcProvider + protected readonly provider: JsonRpcProvider private parsers: SubParser[] = [] @@ -34,7 +34,7 @@ export class BaseTransactionParser { this.chainId = args.chainId this.assetId = args.assetId this.api = args.api - this.provider = new ethers.providers.StaticJsonRpcProvider(args.rpcUrl) + this.provider = new JsonRpcProvider(args.rpcUrl, undefined, { staticNetwork: true }) } /** @@ -51,7 +51,7 @@ export class BaseTransactionParser { } async parse(tx: T, address: string): Promise { - address = ethers.utils.getAddress(address) + address = getAddress(address) // We expect only one Parser to return a result. If multiple do, we take the first and early exit. const contractParserResult = await findAsyncSequential, TxSpecific>( diff --git a/packages/unchained-client/src/evm/parser/nft.ts b/packages/unchained-client/src/evm/parser/nft.ts index 8acc5997db9..eb54c8ac47f 100644 --- a/packages/unchained-client/src/evm/parser/nft.ts +++ b/packages/unchained-client/src/evm/parser/nft.ts @@ -18,13 +18,13 @@ export interface TxMetadata extends BaseTxMetadata { interface ParserArgs { chainId: ChainId api: Api - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider } const supportedTokenTypes = ['ERC721', 'ERC1155', 'BEP721', 'BEP1155'] export class Parser implements SubParser { - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider readonly chainId: ChainId readonly api: Api diff --git a/packages/unchained-client/src/evm/parser/thorchain.ts b/packages/unchained-client/src/evm/parser/thorchain.ts index 2e0b766bd8e..f4892f107b1 100644 --- a/packages/unchained-client/src/evm/parser/thorchain.ts +++ b/packages/unchained-client/src/evm/parser/thorchain.ts @@ -34,17 +34,17 @@ interface SupportedFunctions { export class Parser implements SubParser { private readonly chainId: ChainId private readonly thorchainParser: ThorchainParser - private readonly abiInterface: ethers.utils.Interface + private readonly abiInterface: ethers.Interface private readonly supportedFunctions: SupportedFunctions constructor(args: ParserArgs) { - this.abiInterface = new ethers.utils.Interface(routerAbi) + this.abiInterface = new ethers.Interface(routerAbi) this.supportedFunctions = { - depositSigHash: this.abiInterface.getSighash('deposit'), - depositWithExpirySigHash: this.abiInterface.getSighash('depositWithExpiry'), - transferOutSigHash: this.abiInterface.getSighash('transferOut'), - transferOutAndCallSigHash: this.abiInterface.getSighash('transferOutAndCall'), - swapInSigHash: this.abiInterface.getSighash('swapIn'), + depositSigHash: this.abiInterface.getFunction('deposit')!.selector, + depositWithExpirySigHash: this.abiInterface.getFunction('depositWithExpiry')!.selector, + transferOutSigHash: this.abiInterface.getFunction('transferOut')!.selector, + transferOutAndCallSigHash: this.abiInterface.getFunction('transferOutAndCall')!.selector, + swapInSigHash: this.abiInterface.getFunction('swapIn')!.selector, } this.thorchainParser = new ThorchainParser({ midgardUrl: args.midgardUrl }) this.chainId = args.chainId diff --git a/react-app-rewired/index.ts b/react-app-rewired/index.ts index 14a4f5d8b0d..ced5538ecad 100644 --- a/react-app-rewired/index.ts +++ b/react-app-rewired/index.ts @@ -335,7 +335,8 @@ const reactAppRewireConfig = { _.merge(config, { resolve: { alias: { - 'ethers/lib/utils': 'ethers/lib/utils.js', + 'ethers/lib/utils': 'ethers5/lib/utils.js', + 'ethers/lib/utils.js': 'ethers5/lib/utils.js', }, }, }), diff --git a/scripts/generateAssetData/ethereum/yearnVaults.ts b/scripts/generateAssetData/ethereum/yearnVaults.ts index 65ebf5ea880..62df72e4d0e 100644 --- a/scripts/generateAssetData/ethereum/yearnVaults.ts +++ b/scripts/generateAssetData/ethereum/yearnVaults.ts @@ -2,7 +2,7 @@ import { ethChainId as chainId, toAssetId } from '@shapeshiftoss/caip' import type { Asset } from '@shapeshiftoss/types' import type { Token, Vault } from '@yfi/sdk' import { Yearn } from '@yfi/sdk' -import { ethers } from 'ethers' +import { ethers } from 'ethers5' import toLower from 'lodash/toLower' import { ethereum } from '../baseAssets' diff --git a/src/components/Layout/Header/NavBar/ChainMenu.tsx b/src/components/Layout/Header/NavBar/ChainMenu.tsx index 1d93965b347..d17745c9d95 100644 --- a/src/components/Layout/Header/NavBar/ChainMenu.tsx +++ b/src/components/Layout/Header/NavBar/ChainMenu.tsx @@ -17,9 +17,9 @@ import type { ChainId } from '@shapeshiftoss/caip' import { fromChainId, gnosisChainId } from '@shapeshiftoss/caip' import type { ETHWallet } from '@shapeshiftoss/hdwallet-core' import { supportsEthSwitchChain } from '@shapeshiftoss/hdwallet-core' -import { utils } from 'ethers' import { memo, useCallback, useMemo } from 'react' import { useTranslate } from 'react-polyglot' +import { toHex } from 'viem' import { AssetIcon } from 'components/AssetIcon' import { CircleIcon } from 'components/Icons/Circle' import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton' @@ -106,7 +106,7 @@ export const ChainMenu = memo((props: ChainMenuProps) => { requestedChainId === gnosisChainId ? ['https://rpc.gnosischain.com'] : [] const requestedChainRpcUrl = requestedChainChainAdapter.getRpcUrl() await (state.wallet as ETHWallet).ethSwitchChain?.({ - chainId: utils.hexValue(Number(requestedEthNetwork)), + chainId: toHex(Number(requestedEthNetwork)), chainName: requestedChainChainAdapter.getDisplayName(), nativeCurrency: { name: requestedChainFeeAsset.name, diff --git a/src/components/Layout/Header/NavBar/Notifications.tsx b/src/components/Layout/Header/NavBar/Notifications.tsx index b95fb7e4423..b4ccf4dd58f 100644 --- a/src/components/Layout/Header/NavBar/Notifications.tsx +++ b/src/components/Layout/Header/NavBar/Notifications.tsx @@ -3,9 +3,9 @@ import type { BIP32Path, ETHSignTypedData } from '@shapeshiftoss/hdwallet-core' import { supportsETH } from '@shapeshiftoss/hdwallet-core' import type { CustomTheme, ThemeMode as ThemeModeType } from '@wherever/react-notification-feed' import { getConfig } from 'config' -import { utils } from 'ethers' import { lazy, memo, Suspense, useCallback, useEffect, useMemo, useState } from 'react' import { useTranslate } from 'react-polyglot' +import { toHex } from 'viem' import { KeyManager } from 'context/WalletProvider/KeyManager' import { useFeatureFlag } from 'hooks/useFeatureFlag/useFeatureFlag' import { useWallet } from 'hooks/useWallet/useWallet' @@ -92,7 +92,7 @@ export const Notifications = memo(() => { try { const signedMsg = await wallet.ethSignMessage({ addressNList, - message: utils.hexlify(utils.toUtf8Bytes(message)), + message: toHex(message), }) return signedMsg?.signature diff --git a/src/components/TransactionHistoryRows/utils.test.ts b/src/components/TransactionHistoryRows/utils.test.ts index d4e07eccd40..f558192bb54 100644 --- a/src/components/TransactionHistoryRows/utils.test.ts +++ b/src/components/TransactionHistoryRows/utils.test.ts @@ -1,8 +1,8 @@ -import { MaxUint256 } from '@ethersproject/constants' import { ethChainId, foxAssetId } from '@shapeshiftoss/caip' import type { TxMetadata } from '@shapeshiftoss/chain-adapters' import type { Asset, MarketData } from '@shapeshiftoss/types' import { mockMarketData } from 'test/mocks/marketData' +import { maxUint256 } from 'viem' import { describe, expect, it } from 'vitest' import { makeAmountOrDefault } from './utils' @@ -69,7 +69,7 @@ describe('TransactionHistoryRow/utils', () => { it('can parse erc20 infinite (max solidity uint256) approvals', () => { const args = makeRestArgsTuple({ - value: MaxUint256.toString(), + value: maxUint256.toString(), marketData: foxMarketData, asset: foxAsset, parser: 'erc20', diff --git a/src/components/TransactionHistoryRows/utils.ts b/src/components/TransactionHistoryRows/utils.ts index 5cfccf71d68..61503cf8e45 100644 --- a/src/components/TransactionHistoryRows/utils.ts +++ b/src/components/TransactionHistoryRows/utils.ts @@ -1,7 +1,7 @@ -import { MaxUint256 } from '@ethersproject/constants' import type { TransferType, TxMetadata } from '@shapeshiftoss/chain-adapters' import type { Asset, MarketData } from '@shapeshiftoss/types' import { memoize } from 'lodash' +import { maxUint256 } from 'viem' import type { Transfer } from 'hooks/useTxDetails/useTxDetails' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { priceAtDate } from 'lib/charts' @@ -93,7 +93,7 @@ export const makeAmountOrDefault = ( (approvedAssetMarketData.maxSupply && bn(approvedAssetMarketData.maxSupply).gte(0) && bn(approvedAmount).gte(approvedAssetMarketData.maxSupply)) || - bn(value).isEqualTo(MaxUint256.toString()) + bn(value).isEqualTo(maxUint256.toString()) ) return `transactionRow.parser.${parser}.infinite` // We don't have market data for that asset thus can't know whether or not it's infinite diff --git a/src/context/WalletProvider/WalletProvider.tsx b/src/context/WalletProvider/WalletProvider.tsx index a56d76fcf94..1e2f22404c1 100644 --- a/src/context/WalletProvider/WalletProvider.tsx +++ b/src/context/WalletProvider/WalletProvider.tsx @@ -8,7 +8,7 @@ import type { NativeHDWallet } from '@shapeshiftoss/hdwallet-native' import { Dummy } from '@shapeshiftoss/hdwallet-native/dist/crypto/isolation/engines' import type { EthereumProvider as EthereumProviderType } from '@walletconnect/ethereum-provider/dist/types/EthereumProvider' import { PublicWalletXpubs } from 'constants/PublicWalletXpubs' -import type { providers } from 'ethers' +import type { BrowserProvider } from 'ethers' import findIndex from 'lodash/findIndex' import omit from 'lodash/omit' import React, { useCallback, useEffect, useMemo, useReducer } from 'react' @@ -73,7 +73,7 @@ const initialDeviceState: DeviceState = { isUpdatingPin: false, isDeviceLoading: false, } -export type MetaMaskLikeProvider = providers.Web3Provider +export type MetaMaskLikeProvider = BrowserProvider // A subset of wallets which have an EIP-1193-like provider export type KeyManagerWithProvider = diff --git a/src/contracts/contractManager.ts b/src/contracts/contractManager.ts index 3730cd3191b..b59a82edb05 100644 --- a/src/contracts/contractManager.ts +++ b/src/contracts/contractManager.ts @@ -10,11 +10,10 @@ import { FarmingABI } from 'contracts/abis/farmingAbi' import { IUniswapV2Pair } from 'contracts/abis/IUniswapV2Pair' import { IUniswapV2Router02 } from 'contracts/abis/IUniswapV2Router02' import { THORChain_RouterABI } from 'contracts/abis/THORCHAIN_RouterABI' -import { ethers } from 'ethers' import memoize from 'lodash/memoize' import type { Address } from 'viem' -import { getContract } from 'viem' -import { getEthersProvider } from 'lib/ethersProviderSingleton' +import { getAddress, getContract } from 'viem' +import { getEthersV5Provider } from 'lib/ethersProviderSingleton' import { viemClientByChainId, viemEthMainnetClient } from 'lib/viem-client' import { @@ -104,7 +103,7 @@ export const getOrCreateContractByType = ({ }) definedContracts.push({ contract, - address: ethers.utils.getAddress(address), + address: getAddress(address), } as unknown as DefinedContract) return contract as KnownContractByType } @@ -112,13 +111,13 @@ export const getOrCreateContractByType = ({ export const fetchUniV2PairData = memoize(async (pairAssetId: AssetId) => { const { assetReference, chainId } = fromAssetId(pairAssetId) // Checksum - const contractAddress = ethers.utils.getAddress(assetReference) + const contractAddress = getAddress(assetReference) const pair = getOrCreateContractByType({ address: contractAddress, type: ContractType.UniV2Pair, chainId: KnownChainIds.EthereumMainnet, }) - const ethersProvider = getEthersProvider() + const ethersV5Provider = getEthersV5Provider() const token0Address = await pair.read.token0() const token1Address = await pair.read.token1() @@ -141,13 +140,13 @@ export const fetchUniV2PairData = memoize(async (pairAssetId: AssetId) => { const token0: Token = await Fetcher.fetchTokenData( Number(asset0EvmChainId), asset0Address, - ethersProvider, + ethersV5Provider, ) const token1: Token = await Fetcher.fetchTokenData( Number(asset1EvmChainId), asset1Address, - ethersProvider, + ethersV5Provider, ) - return Fetcher.fetchPairData(token0, token1, ethersProvider) + return Fetcher.fetchPairData(token0, token1, ethersV5Provider) }) diff --git a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts index 2bfb66c8dc2..d3e705fa398 100644 --- a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts +++ b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts @@ -1,11 +1,10 @@ -import { MaxUint256 } from '@ethersproject/constants' import { ethAssetId, fromAccountId, fromAssetId } from '@shapeshiftoss/caip' import { CONTRACT_INTERACTION } from '@shapeshiftoss/chain-adapters' import { supportsETH } from '@shapeshiftoss/hdwallet-core' import { ETH_FOX_POOL_CONTRACT_ADDRESS } from 'contracts/constants' import { getOrCreateContractByAddress } from 'contracts/contractManager' import { useCallback, useMemo } from 'react' -import { encodeFunctionData, getAddress } from 'viem' +import { encodeFunctionData, getAddress, maxUint256 } from 'viem' import { useFoxEth } from 'context/FoxEthProvider/FoxEthProvider' import { useWallet } from 'hooks/useWallet/useWallet' import { toBaseUnit } from 'lib/math' @@ -148,7 +147,7 @@ export const useFoxFarming = ( const data = encodeFunctionData({ abi: uniV2LPContract.abi, functionName: 'approve', - args: [contractAddress, BigInt(MaxUint256.toString())], + args: [contractAddress, maxUint256], }) return getFeesWithWallet({ @@ -232,7 +231,7 @@ export const useFoxFarming = ( const data = encodeFunctionData({ abi: uniV2LPContract.abi, functionName: 'approve', - args: [contractAddress, BigInt(MaxUint256.toString())], + args: [contractAddress, maxUint256], }) const fees = await getApproveFees() diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/FoxyDeposit.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/FoxyDeposit.tsx index 995f72aaf7a..1edaf8ff7b1 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/FoxyDeposit.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/FoxyDeposit.tsx @@ -2,7 +2,6 @@ import { Center } from '@chakra-ui/react' import type { AccountId } from '@shapeshiftoss/caip' import { toAssetId } from '@shapeshiftoss/caip' import { KnownChainIds } from '@shapeshiftoss/types' -import { ethers } from 'ethers' import { DefiModalContent } from 'features/defi/components/DefiModal/DefiModalContent' import { DefiModalHeader } from 'features/defi/components/DefiModal/DefiModalHeader' import type { @@ -14,6 +13,7 @@ import qs from 'qs' import { useCallback, useEffect, useMemo, useReducer } from 'react' import { useTranslate } from 'react-polyglot' import { useSelector } from 'react-redux' +import { getAddress } from 'viem' import type { AccountDropdownProps } from 'components/AccountDropdown/AccountDropdown' import { CircularProgress } from 'components/CircularProgress/CircularProgress' import type { DefiStepProps } from 'components/DeFi/components/Steps' @@ -93,7 +93,7 @@ export const FoxyDeposit: React.FC<{ ) return const foxyOpportunity = await foxyApi.getFoxyOpportunityByStakingAddress( - ethers.utils.getAddress(foxyStakingContractAddress), + getAddress(foxyStakingContractAddress), ) dispatch({ type: FoxyDepositActionType.SET_OPPORTUNITY, diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx index 5679d141534..42eb6cee32d 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx @@ -2,7 +2,7 @@ import { Alert, AlertIcon, Box, Stack, useToast } from '@chakra-ui/react' import type { AccountId } from '@shapeshiftoss/caip' import { fromAccountId } from '@shapeshiftoss/caip' import { supportsETH } from '@shapeshiftoss/hdwallet-core' -import type { ethers } from 'ethers' +import type { TransactionReceipt, TransactionReceiptParams } from 'ethers' import { Confirm as ReusableConfirm } from 'features/defi/components/Confirm/Confirm' import { Summary } from 'features/defi/components/Summary' import { DefiStep } from 'features/defi/contexts/DefiManagerProvider/DefiCommon' @@ -32,7 +32,7 @@ import { DepositContext } from '../DepositContext' type ConfirmProps = StepComponentProps & { accountId: AccountId | undefined } export const Confirm: React.FC = ({ onNext, accountId }) => { - const { poll } = usePoll() + const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(DepositContext) const translate = useTranslate() @@ -98,16 +98,18 @@ export const Confirm: React.FC = ({ onNext, accountId }) => { const transactionReceipt = await poll({ fn: () => foxyApi.getTxReceipt({ txid }), - validate: (result: ethers.providers.TransactionReceipt) => !isNil(result), + validate: (result: TransactionReceipt | null) => !isNil(result), interval: 15000, maxAttempts: 30, }) dispatch({ type: FoxyDepositActionType.SET_DEPOSIT, payload: { - txStatus: transactionReceipt.status ? 'success' : 'failed', - usedGasFeeCryptoBaseUnit: transactionReceipt.effectiveGasPrice - .mul(transactionReceipt.gasUsed) + txStatus: transactionReceipt?.status ? 'success' : 'failed', + usedGasFeeCryptoBaseUnit: bnOrZero( + (transactionReceipt as TransactionReceiptParams | null)?.effectiveGasPrice?.toString(), + ) + .times(transactionReceipt?.gasUsed.toString() ?? 0) .toString(), }, }) diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Overview/Claim/ClaimStatus.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Overview/Claim/ClaimStatus.tsx index 75d68b5e1de..dcfcba22bd8 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Overview/Claim/ClaimStatus.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Overview/Claim/ClaimStatus.tsx @@ -1,7 +1,7 @@ import { Box, Button, Center, Link, ModalBody, ModalFooter, Stack } from '@chakra-ui/react' import type { AccountId, AssetId, ChainId } from '@shapeshiftoss/caip' import { ASSET_REFERENCE, toAssetId } from '@shapeshiftoss/caip' -import type { ethers } from 'ethers' +import type { TransactionReceipt, TransactionReceiptParams } from 'ethers' import isNil from 'lodash/isNil' import { useCallback, useEffect, useMemo, useState } from 'react' import { FaCheck, FaTimes } from 'react-icons/fa' @@ -68,7 +68,7 @@ type ClaimStatusProps = { } export const ClaimStatus: React.FC = ({ accountId }) => { - const { poll } = usePoll() + const { poll } = usePoll() const { history: browserHistory } = useBrowserRouter() const foxyApi = getFoxyApi() const translate = useTranslate() @@ -118,20 +118,22 @@ export const ClaimStatus: React.FC = ({ accountId }) => { try { const transactionReceipt = await poll({ fn: () => foxyApi.getTxReceipt({ txid }), - validate: (result: ethers.providers.TransactionReceipt) => !isNil(result), + validate: (result: TransactionReceipt | null) => !isNil(result), interval: 15000, maxAttempts: 30, }) - if (transactionReceipt.status) { + if (transactionReceipt?.status) { refetchFoxyBalances() } setState({ ...state, - txStatus: transactionReceipt.status ? TxStatus.SUCCESS : TxStatus.FAILED, - usedGasFeeCryptoBaseUnit: transactionReceipt.effectiveGasPrice - .mul(transactionReceipt.gasUsed) + txStatus: transactionReceipt?.status ? TxStatus.SUCCESS : TxStatus.FAILED, + usedGasFeeCryptoBaseUnit: bnOrZero( + (transactionReceipt as TransactionReceiptParams | null)?.effectiveGasPrice?.toString(), + ) + .times(bnOrZero(transactionReceipt?.gasUsed.toString())) .toString(), }) } catch (error) { diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/FoxyWithdraw.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/FoxyWithdraw.tsx index bee9912c550..2906db8dac4 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/FoxyWithdraw.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/FoxyWithdraw.tsx @@ -1,7 +1,6 @@ import { Center } from '@chakra-ui/react' import type { AccountId } from '@shapeshiftoss/caip' import { KnownChainIds } from '@shapeshiftoss/types' -import { ethers } from 'ethers' import { DefiModalContent } from 'features/defi/components/DefiModal/DefiModalContent' import { DefiModalHeader } from 'features/defi/components/DefiModal/DefiModalHeader' import type { @@ -14,6 +13,7 @@ import qs from 'qs' import { useCallback, useEffect, useMemo, useReducer } from 'react' import { useTranslate } from 'react-polyglot' import { useSelector } from 'react-redux' +import { getAddress } from 'viem' import type { AccountDropdownProps } from 'components/AccountDropdown/AccountDropdown' import { CircularProgress } from 'components/CircularProgress/CircularProgress' import type { DefiStepProps } from 'components/DeFi/components/Steps' @@ -75,7 +75,7 @@ export const FoxyWithdraw: React.FC<{ ) return const foxyOpportunity = await foxyApi.getFoxyOpportunityByStakingAddress( - ethers.utils.getAddress(foxyStakingContractAddress), + getAddress(foxyStakingContractAddress), ) // Get foxy fee for instant sends const foxyFeePercentage = await foxyApi.instantUnstakeFee({ diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx index 4adee13f16e..b7910700f64 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx @@ -3,7 +3,7 @@ import type { AccountId } from '@shapeshiftoss/caip' import { fromAccountId } from '@shapeshiftoss/caip' import { supportsETH } from '@shapeshiftoss/hdwallet-core' import { WithdrawType } from '@shapeshiftoss/types' -import type { ethers } from 'ethers' +import type { TransactionReceipt, TransactionReceiptParams } from 'ethers' import { Confirm as ReusableConfirm } from 'features/defi/components/Confirm/Confirm' import { Summary } from 'features/defi/components/Summary' import { DefiStep } from 'features/defi/contexts/DefiManagerProvider/DefiCommon' @@ -34,7 +34,7 @@ export const Confirm: React.FC { - const { poll } = usePoll() + const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(WithdrawContext) const translate = useTranslate() @@ -103,16 +103,19 @@ export const Confirm: React.FC foxyApi.getTxReceipt({ txid }), - validate: (result: ethers.providers.TransactionReceipt) => !isNil(result), + validate: (result: TransactionReceipt | null) => !isNil(result), interval: 15000, maxAttempts: 30, }) dispatch({ type: FoxyWithdrawActionType.SET_WITHDRAW, payload: { - txStatus: transactionReceipt.status ? 'success' : 'failed', - usedGasFeeCryptoBaseUnit: transactionReceipt.effectiveGasPrice - .mul(transactionReceipt.gasUsed) + txStatus: transactionReceipt?.status ? 'success' : 'failed', + usedGasFeeCryptoBaseUnit: bnOrZero( + // Types are drunk here, TransactionReceipt *does* implement TransactionReceiptParams but things are not narrowed down properly for some reason + (transactionReceipt as TransactionReceiptParams | null)?.effectiveGasPrice?.toString(), + ) + .times(bnOrZero(transactionReceipt?.gasUsed?.toString())) .toString(), }, }) diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx index 2635d197611..84bd1062439 100644 --- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx +++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx @@ -18,7 +18,6 @@ import type { Asset, KnownChainIds } from '@shapeshiftoss/types' import { getConfig } from 'config' import { getOrCreateContractByType } from 'contracts/contractManager' import { ContractType } from 'contracts/types' -import { utils } from 'ethers' import { Confirm as ReusableConfirm } from 'features/defi/components/Confirm/Confirm' import { Summary } from 'features/defi/components/Summary' import type { @@ -29,7 +28,7 @@ import { DefiStep } from 'features/defi/contexts/DefiManagerProvider/DefiCommon' import { useCallback, useContext, useEffect, useMemo, useState } from 'react' import { useTranslate } from 'react-polyglot' import { useIsTradingActive } from 'react-queries/hooks/useIsTradingActive' -import { encodeFunctionData, getAddress } from 'viem' +import { encodeFunctionData, getAddress, toHex } from 'viem' import { Amount } from 'components/Amount/Amount' import { AssetIcon } from 'components/AssetIcon' import type { StepComponentProps } from 'components/DeFi/components/Steps' @@ -257,9 +256,7 @@ export const Confirm: React.FC = ({ accountId, onNext }) => { assetId, from: maybeFromUTXOAccountAddress, to: quote.inbound_address, - memo: supportedEvmChainIds.includes(chainId as KnownChainIds) - ? utils.hexlify(utils.toUtf8Bytes(memoUtf8)) - : memoUtf8, + memo: supportedEvmChainIds.includes(chainId as KnownChainIds) ? toHex(memoUtf8) : memoUtf8, sendMax: Boolean(!isUtxoChainId(chainId) && state?.deposit.sendMax), accountId, contractAddress: tokenOrUndefined(fromAssetId(asset.assetId).assetReference), @@ -476,9 +473,7 @@ export const Confirm: React.FC = ({ accountId, onNext }) => { from: maybeFromUTXOAccountAddress, sendMax: Boolean(state?.deposit.sendMax), accountId, - memo: supportedEvmChainIds.includes(chainId as KnownChainIds) - ? utils.hexlify(utils.toUtf8Bytes(memoUtf8)) - : memoUtf8, + memo: supportedEvmChainIds.includes(chainId as KnownChainIds) ? toHex(memoUtf8) : memoUtf8, amountFieldError: '', estimatedFees, feeType: FeeDataKey.Fast, diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Deposit.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Deposit.tsx index 58fc6c1339f..5bed0c4a2aa 100644 --- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Deposit.tsx +++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Deposit.tsx @@ -1,5 +1,4 @@ import { Skeleton, useToast } from '@chakra-ui/react' -import { MaxUint256 } from '@ethersproject/constants' import type { AccountId } from '@shapeshiftoss/caip' import { fromAccountId, fromAssetId, toAssetId } from '@shapeshiftoss/caip' import type { FeeDataEstimate } from '@shapeshiftoss/chain-adapters' @@ -24,7 +23,7 @@ import { useCallback, useContext, useEffect, useMemo, useState } from 'react' import { useTranslate } from 'react-polyglot' import type { EstimatedFeesQueryKey } from 'react-queries/hooks/useQuoteEstimatedFeesQuery' import { useHistory } from 'react-router-dom' -import { encodeFunctionData, getAddress } from 'viem' +import { encodeFunctionData, getAddress, maxUint256 } from 'viem' import type { AccountDropdownProps } from 'components/AccountDropdown/AccountDropdown' import { Amount } from 'components/Amount/Amount' import type { StepComponentProps } from 'components/DeFi/components/Steps' @@ -489,7 +488,7 @@ export const Deposit: React.FC = ({ const data = encodeFunctionData({ abi: contract.abi, functionName: 'approve', - args: [getAddress(saversRouterContractAddress), BigInt(MaxUint256.toString())], + args: [getAddress(saversRouterContractAddress), maxUint256], }) const adapter = assertGetEvmChainAdapter(chainId) diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx index d2f1bfcb4d2..41e584dc2ae 100644 --- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx +++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx @@ -9,7 +9,6 @@ import { Stack, useToast, } from '@chakra-ui/react' -import { AddressZero } from '@ethersproject/constants' import type { AccountId } from '@shapeshiftoss/caip' import { bchChainId, fromAccountId, fromAssetId, toAssetId } from '@shapeshiftoss/caip' import { FeeDataKey } from '@shapeshiftoss/chain-adapters' @@ -30,7 +29,7 @@ import { DefiStep } from 'features/defi/contexts/DefiManagerProvider/DefiCommon' import { useCallback, useContext, useEffect, useMemo, useState } from 'react' import { useTranslate } from 'react-polyglot' import { useIsTradingActive } from 'react-queries/hooks/useIsTradingActive' -import { encodeFunctionData, getAddress } from 'viem' +import { encodeFunctionData, getAddress, zeroAddress } from 'viem' import { Amount } from 'components/Amount/Amount' import { AssetIcon } from 'components/AssetIcon' import type { StepComponentProps } from 'components/DeFi/components/Steps' @@ -415,7 +414,7 @@ export const Confirm: React.FC = ({ accountId, onNext }) => { getAddress(quote.inbound_address), // This looks incorrect according to https://dev.thorchain.org/thorchain-dev/concepts/sending-transactions#evm-chains // But this is how THORSwap does it, and it actually works - using the actual asset address as "asset" will result in reverts - AddressZero, + zeroAddress, BigInt(amount), quote.memo, BigInt(quote.expiry), diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Withdraw.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Withdraw.tsx index e8f9c8388f8..c65fe541750 100644 --- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Withdraw.tsx +++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Withdraw.tsx @@ -1,5 +1,4 @@ import { Alert, AlertIcon, Skeleton, useToast } from '@chakra-ui/react' -import { AddressZero } from '@ethersproject/constants' import type { AccountId } from '@shapeshiftoss/caip' import { fromAccountId, fromAssetId, toAssetId } from '@shapeshiftoss/caip' import type { Asset, KnownChainIds } from '@shapeshiftoss/types' @@ -17,7 +16,7 @@ import { DefiStep } from 'features/defi/contexts/DefiManagerProvider/DefiCommon' import { useCallback, useContext, useMemo, useState } from 'react' import { FormProvider, useForm } from 'react-hook-form' import { useTranslate } from 'react-polyglot' -import { encodeFunctionData, getAddress } from 'viem' +import { encodeFunctionData, getAddress, zeroAddress } from 'viem' import { Amount } from 'components/Amount/Amount' import type { StepComponentProps } from 'components/DeFi/components/Steps' import { getChainShortName } from 'components/MultiHopTrade/components/MultiHopTradeConfirm/utils/getChainShortName' @@ -274,7 +273,7 @@ export const Withdraw: React.FC = ({ accountId, fromAddress, onNe getAddress(quote.inbound_address), // This looks incorrect according to https://dev.thorchain.org/thorchain-dev/concepts/sending-transactions#evm-chains // But this is how THORSwap does it, and it actually works - using the actual asset address as "asset" will result in reverts - AddressZero, + zeroAddress, BigInt(amountCryptoBaseUnit), quote.memo, BigInt(quote.expiry), diff --git a/src/features/defi/providers/univ2/components/UniV2Manager/Deposit/components/Approve.tsx b/src/features/defi/providers/univ2/components/UniV2Manager/Deposit/components/Approve.tsx index b9f64cb38ac..f7e9101b85e 100644 --- a/src/features/defi/providers/univ2/components/UniV2Manager/Deposit/components/Approve.tsx +++ b/src/features/defi/providers/univ2/components/UniV2Manager/Deposit/components/Approve.tsx @@ -3,7 +3,6 @@ import type { AccountId } from '@shapeshiftoss/caip' import { ethAssetId, fromAssetId, toAssetId } from '@shapeshiftoss/caip' import { supportsETH } from '@shapeshiftoss/hdwallet-core' import { UNISWAP_V2_ROUTER_02_CONTRACT_ADDRESS } from 'contracts/constants' -import { ethers } from 'ethers' import { Approve as ReusableApprove } from 'features/defi/components/Approve/Approve' import { ApprovePreFooter } from 'features/defi/components/Approve/ApprovePreFooter' import type { @@ -15,7 +14,7 @@ import { canCoverTxFees } from 'features/defi/helpers/utils' import { useUniV2LiquidityPool } from 'features/defi/providers/univ2/hooks/useUniV2LiquidityPool' import { useCallback, useContext, useEffect, useMemo, useState } from 'react' import { useTranslate } from 'react-polyglot' -import type { Address } from 'viem' +import { type Address, getAddress } from 'viem' import type { StepComponentProps } from 'components/DeFi/components/Steps' import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter' import { usePoll } from 'hooks/usePoll/usePoll' @@ -101,11 +100,11 @@ export const Approve: React.FC = ({ accountId, onNext }) => { const asset0ContractAddress = useMemo(() => { if (assetId0 === ethAssetId) return undefined - return ethers.utils.getAddress(fromAssetId(assetId0).assetReference) + return getAddress(fromAssetId(assetId0).assetReference) }, [assetId0]) const asset1ContractAddress = useMemo(() => { if (assetId1 === ethAssetId) return undefined - return ethers.utils.getAddress(fromAssetId(assetId1).assetReference) + return getAddress(fromAssetId(assetId1).assetReference) }, [assetId1]) const neededApprovals = [ isApprove0Needed && asset0ContractAddress, diff --git a/src/features/defi/providers/univ2/components/UniV2Manager/Deposit/components/Deposit.tsx b/src/features/defi/providers/univ2/components/UniV2Manager/Deposit/components/Deposit.tsx index c80c0ab8fc2..b9b0ffb36fa 100644 --- a/src/features/defi/providers/univ2/components/UniV2Manager/Deposit/components/Deposit.tsx +++ b/src/features/defi/providers/univ2/components/UniV2Manager/Deposit/components/Deposit.tsx @@ -1,7 +1,6 @@ import { useToast } from '@chakra-ui/react' import type { AccountId } from '@shapeshiftoss/caip' import { ASSET_REFERENCE, ethAssetId, fromAssetId, toAssetId } from '@shapeshiftoss/caip' -import { ethers } from 'ethers' import type { DepositValues } from 'features/defi/components/Deposit/PairDeposit' import { PairDeposit } from 'features/defi/components/Deposit/PairDeposit' import type { @@ -14,6 +13,7 @@ import qs from 'qs' import { useCallback, useContext, useMemo } from 'react' import { useTranslate } from 'react-polyglot' import { useHistory } from 'react-router-dom' +import { getAddress } from 'viem' import type { AccountDropdownProps } from 'components/AccountDropdown/AccountDropdown' import type { StepComponentProps } from 'components/DeFi/components/Steps' import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter' @@ -186,13 +186,9 @@ export const Deposit: React.FC = ({ dispatch({ type: UniV2DepositActionType.SET_LOADING, payload: false }) } else { const asset0ContractAddress = - assetId0 !== ethAssetId - ? ethers.utils.getAddress(fromAssetId(assetId0).assetReference) - : undefined + assetId0 !== ethAssetId ? getAddress(fromAssetId(assetId0).assetReference) : undefined const asset1ContractAddress = - assetId1 !== ethAssetId - ? ethers.utils.getAddress(fromAssetId(assetId1).assetReference) - : undefined + assetId1 !== ethAssetId ? getAddress(fromAssetId(assetId1).assetReference) : undefined // While the naive approach would be to think both assets approve() calls are going to result in the same gas estimation, // this is not necesssarly true. Some ERC-20s approve() might have a bit more logic, and thus require more gas. diff --git a/src/features/defi/providers/univ2/components/UniV2Manager/Withdraw/components/Approve.tsx b/src/features/defi/providers/univ2/components/UniV2Manager/Withdraw/components/Approve.tsx index ca25192744a..5d88657aab4 100644 --- a/src/features/defi/providers/univ2/components/UniV2Manager/Withdraw/components/Approve.tsx +++ b/src/features/defi/providers/univ2/components/UniV2Manager/Withdraw/components/Approve.tsx @@ -3,7 +3,6 @@ import type { AccountId } from '@shapeshiftoss/caip' import { ethAssetId, fromAssetId, toAssetId } from '@shapeshiftoss/caip' import { supportsETH } from '@shapeshiftoss/hdwallet-core' import { UNISWAP_V2_ROUTER_02_CONTRACT_ADDRESS } from 'contracts/constants' -import { ethers } from 'ethers' import { Approve as ReusableApprove } from 'features/defi/components/Approve/Approve' import { ApprovePreFooter } from 'features/defi/components/Approve/ApprovePreFooter' import type { @@ -15,6 +14,7 @@ import { canCoverTxFees } from 'features/defi/helpers/utils' import { useUniV2LiquidityPool } from 'features/defi/providers/univ2/hooks/useUniV2LiquidityPool' import { useCallback, useContext, useEffect, useMemo } from 'react' import { useTranslate } from 'react-polyglot' +import { getAddress } from 'viem' import type { StepComponentProps } from 'components/DeFi/components/Steps' import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter' import { usePoll } from 'hooks/usePoll/usePoll' @@ -112,7 +112,7 @@ export const Approve: React.FC = ({ accountId, onNext }) => { try { dispatch({ type: UniV2WithdrawActionType.SET_LOADING, payload: true }) - const lpAssetContractAddress = ethers.utils.getAddress(fromAssetId(lpAssetId).assetReference) + const lpAssetContractAddress = getAddress(fromAssetId(lpAssetId).assetReference) await approveAsset(lpAssetContractAddress) await poll({ fn: () => lpAllowance(), diff --git a/src/features/defi/providers/univ2/components/UniV2Manager/Withdraw/components/Withdraw.tsx b/src/features/defi/providers/univ2/components/UniV2Manager/Withdraw/components/Withdraw.tsx index 699ed2444f9..4090cddffa6 100644 --- a/src/features/defi/providers/univ2/components/UniV2Manager/Withdraw/components/Withdraw.tsx +++ b/src/features/defi/providers/univ2/components/UniV2Manager/Withdraw/components/Withdraw.tsx @@ -1,6 +1,5 @@ import type { AccountId } from '@shapeshiftoss/caip' import { ASSET_REFERENCE, fromAssetId, toAssetId } from '@shapeshiftoss/caip' -import { ethers } from 'ethers' import type { WithdrawValues } from 'features/defi/components/Withdraw/Withdraw' import { Field, Withdraw as ReusableWithdraw } from 'features/defi/components/Withdraw/Withdraw' import type { @@ -11,6 +10,7 @@ import { DefiStep } from 'features/defi/contexts/DefiManagerProvider/DefiCommon' import { useUniV2LiquidityPool } from 'features/defi/providers/univ2/hooks/useUniV2LiquidityPool' import { useCallback, useContext, useMemo, useState } from 'react' import { FormProvider, useForm } from 'react-hook-form' +import { getAddress } from 'viem' import type { AccountDropdownProps } from 'components/AccountDropdown/AccountDropdown' import { AssetInput } from 'components/DeFi/components/AssetInput' import type { StepComponentProps } from 'components/DeFi/components/Steps' @@ -200,9 +200,7 @@ export const Withdraw: React.FC = ({ onNext(DefiStep.Confirm) dispatch({ type: UniV2WithdrawActionType.SET_LOADING, payload: false }) } else { - const lpAssetContractAddress = ethers.utils.getAddress( - fromAssetId(lpAssetId).assetReference, - ) + const lpAssetContractAddress = getAddress(fromAssetId(lpAssetId).assetReference) const fees = await getApproveFees(lpAssetContractAddress) if (!fees) return diff --git a/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts b/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts index e029178b160..199e09314dc 100644 --- a/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts +++ b/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts @@ -1,4 +1,3 @@ -import { MaxUint256 } from '@ethersproject/constants' import type { AccountId, AssetId } from '@shapeshiftoss/caip' import { ethAssetId, ethChainId, fromAccountId, fromAssetId, toAssetId } from '@shapeshiftoss/caip' import { CONTRACT_INTERACTION } from '@shapeshiftoss/chain-adapters' @@ -9,10 +8,10 @@ import { } from 'contracts/constants' import { getOrCreateContractByAddress, getOrCreateContractByType } from 'contracts/contractManager' import { ContractType } from 'contracts/types' -import { ethers } from 'ethers' import isNumber from 'lodash/isNumber' import { useCallback, useMemo } from 'react' -import { type Address, encodeFunctionData, getAddress } from 'viem' +import type { Address } from 'viem' +import { encodeFunctionData, getAddress, maxUint256 } from 'viem' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { fromBaseUnit, toBaseUnit } from 'lib/math' @@ -81,16 +80,16 @@ export const useUniV2LiquidityPool = ({ // Checksummed addresses const asset0ContractAddress = useMemo( - () => ethers.utils.getAddress(fromAssetId(assetId0OrWeth).assetReference), + () => getAddress(fromAssetId(assetId0OrWeth).assetReference), [assetId0OrWeth], ) const asset1ContractAddress = useMemo( - () => ethers.utils.getAddress(fromAssetId(assetId1OrWeth).assetReference), + () => getAddress(fromAssetId(assetId1OrWeth).assetReference), [assetId1OrWeth], ) const lpContractAddress = useMemo( - () => ethers.utils.getAddress(fromAssetId(lpAssetId).assetReference), + () => getAddress(fromAssetId(lpAssetId).assetReference), [lpAssetId], ) @@ -244,8 +243,8 @@ export const useUniV2LiquidityPool = ({ asset1Amount, asset0Amount, }: { - asset0ContractAddress: string - asset1ContractAddress: string + asset0ContractAddress: Address + asset1ContractAddress: Address lpAmount: string asset1Amount: string asset0Amount: string @@ -256,9 +255,8 @@ export const useUniV2LiquidityPool = ({ const to = getAddress(fromAccountId(accountId).account) if ([assetId0OrWeth, assetId1OrWeth].includes(wethAssetId)) { - const otherAssetContractAddress = getAddress( - assetId0OrWeth === wethAssetId ? asset1ContractAddress : asset0ContractAddress, - ) + const otherAssetContractAddress = + assetId0OrWeth === wethAssetId ? asset1ContractAddress : asset0ContractAddress const otherAsset = assetId0OrWeth === wethAssetId ? asset1 : asset0 const ethAmount = assetId0OrWeth === wethAssetId ? asset0Amount : asset1Amount const otherAssetAmount = assetId0OrWeth === wethAssetId ? asset1Amount : asset0Amount @@ -282,8 +280,8 @@ export const useUniV2LiquidityPool = ({ abi: uniswapRouterContract.abi, functionName: 'removeLiquidity', args: [ - getAddress(asset0ContractAddress), - getAddress(asset1ContractAddress), + asset0ContractAddress, + asset1ContractAddress, BigInt(toBaseUnit(lpAmount, lpAsset.precision)), BigInt(calculateSlippageMargin(asset0Amount, asset0.precision)), BigInt(calculateSlippageMargin(asset1Amount, asset1.precision)), @@ -452,10 +450,7 @@ export const useUniV2LiquidityPool = ({ const data = encodeFunctionData({ abi: contract.abi, functionName: 'approve', - args: [ - getAddress(fromAssetId(uniswapV2Router02AssetId).assetReference), - BigInt(MaxUint256.toString()), - ], + args: [getAddress(fromAssetId(uniswapV2Router02AssetId).assetReference), maxUint256], }) return getFeesWithWallet({ @@ -606,7 +601,7 @@ export const useUniV2LiquidityPool = ({ const data = encodeFunctionData({ abi: contract.abi, functionName: 'approve', - args: [uniV2ContractAddress, BigInt(MaxUint256.toString())], + args: [uniV2ContractAddress, maxUint256], }) const fees = await getApproveFees(contractAddress) diff --git a/src/hooks/useIsSnapInstalled/useIsSnapInstalled.tsx b/src/hooks/useIsSnapInstalled/useIsSnapInstalled.tsx index c50d6fcc34b..b5728c4d95c 100644 --- a/src/hooks/useIsSnapInstalled/useIsSnapInstalled.tsx +++ b/src/hooks/useIsSnapInstalled/useIsSnapInstalled.tsx @@ -3,7 +3,7 @@ import type { HDWallet } from '@shapeshiftoss/hdwallet-core' import { MetaMaskShapeShiftMultiChainHDWallet } from '@shapeshiftoss/hdwallet-shapeshift-multichain' import { shapeShiftSnapInstalled } from '@shapeshiftoss/metamask-snaps-adapter' import { getConfig } from 'config' -import type { providers } from 'ethers' +import type { Eip1193Provider } from 'ethers' import pDebounce from 'p-debounce' import pMemoize from 'p-memoize' import { useCallback, useEffect, useState } from 'react' @@ -87,9 +87,10 @@ export const checkIsMetaMask = pMemoize( // We don't want to run this hook altogether if using any wallet other than MM if (!isMetaMaskMultichainWallet) return false - const provider = (await detectEthereumProvider()) as providers.ExternalProvider + const provider = (await detectEthereumProvider()) as Eip1193Provider // MetaMask impersonators don't support the methods we need to check for snap installation, and will throw - if (!provider.isMetaMask) return false + // `as any` because isMetaMask is gone from the providers in ethers v6 + if (!(provider as any).isMetaMask) return false return true }, @@ -104,7 +105,7 @@ export const checkIsMetaMaskImpersonator = pMemoize( // We don't want to run this hook altogether if using any wallet other than MM if (!isMetaMaskMultichainWallet) return false - const provider = (await detectEthereumProvider()) as providers.ExternalProvider + const provider = (await detectEthereumProvider()) as Eip1193Provider // Some impersonators really like to make it difficult for us to detect *actual* MetaMask // Note, checking for the truthiness of the value isn't enough - some impersonators have the key present but undefined // This is weird, but welcome to the world of web3 diff --git a/src/lib/address/yat.ts b/src/lib/address/yat.ts index 4458ed2137e..c87a154de5e 100644 --- a/src/lib/address/yat.ts +++ b/src/lib/address/yat.ts @@ -1,8 +1,8 @@ import type { AssetId } from '@shapeshiftoss/caip' import axios from 'axios' import { getConfig } from 'config' -import { ethers } from 'ethers' import GraphemeSplitter from 'grapheme-splitter' +import { getAddress } from 'viem' // validate a yat type ValidateYatArgs = { @@ -77,7 +77,7 @@ export const resolveYat: ResolveYat = async args => { })() if (!maybeAddress) return '' - return ethers.utils.getAddress(maybeAddress) + return getAddress(maybeAddress) } catch (e) { return '' } diff --git a/src/lib/ethersProviderSingleton.ts b/src/lib/ethersProviderSingleton.ts index a66c8686dd8..086d435b45b 100644 --- a/src/lib/ethersProviderSingleton.ts +++ b/src/lib/ethersProviderSingleton.ts @@ -2,7 +2,8 @@ import type { ChainId } from '@shapeshiftoss/caip' import type { EvmChainId } from '@shapeshiftoss/chain-adapters' import { KnownChainIds } from '@shapeshiftoss/types' import { getConfig } from 'config' -import { providers } from 'ethers' +import { JsonRpcProvider } from 'ethers' +import { ethers as ethersV5 } from 'ethers5' import { assertUnreachable } from './utils' @@ -29,16 +30,32 @@ export const rpcUrlByChainId = (chainId: EvmChainId): string => { } } -const ethersProviders: Map = new Map() +const ethersProviders: Map = new Map() +const ethersV5Providers: Map = new Map() export const getEthersProvider = ( chainId: EvmChainId = KnownChainIds.EthereumMainnet, -): providers.StaticJsonRpcProvider => { +): JsonRpcProvider => { if (!ethersProviders.has(chainId)) { - const provider = new providers.StaticJsonRpcProvider(rpcUrlByChainId(chainId)) + const provider = new JsonRpcProvider(rpcUrlByChainId(chainId), undefined, { + staticNetwork: true, + }) ethersProviders.set(chainId, provider) return provider } else { return ethersProviders.get(chainId)! } } + +// For backwards-compatibility for libraries still stuck in v5 +export const getEthersV5Provider = ( + chainId: EvmChainId = KnownChainIds.EthereumMainnet, +): ethersV5.providers.JsonRpcProvider => { + if (!ethersV5Providers.has(chainId)) { + const provider = new ethersV5.providers.StaticJsonRpcProvider(rpcUrlByChainId(chainId)) + ethersV5Providers.set(chainId, provider) + return provider + } else { + return ethersV5Providers.get(chainId)! + } +} diff --git a/src/lib/investor/investor-foxy/abi/erc20-abi.ts b/src/lib/investor/investor-foxy/abi/erc20-abi.ts index ae7e19c78ef..33b361e15e0 100644 --- a/src/lib/investor/investor-foxy/abi/erc20-abi.ts +++ b/src/lib/investor/investor-foxy/abi/erc20-abi.ts @@ -1,6 +1,6 @@ -import type { ContractInterface } from 'ethers' +import type { InterfaceAbi } from 'ethers' -export const erc20Abi: ContractInterface = [ +export const erc20Abi: InterfaceAbi = [ { constant: true, inputs: [], diff --git a/src/lib/investor/investor-foxy/abi/foxy-abi.ts b/src/lib/investor/investor-foxy/abi/foxy-abi.ts index 99522a88a09..35c59c92f97 100644 --- a/src/lib/investor/investor-foxy/abi/foxy-abi.ts +++ b/src/lib/investor/investor-foxy/abi/foxy-abi.ts @@ -1,6 +1,6 @@ -import type { ContractInterface } from 'ethers' +import type { InterfaceAbi } from 'ethers' -export const foxyAbi: ContractInterface = [ +export const foxyAbi: InterfaceAbi = [ { inputs: [], stateMutability: 'nonpayable', diff --git a/src/lib/investor/investor-foxy/abi/foxy-staking-abi.ts b/src/lib/investor/investor-foxy/abi/foxy-staking-abi.ts index 0d62f0aae71..659c34beb4b 100644 --- a/src/lib/investor/investor-foxy/abi/foxy-staking-abi.ts +++ b/src/lib/investor/investor-foxy/abi/foxy-staking-abi.ts @@ -1,6 +1,6 @@ -import type { ContractInterface } from 'ethers' +import type { InterfaceAbi } from 'ethers' -export const foxyStakingAbi: ContractInterface = [ +export const foxyStakingAbi: InterfaceAbi = [ { inputs: [ { diff --git a/src/lib/investor/investor-foxy/abi/liquidity-reserve-abi.ts b/src/lib/investor/investor-foxy/abi/liquidity-reserve-abi.ts index 4cea3c40602..c27ffe98eb8 100644 --- a/src/lib/investor/investor-foxy/abi/liquidity-reserve-abi.ts +++ b/src/lib/investor/investor-foxy/abi/liquidity-reserve-abi.ts @@ -1,6 +1,6 @@ -import type { ContractInterface } from 'ethers' +import type { InterfaceAbi } from 'ethers' -export const liquidityReserveAbi: ContractInterface = [ +export const liquidityReserveAbi: InterfaceAbi = [ { inputs: [ { diff --git a/src/lib/investor/investor-foxy/abi/toke-manager-abi.ts b/src/lib/investor/investor-foxy/abi/toke-manager-abi.ts index a4a5250015e..05fa03c7b39 100644 --- a/src/lib/investor/investor-foxy/abi/toke-manager-abi.ts +++ b/src/lib/investor/investor-foxy/abi/toke-manager-abi.ts @@ -1,6 +1,6 @@ -import type { ContractInterface } from 'ethers' +import type { InterfaceAbi } from 'ethers' -export const tokeManagerAbi: ContractInterface = [ +export const tokeManagerAbi: InterfaceAbi = [ { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, { anonymous: false, diff --git a/src/lib/investor/investor-foxy/abi/toke-pool-abi.ts b/src/lib/investor/investor-foxy/abi/toke-pool-abi.ts index 4ef28248b05..365958d9ec6 100644 --- a/src/lib/investor/investor-foxy/abi/toke-pool-abi.ts +++ b/src/lib/investor/investor-foxy/abi/toke-pool-abi.ts @@ -1,6 +1,6 @@ -import type { ContractInterface } from 'ethers' +import type { InterfaceAbi } from 'ethers' -export const tokePoolAbi: ContractInterface = [ +export const tokePoolAbi: InterfaceAbi = [ { anonymous: false, inputs: [ diff --git a/src/lib/investor/investor-foxy/abi/toke-reward-hash-abi.ts b/src/lib/investor/investor-foxy/abi/toke-reward-hash-abi.ts index c2d62f9274c..de4e9189d26 100644 --- a/src/lib/investor/investor-foxy/abi/toke-reward-hash-abi.ts +++ b/src/lib/investor/investor-foxy/abi/toke-reward-hash-abi.ts @@ -1,6 +1,6 @@ -import type { ContractInterface } from 'ethers' +import type { InterfaceAbi } from 'ethers' -export const tokeRewardHashAbi: ContractInterface = [ +export const tokeRewardHashAbi: InterfaceAbi = [ { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, { anonymous: false, diff --git a/src/lib/investor/investor-foxy/api/api.ts b/src/lib/investor/investor-foxy/api/api.ts index 2d788a113ee..22f94599e6b 100644 --- a/src/lib/investor/investor-foxy/api/api.ts +++ b/src/lib/investor/investor-foxy/api/api.ts @@ -10,8 +10,10 @@ import { import { KnownChainIds, WithdrawType } from '@shapeshiftoss/types' import axios from 'axios' import type { BigNumber } from 'bignumber.js' +import type { TransactionReceipt } from 'ethers' import { ethers } from 'ethers' import { toLower } from 'lodash' +import { getAddress } from 'viem' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { MAX_ALLOWANCE } from 'lib/investor/constants' import { DefiType } from 'state/slices/opportunitiesSlice/types' @@ -59,7 +61,7 @@ type EthereumChainReference = export type ConstructorArgs = { adapter: EvmBaseAdapter providerUrl: string - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider foxyAddresses: FoxyAddressesType chainReference?: EthereumChainReference } @@ -83,7 +85,7 @@ const TOKE_IPFS_URL = 'https://ipfs.tokemaklabs.xyz/ipfs' export class FoxyApi { public adapter: EvmBaseAdapter - public provider: ethers.providers.StaticJsonRpcProvider + public provider: ethers.JsonRpcProvider private providerUrl: string private foxyStakingContracts: ethers.Contract[] private liquidityReserveContracts: ethers.Contract[] @@ -116,8 +118,8 @@ export class FoxyApi { * to exponential notation ('1.6e+21') in javascript. * @param amount */ - private normalizeAmount(amount: BigNumber): ethers.BigNumber { - return ethers.BigNumber.from(amount.toFixed()) + private normalizeAmount(amount: BigNumber): BigInt { + return BigInt(amount.toFixed()) } // TODO(gomes): This is rank and should really belong in web for sanity sake. @@ -152,7 +154,7 @@ export class FoxyApi { if (dryRun) return signedTx try { if (this.providerUrl.includes('localhost') || this.providerUrl.includes('127.0.0.1')) { - const sendSignedTx = await this.provider.sendTransaction(signedTx) + const sendSignedTx = await this.provider.broadcastTransaction(signedTx) return sendSignedTx?.blockHash ?? '' } return this.adapter.broadcastTransaction({ @@ -178,8 +180,8 @@ export class FoxyApi { } checksumAddress(address: string): string { - // ethers always returns checksum addresses from getAddress() calls - return ethers.utils.getAddress(address) + // viem always returns checksum addresses from getAddress() calls + return getAddress(address) } private verifyAddresses(addresses: string[]) { @@ -190,7 +192,9 @@ export class FoxyApi { private getStakingContract(contractAddress: string): ethers.Contract { const stakingContract = this.foxyStakingContracts.find( - item => toLower(item.address) === toLower(contractAddress), + // This can be string | Addressable, where Addressable is an object containing getAddress() + // for ENS names. We can safely narrow it down to a string, as we do not instantiate contracts with an ens name. + item => toLower(item.target as string) === toLower(contractAddress), ) if (!stakingContract) throw new Error('Not a valid contract address') return stakingContract @@ -198,7 +202,9 @@ export class FoxyApi { private getLiquidityReserveContract(liquidityReserveAddress: string): ethers.Contract { const liquidityReserveContract = this.liquidityReserveContracts.find( - item => toLower(item.address) === toLower(liquidityReserveAddress), + // This can be string | Addressable, where Addressable is an object containing getAddress() + // for ENS names. We can safely narrow it down to a string, as we do not instantiate contracts with an ens name. + item => toLower(item.target as string) === toLower(liquidityReserveAddress), ) if (!liquidityReserveContract) throw new Error('Not a valid reserve contract address') return liquidityReserveContract @@ -209,7 +215,9 @@ export class FoxyApi { const opportunities = await Promise.all( this.foxyAddresses.map(async addresses => { const stakingContract = this.foxyStakingContracts.find( - item => toLower(item.address) === toLower(addresses.staking), + // This can be string | Addressable, where Addressable is an object containing getAddress() + // for ENS names. We can safely narrow it down to a string, as we do not instantiate contracts with an ens name. + item => toLower(item.target as string) === toLower(addresses.staking), ) try { const expired = await stakingContract?.pauseStaking() @@ -246,7 +254,7 @@ export class FoxyApi { } } - getTxReceipt({ txid }: TxReceipt): Promise { + getTxReceipt({ txid }: TxReceipt): Promise { if (!txid) throw new Error('Must pass txid') return this.provider.getTransactionReceipt(txid) } @@ -361,7 +369,7 @@ export class FoxyApi { const liquidityReserveContract = this.getLiquidityReserveContract(contractAddress) try { - const data = liquidityReserveContract.encodeFunctionData('removeLiquidity', [ + const data = await liquidityReserveContract.encodeFunctionData('removeLiquidity', [ this.normalizeAmount(amountDesired), ]) @@ -650,7 +658,12 @@ export class FoxyApi { } })() - const epoch = await (() => { + const epoch: { + length?: BigInt + number?: BigInt + endBlock?: BigInt + distribute?: BigInt + } = await (() => { try { return stakingContract.epoch() } catch (e) { @@ -659,52 +672,66 @@ export class FoxyApi { } })() - const requestedWithdrawals = await (() => { + const requestedWithdrawals: { + minCycle?: BigInt + amount?: BigInt + } = await (() => { try { - return tokePoolContract.requestedWithdrawals(stakingContract.address) + return tokePoolContract.requestedWithdrawals(stakingContract.target) } catch (e) { console.error(e, 'failed to get requestedWithdrawals') return {} } })() - const currentCycleIndex = await (() => { + const currentCycleIndex: BigInt = await (() => { try { return tokeManagerContract.getCurrentCycleIndex() } catch (e) { console.error(e, 'failed to get currentCycleIndex') - return 0 + return BigInt(0) } })() - - const withdrawalAmount = await (() => { + const withdrawalAmount: BigInt = await (() => { try { return stakingContract.withdrawalAmount() } catch (e) { console.error(e, 'failed to get currentCycleIndex') - return 0 + return BigInt(0) } })() const currentBlock = await this.provider.getBlockNumber() - const epochExpired = epoch.number.gte(coolDownInfo.endEpoch) - const coolDownValid = !coolDownInfo.endEpoch.isZero() && !coolDownInfo.amount.isZero() + const epochExpired = bnOrZero(epoch.number?.toString()).gte(coolDownInfo.endEpoch.toString()) + const coolDownValid = + !bnOrZero(coolDownInfo.endEpoch).isZero() && !bnOrZero(coolDownInfo.amount).isZero() - const pastTokeCycleIndex = requestedWithdrawals.minCycle.lte(currentCycleIndex) - const stakingTokenAvailableWithTokemak = requestedWithdrawals.amount.add(withdrawalAmount) - const stakingTokenAvailable = withdrawalAmount.gte(coolDownInfo.amount) + const pastTokeCycleIndex = bnOrZero(requestedWithdrawals.minCycle?.toString()).lte( + currentCycleIndex.toString(), + ) + const stakingTokenAvailableWithTokemak = bnOrZero(requestedWithdrawals.amount?.toString()).plus( + withdrawalAmount.toString(), + ) + const stakingTokenAvailable = bnOrZero(withdrawalAmount.toString()).gte(coolDownInfo.amount) const validCycleAndAmount = (pastTokeCycleIndex && stakingTokenAvailableWithTokemak.gte(coolDownInfo.amount)) || stakingTokenAvailable - const epochsLeft = bnOrZero(coolDownInfo.endEpoch.toString()).minus(epoch.number.toString()) + const epochsLeft = bnOrZero(coolDownInfo.endEpoch.toString()).minus( + epoch.number?.toString() ?? '0', + ) const blocksLeftInCurrentEpoch = - epochsLeft.gt(0) && epoch.endBlock.gt(currentBlock) - ? epoch.endBlock.sub(currentBlock).toNumber() + epochsLeft.gt(0) && bnOrZero(epoch.endBlock?.toString()).gt(currentBlock) + ? bnOrZero(epoch.endBlock?.toString()) + .minus(currentBlock) + .toNumber() : 0 // calculate time remaining in current epoch const blocksLeftInFutureEpochs = epochsLeft.minus(1).gt(0) - ? epochsLeft.minus(1).times(epoch.length).toNumber() + ? epochsLeft + .minus(1) + .times(epoch.length?.toString() ?? '0') + .toNumber() : 0 return ( @@ -814,7 +841,7 @@ export class FoxyApi { const nextCycleStart = bnOrZero(currentCycleStart).plus(duration) const blockNumber = await this.provider.getBlockNumber() - const timestamp = (await this.provider.getBlock(blockNumber)).timestamp + const timestamp = (await this.provider.getBlock(blockNumber))?.timestamp const isTimeToRequest = bnOrZero(timestamp) .plus(timeLeftToRequestWithdrawal) @@ -996,8 +1023,6 @@ export class FoxyApi { } const liquidityReserveContract = this.getLiquidityReserveContract(liquidityReserveAddress) try { - // ethers BigNumber doesn't support floats, so we have to convert it to a regular bn first - // to be able to get a float bignumber.js as an output const feeInBasisPoints = bnOrZero((await liquidityReserveContract.fee()).toString()) return feeInBasisPoints.div(10000) // convert from basis points to decimal percentage } catch (e) { @@ -1046,7 +1071,7 @@ export class FoxyApi { const coolDownInfo: [amount: string, gons: string, expiry: string] = ( await stakingContract.coolDownInfo(userAddress) - ).map((info: ethers.BigNumber) => info.toString()) + ).map((info: BigInt) => info.toString()) const releaseTime = await this.getTimeUntilClaimable(input) const [amount, gons, expiry] = coolDownInfo diff --git a/src/lib/investor/investor-foxy/foxycli.ts b/src/lib/investor/investor-foxy/foxycli.ts index 4c717810d98..c69ee6c96e6 100644 --- a/src/lib/investor/investor-foxy/foxycli.ts +++ b/src/lib/investor/investor-foxy/foxycli.ts @@ -55,9 +55,7 @@ const main = async (): Promise => { adapter: ethChainAdapter, providerUrl: process.env.ARCHIVE_NODE || 'http://127.0.0.1:8545/', foxyAddresses, - provider: new ethers.providers.StaticJsonRpcProvider( - process.env.ARCHIVE_NODE || 'http://127.0.0.1:8545/', - ), + provider: new ethers.JsonRpcProvider(process.env.ARCHIVE_NODE || 'http://127.0.0.1:8545/'), }) const accountNumber = 0 diff --git a/src/lib/market-service/foxy/foxy.test.ts b/src/lib/market-service/foxy/foxy.test.ts index d4a006b1950..b5f721092e2 100644 --- a/src/lib/market-service/foxy/foxy.test.ts +++ b/src/lib/market-service/foxy/foxy.test.ts @@ -8,7 +8,7 @@ import { FOXY_ASSET_ID, FoxyMarketService } from './foxy' import { fox, mockFoxyMarketData } from './foxyMockData' const foxyMarketService = new FoxyMarketService({ - provider: new ethers.providers.StaticJsonRpcProvider(''), + provider: new ethers.JsonRpcProvider(''), providerUrls: { jsonRpcProviderUrl: 'dummy', unchainedEthereumHttpUrl: '', diff --git a/src/lib/market-service/foxy/foxy.ts b/src/lib/market-service/foxy/foxy.ts index 712cc074629..f4087fa3d5c 100644 --- a/src/lib/market-service/foxy/foxy.ts +++ b/src/lib/market-service/foxy/foxy.ts @@ -20,14 +20,14 @@ const FOXY_ASSET_PRECISION = '18' export class FoxyMarketService extends CoinGeckoMarketService implements MarketService { providerUrls: ProviderUrls - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider constructor({ providerUrls, provider, }: { providerUrls: ProviderUrls - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider }) { super() diff --git a/src/lib/market-service/market-service-manager.ts b/src/lib/market-service/market-service-manager.ts index 736f706a075..39af57f3d47 100644 --- a/src/lib/market-service/market-service-manager.ts +++ b/src/lib/market-service/market-service-manager.ts @@ -26,7 +26,7 @@ export type ProviderUrls = { export type MarketServiceManagerArgs = { yearnChainReference: 1 | 250 | 1337 | 42161 // from @yfi/sdk providerUrls: ProviderUrls - provider: ethers.providers.StaticJsonRpcProvider + provider: ethers.JsonRpcProvider } export class MarketServiceManager { diff --git a/src/lib/market-service/market-service.test.ts b/src/lib/market-service/market-service.test.ts index 515b1c0b9b7..c3403bd1b90 100644 --- a/src/lib/market-service/market-service.test.ts +++ b/src/lib/market-service/market-service.test.ts @@ -101,7 +101,7 @@ describe('market service', () => { const marketServiceManagerArgs = { coinGeckoAPIKey: 'dummyCoingeckoApiKey', yearnChainReference: 1 as const, - provider: new ethers.providers.StaticJsonRpcProvider(''), + provider: new ethers.JsonRpcProvider(''), providerUrls: { jsonRpcProviderUrl: '', unchainedEthereumWsUrl: '', diff --git a/src/lib/swapper/swappers/CowSwapper/CowSwapper.ts b/src/lib/swapper/swappers/CowSwapper/CowSwapper.ts index f71ec3729d5..c101d82b5a1 100644 --- a/src/lib/swapper/swappers/CowSwapper/CowSwapper.ts +++ b/src/lib/swapper/swappers/CowSwapper/CowSwapper.ts @@ -8,7 +8,7 @@ import type { import type { Asset } from '@shapeshiftoss/types' import { getConfig } from 'config' import { ethers } from 'ethers' -import { isHexString } from 'ethers/lib/utils.js' +import { isHex } from 'viem' import { filterAssetIdsBySellable } from './filterAssetIdsBySellable/filterAssetIdsBySellable' import { filterBuyAssetsBySellAssetId } from './filterBuyAssetsBySellAssetId/filterBuyAssetsBySellAssetId' @@ -38,14 +38,14 @@ export const cowSwapper: Swapper = { // orderDigest should be an hex string here. All we need to do is pass it to signMessage/wallet.ethSignMessage and sign it const messageToSign = orderDigest - if (!isHexString(messageToSign)) throw new Error('messageToSign is not an hex string') + if (!isHex(messageToSign)) throw new Error('messageToSign is not an hex string') const signatureOrderDigest = await signMessage(messageToSign) // Passing the signature through split/join to normalize the `v` byte. // Some wallets do not pad it with `27`, which causes a signature failure // `splitSignature` pads it if needed, and `joinSignature` simply puts it back together - const signature = ethers.utils.joinSignature(ethers.utils.splitSignature(signatureOrderDigest)) + const signature = ethers.Signature.from(ethers.Signature.from(signatureOrderDigest)).serialized const maybeNetwork = getCowswapNetwork(chainId) if (maybeNetwork.isErr()) throw maybeNetwork.unwrapErr() diff --git a/src/lib/swapper/swappers/CowSwapper/utils/constants.ts b/src/lib/swapper/swappers/CowSwapper/utils/constants.ts index d5e04bf9b4d..2de8b3370c7 100644 --- a/src/lib/swapper/swappers/CowSwapper/utils/constants.ts +++ b/src/lib/swapper/swappers/CowSwapper/utils/constants.ts @@ -1,5 +1,5 @@ -import { AddressZero } from '@ethersproject/constants' import { KnownChainIds } from '@shapeshiftoss/types' +import { zeroAddress } from 'viem' import type { CowChainId } from '../types' @@ -8,7 +8,7 @@ export const MIN_COWSWAP_USD_TRADE_VALUES_BY_CHAIN_ID: Record, ): string => { - return ethers.utils._TypedDataEncoder.hash(domain, types, data) + return TypedDataEncoder.hash(domain, types, data) } /** @@ -216,7 +216,7 @@ const generateAppDataFromDoc = async ( doc: LatestAppDataDocVersion, ): Promise> => { const appData = await stringifyDeterministic(doc) - const appDataKeccak256 = keccak256(toUtf8Bytes(appData)) + const appDataKeccak256 = keccak256(stringToBytes(appData)) return { fullAppData: appData, appDataKeccak256 } } diff --git a/src/lib/swapper/swappers/LifiSwapper/utils/getNetworkFeeCryptoBaseUnit/getNetworkFeeCryptoBaseUnit.ts b/src/lib/swapper/swappers/LifiSwapper/utils/getNetworkFeeCryptoBaseUnit/getNetworkFeeCryptoBaseUnit.ts index e92020c10b9..17ad2b93340 100644 --- a/src/lib/swapper/swappers/LifiSwapper/utils/getNetworkFeeCryptoBaseUnit/getNetworkFeeCryptoBaseUnit.ts +++ b/src/lib/swapper/swappers/LifiSwapper/utils/getNetworkFeeCryptoBaseUnit/getNetworkFeeCryptoBaseUnit.ts @@ -2,7 +2,6 @@ import type { LifiStep } from '@lifi/types' import type { ChainId } from '@shapeshiftoss/caip' import type { EvmChainId } from '@shapeshiftoss/chain-adapters' import { KnownChainIds } from '@shapeshiftoss/types' -import type { BigNumber } from 'ethers' import { ethers } from 'ethers' import { getEthersProvider } from 'lib/ethersProviderSingleton' import { assertGetEvmChainAdapter, calcNetworkFeeCryptoBaseUnit } from 'lib/utils/evm' @@ -50,7 +49,7 @@ export const getNetworkFeeCryptoBaseUnit = async ({ const contract = new ethers.Contract(OPTIMISM_GAS_ORACLE_ADDRESS, abi, provider) - const l1GasUsed = (await contract.getL1GasUsed(data)) as BigNumber + const l1GasUsed = (await contract.getL1GasUsed(data)) as BigInt return l1GasUsed.toString() })() diff --git a/src/lib/utils/evm.ts b/src/lib/utils/evm.ts index 2483e03949e..a2dddac44b0 100644 --- a/src/lib/utils/evm.ts +++ b/src/lib/utils/evm.ts @@ -15,7 +15,6 @@ import { TxStatus } from '@shapeshiftoss/unchained-client' import { getTxStatus } from '@shapeshiftoss/unchained-client/dist/evm' import { getOrCreateContractByType } from 'contracts/contractManager' import { ContractType } from 'contracts/types' -import { ethers } from 'ethers' import { encodeFunctionData, getAddress } from 'viem' import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -219,7 +218,7 @@ export const getApproveContractData = ({ spender, chainId, }: GetApproveContractDataArgs): string => { - const address = ethers.utils.getAddress(to) + const address = getAddress(to) const contract = getOrCreateContractByType({ address, type: ContractType.ERC20, diff --git a/src/pages/Lending/Pool/components/Borrow/BorrowConfirm.tsx b/src/pages/Lending/Pool/components/Borrow/BorrowConfirm.tsx index 625410b34b6..1b886684d02 100644 --- a/src/pages/Lending/Pool/components/Borrow/BorrowConfirm.tsx +++ b/src/pages/Lending/Pool/components/Borrow/BorrowConfirm.tsx @@ -21,12 +21,12 @@ import type { Asset, KnownChainIds } from '@shapeshiftoss/types' import { TxStatus } from '@shapeshiftoss/unchained-client' import { useMutation, useMutationState } from '@tanstack/react-query' import dayjs from 'dayjs' -import { utils } from 'ethers' import prettyMilliseconds from 'pretty-ms' import { useCallback, useEffect, useMemo, useState } from 'react' import { useTranslate } from 'react-polyglot' import { useQuoteEstimatedFeesQuery } from 'react-queries/hooks/useQuoteEstimatedFeesQuery' import { useHistory } from 'react-router' +import { toHex } from 'viem' import { Amount } from 'components/Amount/Amount' import { AssetToAsset } from 'components/AssetToAsset/AssetToAsset' import { HelperTooltip } from 'components/HelperTooltip/HelperTooltip' @@ -299,7 +299,7 @@ export const BorrowConfirm = ({ sendMax: false, accountId: collateralAccountId, memo: supportedEvmChainIds.includes(fromAssetId(collateralAssetId).chainId as KnownChainIds) - ? utils.hexlify(utils.toUtf8Bytes(confirmedQuote.quoteMemo)) + ? toHex(confirmedQuote.quoteMemo) : confirmedQuote.quoteMemo, amountFieldError: '', estimatedFees, diff --git a/src/pages/Lending/Pool/components/Repay/RepayConfirm.tsx b/src/pages/Lending/Pool/components/Repay/RepayConfirm.tsx index e9aa39bb851..bf5113de1d6 100644 --- a/src/pages/Lending/Pool/components/Repay/RepayConfirm.tsx +++ b/src/pages/Lending/Pool/components/Repay/RepayConfirm.tsx @@ -23,12 +23,12 @@ import type { Asset, KnownChainIds } from '@shapeshiftoss/types' import { TxStatus } from '@shapeshiftoss/unchained-client' import { useMutation, useMutationState } from '@tanstack/react-query' import dayjs from 'dayjs' -import { utils } from 'ethers' import prettyMilliseconds from 'pretty-ms' import { useCallback, useEffect, useMemo, useState } from 'react' import { useTranslate } from 'react-polyglot' import { useQuoteEstimatedFeesQuery } from 'react-queries/hooks/useQuoteEstimatedFeesQuery' import { useHistory } from 'react-router' +import { toHex } from 'viem' import { Amount } from 'components/Amount/Amount' import { AssetToAsset } from 'components/AssetToAsset/AssetToAsset' import { HelperTooltip } from 'components/HelperTooltip/HelperTooltip' @@ -290,7 +290,7 @@ export const RepayConfirm = ({ memo: supportedEvmChainIds.includes( fromAssetId(repaymentAsset.assetId).chainId as KnownChainIds, ) - ? utils.hexlify(utils.toUtf8Bytes(confirmedQuote.quoteMemo)) + ? toHex(confirmedQuote.quoteMemo) : confirmedQuote.quoteMemo, to: confirmedQuote.quoteInboundAddress, sendMax: false, @@ -342,7 +342,7 @@ export const RepayConfirm = ({ memo: supportedEvmChainIds.includes( fromAssetId(repaymentAsset?.assetId).chainId as KnownChainIds, ) - ? utils.hexlify(utils.toUtf8Bytes(confirmedQuote.quoteMemo)) + ? toHex(confirmedQuote.quoteMemo) : confirmedQuote.quoteMemo, amountFieldError: '', estimatedFees, diff --git a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx index c10329e4778..c43516cf8e5 100644 --- a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx +++ b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx @@ -9,7 +9,6 @@ import { Link, Skeleton, } from '@chakra-ui/react' -import { AddressZero } from '@ethersproject/constants' import type { AccountId, ChainId } from '@shapeshiftoss/caip' import { type AssetId, @@ -34,7 +33,7 @@ import { useTranslate } from 'react-polyglot' import { reactQueries } from 'react-queries' import { useIsTradingActive } from 'react-queries/hooks/useIsTradingActive' import { selectInboundAddressData } from 'react-queries/selectors' -import { getAddress } from 'viem' +import { getAddress, zeroAddress } from 'viem' import { Amount } from 'components/Amount/Amount' import { AssetIcon } from 'components/AssetIcon' import { CircularProgress } from 'components/CircularProgress/CircularProgress' @@ -291,7 +290,7 @@ export const TransactionRow: React.FC = ({ if (!inboundAddressData?.router) return undefined const assetAddress = isToken(fromAssetId(assetId).assetReference) ? getAddress(fromAssetId(assetId).assetReference) - : AddressZero + : zeroAddress const amount = BigInt(toBaseUnit(amountCryptoPrecision, asset.precision).toString()) const args = (() => { @@ -301,7 +300,7 @@ export const TransactionRow: React.FC = ({ ? getAddress(fromAssetId(assetId).assetReference) : // Native EVM assets use the 0 address as the asset address // https://dev.thorchain.org/concepts/sending-transactions.html#admonition-info-1 - AddressZero + zeroAddress const memo = `+:${thorchainNotationAssetId}:${otherAssetAddress ?? ''}:ss:${ confirmedQuote.feeBps @@ -476,7 +475,7 @@ export const TransactionRow: React.FC = ({ ? getAddress(fromAssetId(assetId).assetReference) : // Native EVM assets use the 0 address as the asset address // https://dev.thorchain.org/concepts/sending-transactions.html#admonition-info-1 - AddressZero + zeroAddress const memo = `+:${thorchainNotationAssetId}:${otherAssetAddress ?? ''}:ss:${ confirmedQuote.feeBps diff --git a/src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx b/src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx index 23d8f422f56..f84f3d243da 100644 --- a/src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx +++ b/src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx @@ -1,6 +1,6 @@ import { Box, Divider, Flex, HStack, useColorModeValue } from '@chakra-ui/react' -import type { ParamType, TransactionDescription } from '@ethersproject/abi' import type { Asset } from '@shapeshiftoss/types' +import type { ParamType, TransactionDescription } from 'ethers' import startCase from 'lodash/startCase' import { CopyButton } from 'plugins/walletConnectToDapps/components/modals/CopyButton' import { ExternalLinkButton } from 'plugins/walletConnectToDapps/components/modals/ExternalLinkButtons' @@ -35,13 +35,13 @@ export const ContractInteractionBreakdown: FC }) => { const contractInterface = useGetAbi(request) - const transaction: TransactionDescription | undefined = useMemo(() => { - if (!contractInterface) return undefined + const transaction: TransactionDescription | null = useMemo(() => { + if (!contractInterface) return null try { return contractInterface?.parseTransaction({ data: request.data, value: request.value }) } catch (e) { console.error(e) - return undefined + return null } }, [contractInterface, request.data, request.value]) @@ -112,7 +112,7 @@ export const ContractInteractionBreakdown: FC )} {!!transaction && - transaction.functionFragment.inputs.map((input, index) => { + transaction.fragment.inputs.map((input, index) => { const Wrapper = input.type === 'bytes[]' ? Flex : Fragment const wrapperProps = input.type === 'bytes[]' diff --git a/src/plugins/walletConnectToDapps/hooks/useGetAbi.tsx b/src/plugins/walletConnectToDapps/hooks/useGetAbi.tsx index c41df7d08b0..6b8bb78651c 100644 --- a/src/plugins/walletConnectToDapps/hooks/useGetAbi.tsx +++ b/src/plugins/walletConnectToDapps/hooks/useGetAbi.tsx @@ -1,8 +1,10 @@ import { skipToken } from '@reduxjs/toolkit/query' -import { getConfig } from 'config' -import { ethers } from 'ethers' +import { KnownChainIds } from '@shapeshiftoss/types' +import { ethers, Fragment } from 'ethers' import type { TransactionParams } from 'plugins/walletConnectToDapps/types' import { useEffect, useMemo, useState } from 'react' +import { getAddress } from 'viem' +import { getEthersProvider } from 'lib/ethersProviderSingleton' import { useGetContractAbiQuery } from 'state/apis/abi/abiApi' /* @@ -19,22 +21,17 @@ enum PROXY_CONTRACT_METHOD_NAME { const EIP1967_IMPLEMENTATION_SLOT = '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' -export const useGetAbi = ( - transactionParams: TransactionParams, -): ethers.utils.Interface | undefined => { +export const useGetAbi = (transactionParams: TransactionParams): ethers.Interface | undefined => { const [proxyContractImplementation, setProxyContractImplementation] = useState( null, ) const { to: contractAddress, data } = transactionParams - const provider = useMemo( - () => new ethers.providers.StaticJsonRpcProvider(getConfig().REACT_APP_ETHEREUM_NODE_URL), - [], - ) + const provider = useMemo(() => getEthersProvider(KnownChainIds.EthereumMainnet), []) const { data: rootContractRawAbiData } = useGetContractAbiQuery(contractAddress) const rootContractInterface = useMemo( - () => (rootContractRawAbiData ? new ethers.utils.Interface(rootContractRawAbiData) : undefined), + () => (rootContractRawAbiData ? new ethers.Interface(rootContractRawAbiData) : undefined), [rootContractRawAbiData], ) @@ -52,7 +49,7 @@ export const useGetAbi = ( // check for proxy methods on the root interface let proxyFunctionNameIfExists: string | undefined if (rootContractInterface) { - const rootFunctions = Object.values(rootContractInterface.functions) + const rootFunctions = rootContractInterface.fragments.filter(Fragment.isFunction) proxyFunctionNameIfExists = Object.values(PROXY_CONTRACT_METHOD_NAME).find(x => rootFunctions.find(y => y.name === x), ) @@ -67,14 +64,12 @@ export const useGetAbi = ( await rootContractWithProvider?.getFunctionImplementation(sighash) break case PROXY_CONTRACT_METHOD_NAME.EIP1967: - const paddedImplementationAddress = await provider.getStorageAt( + const paddedImplementationAddress = await provider.getStorage( contractAddress, EIP1967_IMPLEMENTATION_SLOT, ) // Remove the first 26 chars (64 hex digits) - implementationAddress = ethers.utils.getAddress( - paddedImplementationAddress.substring(26), - ) + implementationAddress = getAddress(paddedImplementationAddress.substring(26)) break default: implementationAddress = null @@ -96,7 +91,7 @@ export const useGetAbi = ( const implementationContractInterface = useMemo( () => contractImplementationRawAbiData - ? new ethers.utils.Interface(contractImplementationRawAbiData) + ? new ethers.Interface(contractImplementationRawAbiData) : undefined, [contractImplementationRawAbiData], ) diff --git a/src/plugins/walletConnectToDapps/utils.ts b/src/plugins/walletConnectToDapps/utils.ts index 3521c683f94..19dc680ff80 100644 --- a/src/plugins/walletConnectToDapps/utils.ts +++ b/src/plugins/walletConnectToDapps/utils.ts @@ -8,7 +8,6 @@ import type { GetFeeDataInput, } from '@shapeshiftoss/chain-adapters' import type { SessionTypes } from '@walletconnect/types' -import { utils } from 'ethers' import type { ConfirmData, CosmosSignAminoCallRequestParams, @@ -18,6 +17,7 @@ import type { TransactionParams, WalletConnectState, } from 'plugins/walletConnectToDapps/types' +import { hexToString, isAddress, isHex, toHex } from 'viem' import { bnOrZero } from 'lib/bignumber/bignumber' import { isSome } from 'lib/utils' @@ -26,7 +26,7 @@ import { isSome } from 'lib/utils' */ export const maybeConvertHexEncodedMessageToUtf8 = (value: string) => { try { - return utils.isHexString(value) ? utils.toUtf8String(value) : value + return isHex(value) ? hexToString(value) : value } catch (e) { // use raw hex string if unable to convert to utf8 (ex. keccak256) return value @@ -34,7 +34,7 @@ export const maybeConvertHexEncodedMessageToUtf8 = (value: string) => { } export const convertNumberToHex = (value: number | string): string => - typeof value === 'number' ? utils.hexlify(value) : utils.hexlify(utils.hexlify(parseInt(value))) + typeof value === 'number' ? toHex(value) : toHex(parseInt(value)) export const convertHexToNumber = (value: string): number => parseInt(value, 16) @@ -81,7 +81,7 @@ export const getGasData = ( * If it is a hex string, it gets converted to utf8 string */ export const getSignParamsMessage = (params: [string, string], toUtf8: boolean) => { - const message = params.filter(p => !utils.isAddress(p))[0] + const message = params.filter(p => !isAddress(p))[0] return toUtf8 ? maybeConvertHexEncodedMessageToUtf8(message) : message } diff --git a/src/react-queries/hooks/useQuoteEstimatedFeesQuery.ts b/src/react-queries/hooks/useQuoteEstimatedFeesQuery.ts index 17cc3384710..be1346ac31d 100644 --- a/src/react-queries/hooks/useQuoteEstimatedFeesQuery.ts +++ b/src/react-queries/hooks/useQuoteEstimatedFeesQuery.ts @@ -1,8 +1,8 @@ import { type AccountId, type AssetId, fromAssetId } from '@shapeshiftoss/caip' import type { Asset, KnownChainIds, MarketData } from '@shapeshiftoss/types' import { useQuery } from '@tanstack/react-query' -import { utils } from 'ethers' import { useMemo } from 'react' +import { toHex } from 'viem' import type { EstimateFeesInput } from 'components/Modals/Send/utils' import { estimateFees } from 'components/Modals/Send/utils' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -89,7 +89,7 @@ export const useQuoteEstimatedFeesQuery = ({ confirmedQuote && 'quoteMemo' in confirmedQuote ? confirmedQuote.quoteMemo : '' const memo = assetId && supportedEvmChainIds.includes(fromAssetId(assetId).chainId as KnownChainIds) - ? utils.hexlify(utils.toUtf8Bytes(quoteMemo)) + ? toHex(quoteMemo) : quoteMemo const to = confirmedQuote && 'quoteInboundAddress' in confirmedQuote diff --git a/src/state/slices/opportunitiesSlice/resolvers/uniV2/index.ts b/src/state/slices/opportunitiesSlice/resolvers/uniV2/index.ts index 962d6c4ac2a..325a63695ed 100644 --- a/src/state/slices/opportunitiesSlice/resolvers/uniV2/index.ts +++ b/src/state/slices/opportunitiesSlice/resolvers/uniV2/index.ts @@ -4,7 +4,7 @@ import type { TokenAmount } from '@uniswap/sdk' import { WETH_TOKEN_CONTRACT_ADDRESS } from 'contracts/constants' import { fetchUniV2PairData, getOrCreateContractByType } from 'contracts/contractManager' import { ContractType } from 'contracts/types' -import { ethers } from 'ethers' +import { getAddress } from 'viem' import type { BN } from 'lib/bignumber/bignumber' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { getEthersProvider } from 'lib/ethersProviderSingleton' @@ -131,8 +131,8 @@ export const uniV2LpOpportunitiesMetadataResolver = async ({ token1Decimals = zapperAppBalanceData.tokens?.[1].decimals! token0Reserves = bnOrZero(zapperAppBalanceData.dataProps?.reserves?.[0])! token1Reserves = bnOrZero(zapperAppBalanceData.dataProps?.reserves?.[1])! - token0Address = ethers.utils.getAddress(zapperAppBalanceData?.tokens?.[0].address!) - token1Address = ethers.utils.getAddress(zapperAppBalanceData?.tokens?.[1].address!) + token0Address = getAddress(zapperAppBalanceData?.tokens?.[0].address!) + token1Address = getAddress(zapperAppBalanceData?.tokens?.[1].address!) apr = bnOrZero(zapperAppBalanceData.dataProps?.apy!).toFixed() return { token0Decimals, @@ -191,7 +191,7 @@ export const uniV2LpOpportunitiesMetadataResolver = async ({ const { assetReference } = fromAssetId(opportunityId) // Checksum - const contractAddress = ethers.utils.getAddress(assetReference) + const contractAddress = getAddress(assetReference) const uniV2LPContract = getOrCreateContractByType({ address: contractAddress, type: ContractType.UniV2Pair, diff --git a/src/state/slices/opportunitiesSlice/resolvers/uniV2/utils.ts b/src/state/slices/opportunitiesSlice/resolvers/uniV2/utils.ts index eecc910b366..f61e93812e4 100644 --- a/src/state/slices/opportunitiesSlice/resolvers/uniV2/utils.ts +++ b/src/state/slices/opportunitiesSlice/resolvers/uniV2/utils.ts @@ -5,10 +5,9 @@ import type { TokenAmount } from '@uniswap/sdk' import type { IUniswapV2Pair } from 'contracts/abis/IUniswapV2Pair' import { getOrCreateContractByType } from 'contracts/contractManager' import { ContractType } from 'contracts/types' -import { ethers } from 'ethers' import memoize from 'lodash/memoize' import type { GetContractReturnType, PublicClient, WalletClient } from 'viem' -import { parseAbiItem } from 'viem' +import { getAddress, parseAbiItem } from 'viem' import type { BN } from 'lib/bignumber/bignumber' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { viemEthMainnetClient } from 'lib/viem-client' @@ -65,7 +64,7 @@ export const calculateAPRFromToken0 = memoize( const { assetReference } = fromAssetId(pairAssetId) // Checksum - const contractAddress = ethers.utils.getAddress(assetReference) + const contractAddress = getAddress(assetReference) const pair = getOrCreateContractByType({ address: contractAddress, type: ContractType.UniV2Pair, diff --git a/src/test/mocks/txs.ts b/src/test/mocks/txs.ts index cf877b0a70e..9de9145f88b 100644 --- a/src/test/mocks/txs.ts +++ b/src/test/mocks/txs.ts @@ -1,7 +1,7 @@ -import { AddressZero } from '@ethersproject/constants' import { ethAssetId, ethChainId, foxAssetId } from '@shapeshiftoss/caip' import { UtxoAccountType } from '@shapeshiftoss/types' import { Dex, TradeType, TransferType, TxStatus } from '@shapeshiftoss/unchained-client' +import { zeroAddress } from 'viem' import type { Tx } from 'state/slices/txHistorySlice/txHistorySlice' export const EthSend: Tx = { @@ -119,7 +119,7 @@ export const TradeTx: Tx = { transfers: [ { assetId: 'eip155:1/erc20:0x5f18c75abdae578b483e5f43f12a39cf75b973a9', - from: [AddressZero], + from: [zeroAddress], to: ['0x934be745172066EDF795ffc5EA9F28f19b440c63'], type: TransferType.Receive, value: '9178352', @@ -315,7 +315,7 @@ export const yearnVaultDeposit: Tx = { transfers: [ { assetId: 'eip155:1/erc20:0x5f18c75abdae578b483e5f43f12a39cf75b973a9', - from: [AddressZero], + from: [zeroAddress], to: ['0x934be745172066EDF795ffc5EA9F28f19b440c63'], type: TransferType.Receive, value: '9178352', @@ -353,7 +353,7 @@ export const createMockEthTxs = (account: string): Tx[] => { }, { assetId: 'eip155:1/erc20:0xfbeb78a723b8087fd2ea7ef1afec93d35e8bed42', - from: [AddressZero], + from: [zeroAddress], to: [account], type: TransferType.Receive, value: '5481290118862792961', @@ -378,7 +378,7 @@ export const createMockEthTxs = (account: string): Tx[] => { { assetId: 'eip155:1/erc20:0xfbeb78a723b8087fd2ea7ef1afec93d35e8bed42', from: [account], - to: [AddressZero], + to: [zeroAddress], type: TransferType.Send, value: '5481290118862792961', }, diff --git a/vitest-web.config.ts b/vitest-web.config.ts index 2e0ce781add..c4083c636b3 100644 --- a/vitest-web.config.ts +++ b/vitest-web.config.ts @@ -16,6 +16,9 @@ export default defineConfig({ exclude: [ 'src/lib/poll/poll.test.ts', 'src/lib/cryptography/login.test.ts', + // Temporarily skipped until https://github.com/shapeshift/hdwallet/pull/666 goes in + 'src/components/Modals/Send/hooks/useSendDetails/useSendDetails.test.tsx', + 'src/components/Modals/Send/hooks/useFormSend/useFormSend.test.tsx', 'packages/**/*.test.ts', 'packages/**/*.test.tsx', ], diff --git a/yarn.lock b/yarn.lock index acb94139162..6dceb1f3712 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,6 +12,13 @@ __metadata: languageName: node linkType: hard +"@adraffy/ens-normalize@npm:1.10.1": + version: 1.10.1 + resolution: "@adraffy/ens-normalize@npm:1.10.1" + checksum: 0836f394ea256972ec19a0b5e78cb7f5bcdfd48d8a32c7478afc94dd53ae44c04d1aa2303d7f3077b4f3ac2323b1f557ab9188e8059978748fdcd83e04a80dcc + languageName: node + linkType: hard + "@adraffy/ens-normalize@npm:1.9.4": version: 1.9.4 resolution: "@adraffy/ens-normalize@npm:1.9.4" @@ -10093,7 +10100,8 @@ __metadata: eslint-plugin-react-memo: ^0.0.3 eslint-plugin-simple-import-sort: ^10.0.0 eth-url-parser: ^1.0.4 - ethers: ^5.7.2 + ethers: ^6.11.1 + ethers5: "npm:ethers@5.7.2" express: ^4.18.2 fast-json-stable-stringify: ^2.1.0 framer-motion: ^11.0.3 @@ -11732,6 +11740,13 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:18.15.13": + version: 18.15.13 + resolution: "@types/node@npm:18.15.13" + checksum: 79cc5a2b5f98e8973061a4260a781425efd39161a0e117a69cd089603964816c1a14025e1387b4590c8e82d05133b7b4154fa53a7dffb3877890a66145e76515 + languageName: node + linkType: hard + "@types/node@npm:>= 8, @types/node@npm:^20.2.5": version: 20.8.4 resolution: "@types/node@npm:20.8.4" @@ -14489,6 +14504,13 @@ __metadata: languageName: node linkType: hard +"aes-js@npm:4.0.0-beta.5": + version: 4.0.0-beta.5 + resolution: "aes-js@npm:4.0.0-beta.5" + checksum: cc2ea969d77df939c32057f7e361b6530aa6cb93cb10617a17a45cd164e6d761002f031ff6330af3e67e58b1f0a3a8fd0b63a720afd591a653b02f649470e15b + languageName: node + linkType: hard + "aes-js@npm:^3.1.2": version: 3.1.2 resolution: "aes-js@npm:3.1.2" @@ -21055,7 +21077,7 @@ __metadata: languageName: node linkType: hard -"ethers@npm:5.7.2, ethers@npm:^5.5.3, ethers@npm:^5.6.5, ethers@npm:^5.6.9, ethers@npm:^5.7.2": +"ethers5@npm:ethers@5.7.2, ethers@npm:5.7.2, ethers@npm:^5.5.3, ethers@npm:^5.6.5, ethers@npm:^5.6.9, ethers@npm:^5.7.2": version: 5.7.2 resolution: "ethers@npm:5.7.2" dependencies: @@ -21093,6 +21115,21 @@ __metadata: languageName: node linkType: hard +"ethers@npm:^6.11.1": + version: 6.11.1 + resolution: "ethers@npm:6.11.1" + dependencies: + "@adraffy/ens-normalize": 1.10.1 + "@noble/curves": 1.2.0 + "@noble/hashes": 1.3.2 + "@types/node": 18.15.13 + aes-js: 4.0.0-beta.5 + tslib: 2.4.0 + ws: 8.5.0 + checksum: e8027c5071ad0370c61a1978f0602ab950d840c5923948f55e88b9808300e4e02e792bb793ea109ce7fa0e748f30a40a05f1202204a2b0402cdffbcb64a218e4 + languageName: node + linkType: hard + "ethjs-unit@npm:0.1.6, ethjs-unit@npm:^0.1.6": version: 0.1.6 resolution: "ethjs-unit@npm:0.1.6" @@ -36781,6 +36818,21 @@ pvutils@latest: languageName: node linkType: hard +"ws@npm:8.5.0": + version: 8.5.0 + resolution: "ws@npm:8.5.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 76f2f90e40344bf18fd544194e7067812fb1372b2a37865678d8f12afe4b478ff2ebc0c7c0aff82cd5e6b66fc43d889eec0f1865c2365d8f7a66d92da7744a77 + languageName: node + linkType: hard + "ws@npm:^3.2.0": version: 3.3.3 resolution: "ws@npm:3.3.3"