diff --git a/liquidity/components/BorrowModal/BorrowModal.tsx b/liquidity/components/BorrowModal/BorrowModal.tsx index 28e8208eb..5d4532c1d 100644 --- a/liquidity/components/BorrowModal/BorrowModal.tsx +++ b/liquidity/components/BorrowModal/BorrowModal.tsx @@ -158,7 +158,7 @@ export const BorrowModal: React.FC<{ try { await execBorrow(); await queryClient.invalidateQueries({ - queryKey: [network.name, 'LiquidityPosition'], + queryKey: [`${network.id}-${network.preset}`, 'LiquidityPosition'], exact: false, }); } catch (error: any) { @@ -178,7 +178,7 @@ export const BorrowModal: React.FC<{ }); throw Error('Borrow failed', { cause: error }); } - }, [errorParserCoreProxy, execBorrow, queryClient, toast, network.name]); + }, [execBorrow, queryClient, network.id, network.preset, errorParserCoreProxy, toast]); const { txnStatus } = txnState; if (!params.poolId || !params.accountId || !collateralType) return null; diff --git a/liquidity/components/DepositModal/DepositModal.tsx b/liquidity/components/DepositModal/DepositModal.tsx index 3592e82d1..194ffd2d7 100644 --- a/liquidity/components/DepositModal/DepositModal.tsx +++ b/liquidity/components/DepositModal/DepositModal.tsx @@ -320,18 +320,22 @@ export const DepositModal: DepositModalProps = ({ await Promise.all([ queryClient.invalidateQueries({ - queryKey: [network.name, 'EthBalance'], + queryKey: [`${network.id}-${network.preset}`, 'EthBalance'], + }), + queryClient.invalidateQueries({ + queryKey: [`${network.id}-${network.preset}`, 'LiquidityPosition'], }), - queryClient.invalidateQueries({ queryKey: [network.name, 'LiquidityPosition'] }), collateralType?.symbol === 'SNX' - ? queryClient.invalidateQueries({ queryKey: [network.name, 'TransferableSynthetix'] }) + ? queryClient.invalidateQueries({ + queryKey: [`${network.id}-${network.preset}`, 'TransferableSynthetix'], + }) : Promise.resolve(), queryClient.invalidateQueries({ - queryKey: [network.name, 'Allowance'], + queryKey: [`${network.id}-${network.preset}`, 'Allowance'], }), !params.accountId ? queryClient.invalidateQueries({ - queryKey: [network.name, 'Accounts'], + queryKey: [`${network.id}-${network.preset}`, 'Accounts'], }) : Promise.resolve(), ]); diff --git a/liquidity/components/RepayModal/RepayModal.tsx b/liquidity/components/RepayModal/RepayModal.tsx index c1c1be69c..1aef031f5 100644 --- a/liquidity/components/RepayModal/RepayModal.tsx +++ b/liquidity/components/RepayModal/RepayModal.tsx @@ -174,13 +174,13 @@ export const RepayModal: React.FC<{ await Promise.all([ queryClient.invalidateQueries({ - queryKey: [network.name, 'TokenBalance'], + queryKey: [`${network.id}-${network.preset}`, 'TokenBalance'], }), queryClient.invalidateQueries({ - queryKey: [network.name, 'Allowance'], + queryKey: [`${network.id}-${network.preset}`, 'Allowance'], }), queryClient.invalidateQueries({ - queryKey: [network.name, 'LiquidityPosition'], + queryKey: [`${network.id}-${network.preset}`, 'LiquidityPosition'], }), ]); diff --git a/liquidity/components/UndelegateModal/UndelegateModal.tsx b/liquidity/components/UndelegateModal/UndelegateModal.tsx index 9c5170a39..7b13d65cf 100644 --- a/liquidity/components/UndelegateModal/UndelegateModal.tsx +++ b/liquidity/components/UndelegateModal/UndelegateModal.tsx @@ -123,7 +123,7 @@ export const UndelegateModal: UndelegateModalProps = ({ onClose, isOpen, liquidi try { await execUndelegate(); await queryClient.invalidateQueries({ - queryKey: [network.name, 'LiquidityPosition'], + queryKey: [`${network.id}-${network.preset}`, 'LiquidityPosition'], exact: false, }); } catch (error: any) { diff --git a/liquidity/components/WithdrawModal/WithdrawModal.tsx b/liquidity/components/WithdrawModal/WithdrawModal.tsx index 67d71bed2..1a33fb8c7 100644 --- a/liquidity/components/WithdrawModal/WithdrawModal.tsx +++ b/liquidity/components/WithdrawModal/WithdrawModal.tsx @@ -134,7 +134,7 @@ export function WithdrawModal({ try { await execWithdraw(); await queryClient.invalidateQueries({ - queryKey: [network.name, 'AccountSpecificCollateral'], + queryKey: [`${network.id}-${network.preset}`, 'AccountSpecificCollateral'], }); } catch (error: any) { const contractError = errorParserCoreProxy(error); diff --git a/liquidity/cypress/cypress/support/e2e.js b/liquidity/cypress/cypress/support/e2e.js index d79aa80c5..8a5906269 100644 --- a/liquidity/cypress/cypress/support/e2e.js +++ b/liquidity/cypress/cypress/support/e2e.js @@ -24,13 +24,7 @@ beforeEach(() => { cy.on('window:before:load', async (win) => { const provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8545'); const network = await provider.getNetwork(); - const networkName = { - 1: 'mainnet', - 10: 'optimism-mainnet', - 5: 'goerli', - 420: 'optimism-goerli', - }[network.chainId]; - win.localStorage.setItem('DEFAULT_NETWORK', networkName); + win.localStorage.setItem('DEFAULT_NETWORK', `${network.chainId}-main`); win.localStorage.setItem('UNSAFE_IMPORT', 'true'); win.localStorage.setItem('connectedWallets', '["MetaMask"]'); win.localStorage.setItem('CONTRACT_ERROR_OPEN', 'true'); diff --git a/liquidity/lib/useAccountCollateral/useAccountCollateral.ts b/liquidity/lib/useAccountCollateral/useAccountCollateral.ts index a35d43749..5710fb571 100644 --- a/liquidity/lib/useAccountCollateral/useAccountCollateral.ts +++ b/liquidity/lib/useAccountCollateral/useAccountCollateral.ts @@ -70,7 +70,12 @@ export function useAccountCollateral({ const tokenAddresses = collateralTypes.data?.map((c) => c.tokenAddress) ?? []; return useQuery({ - queryKey: [network.name, { accountId }, 'AccountCollateral', { tokens: tokenAddresses }], + queryKey: [ + `${network.id}-${network.preset}`, + 'AccountCollateral', + { accountId }, + { tokens: tokenAddresses }, + ], enabled: Boolean(CoreProxy && accountId && tokenAddresses.length > 0), queryFn: async function () { if (!CoreProxy || !accountId || tokenAddresses.length < 1) { @@ -81,7 +86,13 @@ export function useAccountCollateral({ tokenAddresses, CoreProxy, }); - const data = await erc7412Call(CoreProxy.provider, calls, decoder, 'useAccountCollateral'); + const data = await erc7412Call( + network, + CoreProxy.provider, + calls, + decoder, + 'useAccountCollateral' + ); return data.map((x) => ({ ...x, @@ -97,7 +108,7 @@ export function useAccountSpecificCollateral(accountId?: string, collateralAddre const network = useNetwork(); return useQuery({ queryKey: [ - network.name, + `${network.id}-${network.preset}`, 'AccountSpecificCollateral', { accountId }, { token: collateralAddress }, @@ -113,6 +124,7 @@ export function useAccountSpecificCollateral(accountId?: string, collateralAddre CoreProxy, }); const data = await erc7412Call( + network, CoreProxy.provider, calls, decoder, diff --git a/liquidity/lib/useAccountCollateralUnlockDate/useAccountCollateralUnlockDate.ts b/liquidity/lib/useAccountCollateralUnlockDate/useAccountCollateralUnlockDate.ts index 3adc1fc27..cf134be91 100644 --- a/liquidity/lib/useAccountCollateralUnlockDate/useAccountCollateralUnlockDate.ts +++ b/liquidity/lib/useAccountCollateralUnlockDate/useAccountCollateralUnlockDate.ts @@ -8,7 +8,7 @@ export function useAccountCollateralUnlockDate({ accountId }: { accountId?: stri const network = useNetwork(); return useQuery({ - queryKey: [network.name, { accountId }, 'AccountCollateralUnlockDate'], + queryKey: [`${network.id}-${network.preset}`, 'AccountCollateralUnlockDate', { accountId }], enabled: Boolean(CoreProxy && accountId), queryFn: async function () { if (!CoreProxy || !accountId) throw 'OMG'; diff --git a/liquidity/lib/useAccountProxy/useAccountProxy.ts b/liquidity/lib/useAccountProxy/useAccountProxy.ts index a25d92b8b..13da1faf4 100644 --- a/liquidity/lib/useAccountProxy/useAccountProxy.ts +++ b/liquidity/lib/useAccountProxy/useAccountProxy.ts @@ -11,7 +11,7 @@ export function useAccountProxy() { const withSigner = Boolean(signer); return useQuery({ - queryKey: [network.name, 'AccountProxy', { withSigner }], + queryKey: [`${network.id}-${network.preset}`, 'AccountProxy', { withSigner }], queryFn: async function () { const { address, abi } = await importAccountProxy(network.id, network.preset); return new Contract(address, abi, signerOrProvider) as AccountProxyType; diff --git a/liquidity/lib/useAccounts/useAccounts.ts b/liquidity/lib/useAccounts/useAccounts.ts index e92200f55..914809f80 100644 --- a/liquidity/lib/useAccounts/useAccounts.ts +++ b/liquidity/lib/useAccounts/useAccounts.ts @@ -11,7 +11,7 @@ export function useAccounts() { const network = useNetwork(); return useQuery({ - queryKey: [network.name, 'Accounts', { accountAddress: wallet?.address }], + queryKey: [`${network.id}-${network.preset}`, 'Accounts', { accountAddress: wallet?.address }], queryFn: async function () { if (!AccountProxy || !wallet?.address) throw new Error('Should be disabled'); const numberOfAccountTokens = await AccountProxy.balanceOf(wallet.address); diff --git a/liquidity/lib/useAllCollateralPriceIds/useAllCollateralPriceIds.ts b/liquidity/lib/useAllCollateralPriceIds/useAllCollateralPriceIds.ts index aaac70775..d9036e5a7 100644 --- a/liquidity/lib/useAllCollateralPriceIds/useAllCollateralPriceIds.ts +++ b/liquidity/lib/useAllCollateralPriceIds/useAllCollateralPriceIds.ts @@ -6,7 +6,7 @@ import { z } from 'zod'; import { notNil } from '@snx-v3/tsHelpers'; import { useCoreProxy } from '@snx-v3/useCoreProxy'; import { CoreProxyType } from '@synthetixio/v3-contracts'; -import { networksWithERC7412, useNetwork } from '@snx-v3/useBlockchain'; +import { deploymentsWithERC7412, useNetwork } from '@snx-v3/useBlockchain'; import { ZodBigNumber } from '@snx-v3/zod'; import { wei } from '@synthetixio/wei'; @@ -51,14 +51,14 @@ export const useAllCollateralPriceIds = () => { staleTime: Infinity, cacheTime: Infinity, - queryKey: [network.name, 'Collateral Price IDs'], + queryKey: [`${network.id}-${network.preset}`, 'Collateral Price IDs'], queryFn: async () => { if (!CoreProxy || !Multicall3 || !OracleProxy) { throw Error('useAllCollateralPriceIds should not be enabled '); } - if (!networksWithERC7412[network.name]) return []; + if (!deploymentsWithERC7412.includes(`${network.id}-${network.preset}`)) return []; const configs = await loadConfigs({ CoreProxy }); const oracleNodeIds = configs.map((x) => x.oracleNodeId); const calls = oracleNodeIds.map((oracleNodeId) => ({ diff --git a/liquidity/lib/useAllowance/useAllowance.ts b/liquidity/lib/useAllowance/useAllowance.ts index 7ac0b382b..e2037c596 100644 --- a/liquidity/lib/useAllowance/useAllowance.ts +++ b/liquidity/lib/useAllowance/useAllowance.ts @@ -19,7 +19,7 @@ export const useAllowance = ({ return useQuery({ queryKey: [ - network.name, + `${network.id}-${network.preset}`, 'Allowance', { accountAddress: wallet?.address }, { contractAddress, spender }, diff --git a/liquidity/lib/useBlockchain/useBlockchain.tsx b/liquidity/lib/useBlockchain/useBlockchain.tsx index eba47778d..bcad0a87e 100644 --- a/liquidity/lib/useBlockchain/useBlockchain.tsx +++ b/liquidity/lib/useBlockchain/useBlockchain.tsx @@ -10,7 +10,7 @@ import SynthetixLogo from './SynthetixLogo.svg'; export type Network = { id: number; - preset?: string; + preset: string; hexId: string; token: string; name: string; @@ -24,6 +24,7 @@ export type Network = { export const UNSUPPORTED_NETWORK: Network = { id: 0, + preset: 'main', hexId: `0x${Number(0).toString(16)}`, token: 'ETH', name: 'unsupported', @@ -35,9 +36,24 @@ export const UNSUPPORTED_NETWORK: Network = { isTestnet: false, }; -export const NETWORKS: Record = { - mainnet: { +const NETWORK_OPTIMISM: Network = { + id: 10, + preset: 'main', + hexId: `0x${Number(10).toString(16)}`, + token: 'ETH', + name: 'optimism-mainnet', + rpcUrl: `https://optimism-mainnet.infura.io/v3/${INFURA_KEY}`, + label: 'Optimism', + Icon: () => , + isSupported: true, + publicRpcUrl: 'https://mainnet.optimism.io', + isTestnet: false, +}; + +export const NETWORKS: Network[] = [ + { id: 1, + preset: 'main', hexId: `0x${Number(1).toString(16)}`, token: 'ETH', name: 'mainnet', @@ -48,20 +64,10 @@ export const NETWORKS: Record = { publicRpcUrl: 'https://ethereum.publicnode.com', isTestnet: false, }, - 'optimism-mainnet': { - id: 10, - hexId: `0x${Number(10).toString(16)}`, - token: 'ETH', - name: 'optimism-mainnet', - rpcUrl: `https://optimism-mainnet.infura.io/v3/${INFURA_KEY}`, - label: 'Optimism', - Icon: () => , - isSupported: true, - publicRpcUrl: 'https://mainnet.optimism.io', - isTestnet: false, - }, - goerli: { + NETWORK_OPTIMISM, + { id: 5, + preset: 'main', hexId: `0x${Number(5).toString(16)}`, token: 'ETH', name: 'goerli', @@ -72,8 +78,9 @@ export const NETWORKS: Record = { publicRpcUrl: 'https://ethereum-goerli.publicnode.com', isTestnet: true, }, - sepolia: { + { id: 11155111, + preset: 'main', hexId: `0x${Number(11155111).toString(16)}`, token: 'ETH', name: 'sepolia', @@ -84,8 +91,9 @@ export const NETWORKS: Record = { publicRpcUrl: 'https://ethereum-sepolia.publicnode.com', isTestnet: true, }, - 'optimism-goerli': { + { id: 420, + preset: 'main', hexId: `0x${Number(420).toString(16)}`, token: 'ETH', name: 'optimism-goerli', @@ -96,9 +104,9 @@ export const NETWORKS: Record = { publicRpcUrl: 'https://goerli.optimism.io', isTestnet: true, }, - 'base-goerli': { + { id: 84531, - preset: 'competition', + preset: 'main', hexId: `0x${Number(84531).toString(16)}`, token: 'ETH', name: 'base-goerli', @@ -109,37 +117,63 @@ export const NETWORKS: Record = { publicRpcUrl: 'https://base-goerli.publicnode.com', isTestnet: true, }, - cannon: { + { + id: 84531, + preset: 'competition', + hexId: `0x${Number(84531).toString(16)}`, + token: 'ETH', + name: 'base-goerli', + rpcUrl: `https://base-goerli.infura.io/v3/${INFURA_KEY}`, + label: 'Base Goerli (competition)', + Icon: () => , + isSupported: true, + publicRpcUrl: 'https://base-goerli.publicnode.com', + isTestnet: true, + }, + { id: 13370, + preset: 'main', hexId: `0x${Number(13370).toString(16)}`, token: 'ETH', name: 'cannon', rpcUrl: `http://127.0.0.1:8545`, label: 'Cannon', Icon: () => , - isSupported: window.localStorage.getItem('DEFAULT_NETWORK') === 'cannon', + isSupported: window.localStorage.getItem('DEFAULT_NETWORK') === '13370-main', publicRpcUrl: 'http://127.0.0.1:8545', isTestnet: true, }, -}; -export const networksWithERC7412: Record = { - 'base-goerli': true, -}; +]; + +export const deploymentsWithERC7412: string[] = ['84531-competition']; -const DEFAULT_NETWORK_NAME = window.localStorage.getItem('DEFAULT_NETWORK') || 'optimism-mainnet'; export const DEFAULT_NETWORK = - DEFAULT_NETWORK_NAME in NETWORKS ? NETWORKS[DEFAULT_NETWORK_NAME] : NETWORKS['optimism-mainnet']; + NETWORKS.find( + (network) => + `${network.id}-${network.preset}` === window.localStorage.getItem('DEFAULT_NETWORK') + ) ?? NETWORK_OPTIMISM; const injected = injectedModule(); const walletConnect = walletConnectModule({ version: 2, projectId: `${process.env.NEXT_PUBLIC_WC_PROJECT_ID}`, - requiredChains: [NETWORKS['mainnet'].id, NETWORKS['optimism-mainnet'].id], + requiredChains: [1, 10], }); const wallets = [injected, walletConnect]; -const chains = Object.values(NETWORKS).map((network) => ({ +const uniqueChains: Network[] = Object.values( + NETWORKS.reduce((result, network) => { + if (network.id in result) { + return result; + } + Object.assign(result, { + [network.id]: network, + }); + return result; + }, {}) +); +const chains = uniqueChains.map((network) => ({ id: network.hexId, token: network.token, label: network.label, @@ -209,12 +243,13 @@ export const BlockchainProvider: React.FC = ({ children if (currentWallet) { const [chain] = currentWallet.chains; if (chain) { - const selectedNetwork = Object.values(NETWORKS).find( - (network) => network.hexId === chain.id - ); + const selectedNetwork = NETWORKS.find((network) => network.hexId === chain.id); if (selectedNetwork) { setNetwork(selectedNetwork); - window.localStorage.setItem('DEFAULT_NETWORK', selectedNetwork.name); + window.localStorage.setItem( + 'DEFAULT_NETWORK', + `${selectedNetwork.id}-${selectedNetwork.preset}` + ); } } } @@ -256,9 +291,7 @@ export function useNetwork() { ) { return network; } - const connectedChain = Object.values(NETWORKS).find( - (network) => network.hexId === wallet.chains[0].id - ); + const connectedChain = NETWORKS.find((network) => network.hexId === wallet.chains[0].id); if (connectedChain) { return connectedChain; } @@ -271,11 +304,10 @@ export function useSetNetwork() { const hasWallet = Boolean(wallet); return React.useCallback( async (network: Network) => { + setNetwork(network); + window.localStorage.setItem('DEFAULT_NETWORK', `${network.id}-${network.preset}`); if (hasWallet) { await onboard.setChain({ chainId: network.hexId }); - } else { - setNetwork(network); - window.localStorage.setItem('DEFAULT_NETWORK', network.name); } }, [setNetwork, hasWallet] diff --git a/liquidity/lib/useBorrow/useBorrow.tsx b/liquidity/lib/useBorrow/useBorrow.tsx index acd687b61..1b3b8fb19 100644 --- a/liquidity/lib/useBorrow/useBorrow.tsx +++ b/liquidity/lib/useBorrow/useBorrow.tsx @@ -64,7 +64,7 @@ export const useBorrow = ({ ]); const allCalls = collateralPriceCalls.concat(calls); - const erc7412Tx = await withERC7412(provider, allCalls, 'borrow'); + const erc7412Tx = await withERC7412(network, allCalls, 'borrow'); const gasOptionsForTransaction = formatGasPriceForTransaction({ gasLimit: erc7412Tx.gasLimit, diff --git a/liquidity/lib/useCollateralPrices/useCollateralPrices.ts b/liquidity/lib/useCollateralPrices/useCollateralPrices.ts index 9c65a4537..ba016960e 100644 --- a/liquidity/lib/useCollateralPrices/useCollateralPrices.ts +++ b/liquidity/lib/useCollateralPrices/useCollateralPrices.ts @@ -48,14 +48,20 @@ export const useCollateralPrices = () => { return useQuery({ enabled: Boolean(CoreProxy && collateralAddresses && collateralAddresses?.length > 0), - queryKey: [network.name, 'CollateralPrices', { collateralAddresses }], + queryKey: [`${network.id}-${network.preset}`, 'CollateralPrices', { collateralAddresses }], queryFn: async () => { if (!CoreProxy || !collateralAddresses || collateralAddresses.length == 0) { throw 'useCollateralPrices missing required data'; } const { calls, decoder } = await loadPrices({ CoreProxy, collateralAddresses }); - const prices = await erc7412Call(CoreProxy.provider, calls, decoder, 'useCollateralPrices'); + const prices = await erc7412Call( + network, + CoreProxy.provider, + calls, + decoder, + 'useCollateralPrices' + ); return collateralAddresses.reduce((acc: Record, address, i) => { acc[address] = prices[i]; return acc; diff --git a/liquidity/lib/useCollateralTypes/useCollateralTypes.ts b/liquidity/lib/useCollateralTypes/useCollateralTypes.ts index ad2899e2a..3ea352579 100644 --- a/liquidity/lib/useCollateralTypes/useCollateralTypes.ts +++ b/liquidity/lib/useCollateralTypes/useCollateralTypes.ts @@ -80,7 +80,7 @@ export function useCollateralTypes(includeDelegationOff = false) { const { data: Multicall3 } = useMulticall3(); return useQuery({ - queryKey: [network.name, 'CollateralTypes', { includeDelegationOff }], + queryKey: [`${network.id}-${network.preset}`, 'CollateralTypes', { includeDelegationOff }], queryFn: async () => { if (!CoreProxy || !Multicall3) throw Error('Query should not be enabled when contracts missing'); diff --git a/liquidity/lib/useCoreProxy/useCoreProxy.ts b/liquidity/lib/useCoreProxy/useCoreProxy.ts index d9711ccf7..585bbb540 100644 --- a/liquidity/lib/useCoreProxy/useCoreProxy.ts +++ b/liquidity/lib/useCoreProxy/useCoreProxy.ts @@ -11,7 +11,7 @@ export function useCoreProxy() { const withSigner = Boolean(signer); return useQuery({ - queryKey: [network.name, 'CoreProxy', { withSigner }], + queryKey: [`${network.id}-${network.preset}`, 'CoreProxy', { withSigner }], queryFn: async function () { const { address, abi } = await importCoreProxy(network.id, network.preset); return new Contract(address, abi, signerOrProvider) as CoreProxyType; diff --git a/liquidity/lib/useDeposit/useDeposit.tsx b/liquidity/lib/useDeposit/useDeposit.tsx index 4b274e6dc..6d304e9f4 100644 --- a/liquidity/lib/useDeposit/useDeposit.tsx +++ b/liquidity/lib/useDeposit/useDeposit.tsx @@ -93,7 +93,8 @@ export const useDeposit = ({ collateralPriceCallsPromise, ]); const allCalls = collateralPriceCalls.concat(calls); - const erc7412Tx = await withERC7412(provider, allCalls, 'useDeposit'); + + const erc7412Tx = await withERC7412(network, allCalls, 'useDeposit'); const gasOptionsForTransaction = formatGasPriceForTransaction({ gasLimit: erc7412Tx.gasLimit, diff --git a/liquidity/lib/useEthBalance/useEthBalance.ts b/liquidity/lib/useEthBalance/useEthBalance.ts index c78e2aca3..130c85880 100644 --- a/liquidity/lib/useEthBalance/useEthBalance.ts +++ b/liquidity/lib/useEthBalance/useEthBalance.ts @@ -12,7 +12,11 @@ export function useEthBalance(networkId?: number) { const network = useNetwork(); return useQuery({ - queryKey: [network.name, 'EthBalance', { accountAddress: wallet?.address }], + queryKey: [ + `${network.id}-${network.preset}`, + 'EthBalance', + { accountAddress: wallet?.address }, + ], queryFn: async () => { if (!wallet?.address) throw Error('useEthBalance should not be enabled'); const provider = diff --git a/liquidity/lib/useGasPrice/useGasPrice.test.ts b/liquidity/lib/useGasPrice/useGasPrice.test.ts index 2195d1563..ec3c92c77 100644 --- a/liquidity/lib/useGasPrice/useGasPrice.test.ts +++ b/liquidity/lib/useGasPrice/useGasPrice.test.ts @@ -15,7 +15,7 @@ describe('useGasPrice', () => { getBlock: jest.fn(() => ({})), getGasPrice: jest.fn(() => wei(2, GWEI_DECIMALS).toBN()), }; - useNetwork = jest.fn(() => ({ id: 10, name: 'optimism-mainnet' })); + useNetwork = jest.fn(() => ({ id: 10, name: 'optimism-mainnet', preset: 'main' })); useProvider = jest.fn(() => provider); reactQuery = { @@ -38,14 +38,14 @@ describe('useGasPrice', () => { }); test('Returns gas prices for mainnet', async () => { - useNetwork.mockReturnValue({ id: 1, name: 'mainnet' }); + useNetwork.mockReturnValue({ id: 1, name: 'mainnet', preset: 'main' }); provider.getBlock.mockReturnValue({ baseFeePerGas: wei(2, GWEI_DECIMALS).toBN() }); const result = useGasPrice(); const { queryKey, queryFn, enabled } = reactQuery.useQuery.mock.lastCall[0]; expect(result.data).toEqual(undefined); - expect(queryKey).toEqual(['mainnet', 'GasPrice']); + expect(queryKey).toEqual(['1-main', 'GasPrice']); expect(enabled).toEqual(true); const queryResult = await queryFn(); @@ -56,7 +56,7 @@ describe('useGasPrice', () => { const result = useGasPrice(); const { queryKey, queryFn, enabled } = reactQuery.useQuery.mock.lastCall[0]; expect(result.data).toEqual(undefined); - expect(queryKey).toEqual(['optimism-mainnet', 'GasPrice']); + expect(queryKey).toEqual(['10-main', 'GasPrice']); expect(enabled).toEqual(true); const queryResult = await queryFn(); expect(provider.getGasPrice).toBeCalled(); diff --git a/liquidity/lib/useGasPrice/useGasPrice.ts b/liquidity/lib/useGasPrice/useGasPrice.ts index ba54705da..a0bcd5c0e 100644 --- a/liquidity/lib/useGasPrice/useGasPrice.ts +++ b/liquidity/lib/useGasPrice/useGasPrice.ts @@ -37,7 +37,7 @@ export const useGasPrice = () => { return useQuery({ enabled: Boolean(provider), - queryKey: [network.name, 'GasPrice'], + queryKey: [`${network.id}-${network.preset}`, 'GasPrice'], queryFn: () => getGasPrice({ provider }), }); }; diff --git a/liquidity/lib/useLiquidityPosition/useLiquidityPosition.ts b/liquidity/lib/useLiquidityPosition/useLiquidityPosition.ts index d3f9da589..4d2465a47 100644 --- a/liquidity/lib/useLiquidityPosition/useLiquidityPosition.ts +++ b/liquidity/lib/useLiquidityPosition/useLiquidityPosition.ts @@ -79,7 +79,7 @@ export const useLiquidityPosition = ({ const network = useNetwork(); return useQuery({ queryKey: [ - network.name, + `${network.id}-${network.preset}`, 'LiquidityPosition', { accountId }, { @@ -128,6 +128,7 @@ export const useLiquidityPosition = ({ ); return await erc7412Call( + network, CoreProxy.provider, allCalls, (encoded) => { diff --git a/liquidity/lib/useLiquidityPositions/useLiquidityPositions.ts b/liquidity/lib/useLiquidityPositions/useLiquidityPositions.ts index 8adceae51..5beab555e 100644 --- a/liquidity/lib/useLiquidityPositions/useLiquidityPositions.ts +++ b/liquidity/lib/useLiquidityPositions/useLiquidityPositions.ts @@ -45,9 +45,9 @@ export const useLiquidityPositions = ({ accountId }: { accountId?: string }) => return useQuery({ queryKey: [ - network.name, - { accountId }, + `${network.id}-${network.preset}`, 'LiquidityPositions', + { accountId }, { pools: pools ? pools.map((pool) => pool.id).sort() : [], tokens: collateralTypes ? collateralTypes.map((x) => x.tokenAddress).sort() : [], @@ -87,6 +87,7 @@ export const useLiquidityPositions = ({ accountId }: { accountId?: string }) => const allCalls = collateralPriceCalls.concat(priceCalls.concat(positionCalls)); const singlePositionDecoder = positionCallsAndData.at(0)?.decoder; return await erc7412Call( + network, CoreProxy.provider, allCalls, (encoded) => { diff --git a/liquidity/lib/useMarketNamesById/useMarketNamesById.ts b/liquidity/lib/useMarketNamesById/useMarketNamesById.ts index 89eec00b0..e36a764bb 100644 --- a/liquidity/lib/useMarketNamesById/useMarketNamesById.ts +++ b/liquidity/lib/useMarketNamesById/useMarketNamesById.ts @@ -16,7 +16,7 @@ export const useMarketNamesById = ( const network = useNetwork(); return useQuery({ queryKey: [ - network.name, + `${network.id}-${network.preset}`, 'MarketNamesById', { markets: marketIdsAndAddresses diff --git a/liquidity/lib/useMulticall3/useMulticall3.ts b/liquidity/lib/useMulticall3/useMulticall3.ts index dfba3bee7..be3c3fb8b 100644 --- a/liquidity/lib/useMulticall3/useMulticall3.ts +++ b/liquidity/lib/useMulticall3/useMulticall3.ts @@ -11,7 +11,7 @@ export function useMulticall3() { const withSigner = Boolean(signer); return useQuery({ - queryKey: [network.name, 'Multicall3', { withSigner }], + queryKey: [`${network.id}-${network.preset}`, 'Multicall3', { withSigner }], queryFn: async function () { const { address, abi } = await importMulticall3(network.id, network.preset); return new Contract(address, abi, signerOrProvider) as Multicall3Type; diff --git a/liquidity/lib/useOracleManagerProxy/useOracleManagerProxy.ts b/liquidity/lib/useOracleManagerProxy/useOracleManagerProxy.ts index a1eee2a7c..a93af04cf 100644 --- a/liquidity/lib/useOracleManagerProxy/useOracleManagerProxy.ts +++ b/liquidity/lib/useOracleManagerProxy/useOracleManagerProxy.ts @@ -11,7 +11,7 @@ export function useOracleManagerProxy() { const withSigner = Boolean(signer); return useQuery({ - queryKey: [network.name, 'OracleManagerProxy', { withSigner }], + queryKey: [`${network.id}-${network.preset}`, 'OracleManagerProxy', { withSigner }], queryFn: async function () { const { address, abi } = await importOracleManagerProxy(network.id, network.preset); return new Contract(address, abi, signerOrProvider) as OracleManagerProxyType; diff --git a/liquidity/lib/usePoolConfiguration/usePoolConfiguration.ts b/liquidity/lib/usePoolConfiguration/usePoolConfiguration.ts index 41af961a4..d87fa9cff 100644 --- a/liquidity/lib/usePoolConfiguration/usePoolConfiguration.ts +++ b/liquidity/lib/usePoolConfiguration/usePoolConfiguration.ts @@ -28,7 +28,7 @@ export const usePoolConfiguration = (poolId?: string) => { return useQuery({ enabled: Boolean(CoreProxy && poolId && collateralPriceUpdates), - queryKey: [network.name, 'PoolConfiguration', { poolId }], + queryKey: [`${network.id}-${network.preset}`, 'PoolConfiguration', { poolId }], queryFn: async () => { if (!CoreProxy || !poolId || !collateralPriceUpdates) { throw Error('usePoolConfiguration should not be enabled'); @@ -48,6 +48,7 @@ export const usePoolConfiguration = (poolId?: string) => { markets.map((m) => CoreProxy.populateTransaction.isMarketCapacityLocked(m.id)) ); const decoded = await erc7412Call( + network, CoreProxy.provider, collateralPriceCalls.concat(calls), (encoded) => { diff --git a/liquidity/lib/usePoolData/usePoolData.tsx b/liquidity/lib/usePoolData/usePoolData.tsx index 898645726..c445ec825 100644 --- a/liquidity/lib/usePoolData/usePoolData.tsx +++ b/liquidity/lib/usePoolData/usePoolData.tsx @@ -165,7 +165,7 @@ export const usePoolData = (poolId?: string) => { const network = useNetwork(); return useQuery({ - queryKey: [network.name, 'Pool', { pool: poolId }], + queryKey: [`${network.id}-${network.preset}`, 'Pool', { pool: poolId }], queryFn: async () => { if (!poolId) throw Error('OMG!'); const poolData = await getPoolData(network.name, poolId); diff --git a/liquidity/lib/usePools/usePools.ts b/liquidity/lib/usePools/usePools.ts index 53492f9e2..80b61aa1c 100644 --- a/liquidity/lib/usePools/usePools.ts +++ b/liquidity/lib/usePools/usePools.ts @@ -23,7 +23,7 @@ export function usePools() { return useQuery({ enabled: Boolean(CoreProxy), - queryKey: [network.name, 'Pools'], + queryKey: [`${network.id}-${network.preset}`, 'Pools'], queryFn: async () => { if (!CoreProxy) throw 'usePools is missing required data'; diff --git a/liquidity/lib/useRepay/useRepay.tsx b/liquidity/lib/useRepay/useRepay.tsx index ca1515163..8ab6fc1ac 100644 --- a/liquidity/lib/useRepay/useRepay.tsx +++ b/liquidity/lib/useRepay/useRepay.tsx @@ -95,7 +95,7 @@ export const useRepay = ({ ]); const allCalls = collateralPriceCalls.concat(calls); - const erc7412Tx = await withERC7412(provider, allCalls, 'useRepay'); + const erc7412Tx = await withERC7412(network, allCalls, 'useRepay'); const gasOptionsForTransaction = formatGasPriceForTransaction({ gasLimit: erc7412Tx.gasLimit, diff --git a/liquidity/lib/useRewards/useRewards.ts b/liquidity/lib/useRewards/useRewards.ts index ecd54ec63..75a4f69ff 100644 --- a/liquidity/lib/useRewards/useRewards.ts +++ b/liquidity/lib/useRewards/useRewards.ts @@ -68,13 +68,11 @@ export function useRewards( Multicall3 && CoreProxy && distributors && poolId && collateralAddress && accountId ), queryKey: [ + `${network.id}-${network.preset}`, 'Rewards', - network.name, - { - distributors, - accountId, - collateralAddress, - }, + { accountId }, + { collateralAddress }, + { distributors }, ], queryFn: async () => { if ( diff --git a/liquidity/lib/useTokenBalance/useTokenBalance.ts b/liquidity/lib/useTokenBalance/useTokenBalance.ts index 8a5ec2ee7..36718ff10 100644 --- a/liquidity/lib/useTokenBalance/useTokenBalance.ts +++ b/liquidity/lib/useTokenBalance/useTokenBalance.ts @@ -17,7 +17,12 @@ export const useTokenBalance = (address?: string, networkId?: number) => { const tokenAddress = assertAddressType(address) ? address : undefined; const networkIdToUse = networkId ?? network.id; return useQuery({ - queryKey: [network.name, 'TokenBalance', { accountAddress: wallet?.address }, { tokenAddress }], + queryKey: [ + `${network.id}-${network.preset}`, + 'TokenBalance', + { accountAddress: wallet?.address }, + { tokenAddress }, + ], queryFn: async () => { if (!tokenAddress || !wallet?.address) throw Error('Query should not be enabled'); const provider = diff --git a/liquidity/lib/useTransferableSynthetix/useTransferableSynthetix.ts b/liquidity/lib/useTransferableSynthetix/useTransferableSynthetix.ts index 57cd3188f..9c89a0b38 100644 --- a/liquidity/lib/useTransferableSynthetix/useTransferableSynthetix.ts +++ b/liquidity/lib/useTransferableSynthetix/useTransferableSynthetix.ts @@ -15,7 +15,11 @@ export function useTransferableSynthetix() { return useQuery({ enabled: Boolean(provider && accountAddress && snxAddress), - queryKey: [network.name, 'TransferableSynthetix', { address: account?.address }], + queryKey: [ + `${network.id}-${network.preset}`, + 'TransferableSynthetix', + { address: account?.address }, + ], queryFn: async function (): Promise<{ transferable: Wei; collateral?: Wei }> { if (!(provider && accountAddress && snxAddress)) { throw 'useTransferableSynthetix should not be enabled'; diff --git a/liquidity/lib/useUSDProxy/useUSDProxy.ts b/liquidity/lib/useUSDProxy/useUSDProxy.ts index cc5116535..6efcf5f01 100644 --- a/liquidity/lib/useUSDProxy/useUSDProxy.ts +++ b/liquidity/lib/useUSDProxy/useUSDProxy.ts @@ -4,10 +4,8 @@ import type { JsonRpcProvider } from '@ethersproject/providers'; import { useNetwork, useProvider, useSigner, NETWORKS } from '@snx-v3/useBlockchain'; import { USDProxyType, importUSDProxy } from '@synthetixio/v3-contracts'; -const networks = Object.values(NETWORKS); - export function useUSDProxy(nonConnectedProvider?: JsonRpcProvider) { - const network = useNetwork(); + const connectedNetwork = useNetwork(); const provider = useProvider(); const signer = useSigner(); @@ -15,12 +13,13 @@ export function useUSDProxy(nonConnectedProvider?: JsonRpcProvider) { const signerOrProvider = signer || providerToUse; const withSigner = Boolean(signer); - const net = networks.find((n) => n.id === nonConnectedProvider?.network.chainId) ?? network; + const network = + NETWORKS.find((n) => n.id === nonConnectedProvider?.network.chainId) ?? connectedNetwork; return useQuery({ - queryKey: [net.name, 'USDProxy', { withSigner }], + queryKey: [`${network.id}-${network.preset}`, 'USDProxy', { withSigner }], queryFn: async function () { - const { address, abi } = await importUSDProxy(net.id, net.preset); + const { address, abi } = await importUSDProxy(network.id, network.preset); return new Contract(address, abi, signerOrProvider) as USDProxyType; }, enabled: Boolean(signerOrProvider), diff --git a/liquidity/lib/useUndelegate/useUndelegate.tsx b/liquidity/lib/useUndelegate/useUndelegate.tsx index 0729c94cf..86918bbd3 100644 --- a/liquidity/lib/useUndelegate/useUndelegate.tsx +++ b/liquidity/lib/useUndelegate/useUndelegate.tsx @@ -64,7 +64,7 @@ export const useUndelegate = ({ ]); const allCalls = collateralPriceCalls.concat(calls); - const erc7412Tx = await withERC7412(provider, allCalls, 'useUndelegate'); + const erc7412Tx = await withERC7412(network, allCalls, 'useUndelegate'); const gasOptionsForTransaction = formatGasPriceForTransaction({ gasLimit: erc7412Tx.gasLimit, diff --git a/liquidity/lib/useVaultsData/useVaultsData.ts b/liquidity/lib/useVaultsData/useVaultsData.ts index 1f6e119dd..0edf7d19f 100644 --- a/liquidity/lib/useVaultsData/useVaultsData.ts +++ b/liquidity/lib/useVaultsData/useVaultsData.ts @@ -22,7 +22,7 @@ export const useVaultsData = (poolId?: number) => { return useQuery({ queryKey: [ - network.name, + `${network.id}-${network.preset}`, 'VaultCollaterals', { pool: poolId, @@ -56,6 +56,7 @@ export const useVaultsData = (poolId?: number) => { const calls = await Promise.all([collateralPriceUpdateCallsP, collateralCallsP, debtCallsP]); return await erc7412Call( + network, CoreProxyContract.provider, calls.flat(), (multicallResult) => { diff --git a/liquidity/lib/useWithdraw/useWithdraw.tsx b/liquidity/lib/useWithdraw/useWithdraw.tsx index c9cbb2d53..0573cc192 100644 --- a/liquidity/lib/useWithdraw/useWithdraw.tsx +++ b/liquidity/lib/useWithdraw/useWithdraw.tsx @@ -69,7 +69,7 @@ export const useWithdraw = ({ ]); const allCalls = collateralPriceCalls.concat(populatedTxn); - const erc7412Tx = await withERC7412(provider, allCalls, 'useWithdraw'); + const erc7412Tx = await withERC7412(network, allCalls, 'useWithdraw'); const gasOptionsForTransaction = formatGasPriceForTransaction({ gasLimit: erc7412Tx.gasLimit, diff --git a/liquidity/lib/withERC7412/withERC7412.ts b/liquidity/lib/withERC7412/withERC7412.ts index 6b5ec95c1..6df8495fb 100644 --- a/liquidity/lib/withERC7412/withERC7412.ts +++ b/liquidity/lib/withERC7412/withERC7412.ts @@ -4,7 +4,7 @@ import { EvmPriceServiceConnection } from '@pythnetwork/pyth-evm-js'; import { z } from 'zod'; import { ZodBigNumber } from '@snx-v3/zod'; import { offchainMainnetEndpoint, offchainTestnetEndpoint } from '@snx-v3/constants'; -import { NETWORKS, networksWithERC7412 } from '@snx-v3/useBlockchain'; +import { deploymentsWithERC7412, Network } from '@snx-v3/useBlockchain'; import type { Modify } from '@snx-v3/tsHelpers'; import { importCoreProxy, importMulticall3 } from '@synthetixio/v3-contracts'; import { withMemoryCache } from './withMemoryCache'; @@ -146,7 +146,7 @@ const parseError = async (error: any, provider: providers.JsonRpcProvider) => { // simulate w/ wETH contract because it will have eth balance // This is useful when we do read/static calls but still need an balance for the price update // TODO: this probably need to be network aware, maybe look into a different solution even. -const getDefaultFromAddress = (chainName: keyof typeof NETWORKS) => { +const getDefaultFromAddress = (chainName: string) => { switch (chainName) { case 'cannon': return '0x4200000000000000000000000000000000000006'; // TODO, unclear what to put here @@ -170,7 +170,7 @@ const getDefaultFromAddress = (chainName: keyof typeof NETWORKS) => { * If a tx requires ERC7412 pattern, wrap your tx with this function. */ export const withERC7412 = async ( - _provider: ethers.providers.Provider, + network: Network, tx: TransactionRequest | TransactionRequest[], logLabel?: string ): Promise => { @@ -187,21 +187,16 @@ export const withERC7412 = async ( const from = multicallCalls[0].from as string; - const { chainId } = await _provider.getNetwork(); - - const network = Object.values(NETWORKS).find((x) => x.id === chainId); - const networkName = network?.name || 'mainnet'; const jsonRpcProvider = new ethers.providers.JsonRpcProvider(network?.rpcUrl); // Make sure we're always using JSONRpcProvider, the web3 provider coming from the signer might have bugs causing errors to miss revert data // If from is set to the default address (wETH) we can assume it's a read rather than a write - const isRead = from === getDefaultFromAddress(networkName); - const isTestnet = network?.isTestnet || false; - const networkHaveERC7412 = networksWithERC7412[networkName] || false; + const isRead = from === getDefaultFromAddress(network.name); + const networkHaveERC7412 = deploymentsWithERC7412.includes(`${network.id}-${network.preset}`); const useCoreProxy = !networkHaveERC7412 && !isRead; const { address: multicallAddress, abi: multiCallAbi } = useCoreProxy - ? await importCoreProxy(network?.id || 1, network?.preset) - : await importMulticall3(network?.id || 1, network?.preset); + ? await importCoreProxy(network.id, network.preset) + : await importMulticall3(network.id, network.preset); while (true) { try { @@ -235,7 +230,7 @@ export const withERC7412 = async ( const ignoreCache = !isRead; const signedRequiredData = await fetchOffchainData( oracleQuery, - isTestnet, + network.isTestnet, logLabel || '', ignoreCache ? 'no-cache' : undefined ); @@ -277,24 +272,22 @@ export const withERC7412 = async ( * This can be used to do reads plus decoding. The return type will be whatever the type of the decode function is. And the arguments passed will have the multicall decoded and price updates removed */ export async function erc7412Call( + network: Network, provider: ethers.providers.Provider, txRequests: TransactionRequest | TransactionRequest[], decode: (x: string[] | string) => T, logLabel?: string ) { - const { chainId } = await provider.getNetwork(); - const network = Object.values(NETWORKS).find((x) => x.id === chainId); const { address: multicallAddress, abi: multicallAbi } = await importMulticall3( - network?.id || 1, - network?.preset + network.id, + network.preset ); const reqs = [txRequests].flat(); for (const txRequest of reqs) { - txRequest.from = getDefaultFromAddress(network?.name || 'mainnet'); // Reads can always use WETH + txRequest.from = getDefaultFromAddress(network.name); // Reads can always use WETH } - const jsonRpcProvider = new ethers.providers.JsonRpcProvider(network?.rpcUrl); // Make sure we're always using JSONRpcProvider, the web3 provider coming from the signer might have bugs causing errors to miss revert data - const newCall = await withERC7412(jsonRpcProvider, reqs, logLabel); + const newCall = await withERC7412(network, reqs, logLabel); const res = await provider.call(newCall); diff --git a/liquidity/ui/src/layouts/Default/NetworkController.tsx b/liquidity/ui/src/layouts/Default/NetworkController.tsx index 5705fbc00..4866c14d2 100644 --- a/liquidity/ui/src/layouts/Default/NetworkController.tsx +++ b/liquidity/ui/src/layouts/Default/NetworkController.tsx @@ -42,20 +42,17 @@ export function NetworkController() { - {Object.values(NETWORKS) - .filter((network) => network.isSupported) - .map((network) => ( - setNetwork(network)} - > - - - {network.label} - - - ))} + {NETWORKS.filter((network) => network.isSupported).map((network) => ( + setNetwork(network)} + > + + + {network.label} + + + ))} )} diff --git a/liquidity/ui/src/pages/AccountPositionPage/Rewards/RewardRate.tsx b/liquidity/ui/src/pages/AccountPositionPage/Rewards/RewardRate.tsx index 7560c66f3..6c34bc487 100644 --- a/liquidity/ui/src/pages/AccountPositionPage/Rewards/RewardRate.tsx +++ b/liquidity/ui/src/pages/AccountPositionPage/Rewards/RewardRate.tsx @@ -25,6 +25,7 @@ export function RewardRate({ const { data: CoreProxy } = useCoreProxy(); const { data: rewardRate, isLoading } = useQuery({ queryKey: [ + `${network.id}-${network.preset}`, 'RewardRate', { poolId, diff --git a/liquidity/ui/src/pages/AccountPositionPage/Rewards/useRewards.ts b/liquidity/ui/src/pages/AccountPositionPage/Rewards/useRewards.ts index b1324ed8d..1e8113ee5 100644 --- a/liquidity/ui/src/pages/AccountPositionPage/Rewards/useRewards.ts +++ b/liquidity/ui/src/pages/AccountPositionPage/Rewards/useRewards.ts @@ -21,6 +21,7 @@ export const useRewards = ({ return useQuery({ queryKey: [ + `${network.id}-${network.preset}`, 'Rewards', { accountId, diff --git a/liquidity/ui/src/pages/Teleporter/Teleporter.tsx b/liquidity/ui/src/pages/Teleporter/Teleporter.tsx index cdc093cec..ab282f840 100644 --- a/liquidity/ui/src/pages/Teleporter/Teleporter.tsx +++ b/liquidity/ui/src/pages/Teleporter/Teleporter.tsx @@ -32,7 +32,7 @@ import Wei, { wei } from '@synthetixio/wei'; import { HomeLink } from '@snx-v3/HomeLink'; import { providers } from 'ethers'; -const NETWORKS_ARRAY = Object.values(NETWORKS).filter((network) => network.isSupported); +const SUPPORTED_NETWORKS = NETWORKS.filter((network) => network.isSupported); export const TeleporterUi: FC<{ connectedWallet?: string; @@ -115,7 +115,7 @@ export const TeleporterUi: FC<{ - {NETWORKS_ARRAY.filter((item) => item.name !== 'goerli') + {SUPPORTED_NETWORKS.filter((item) => item.name !== 'goerli') .filter((chain) => chain.id !== activeNetwork.id) .map((chain) => { return ( @@ -213,7 +213,7 @@ export const TeleporterUi: FC<{ - {NETWORKS_ARRAY.filter((item) => item.name !== 'goerli') + {SUPPORTED_NETWORKS.filter((item) => item.name !== 'goerli') .filter((chain) => chain.id !== activeNetwork.id) .filter((chain) => activeNetwork.isTestnet ? chain.isTestnet : !chain.isTestnet