diff --git a/hardhat.config.ts b/hardhat.config.ts index 402502cd..05e2eedc 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -10,6 +10,8 @@ const config: HardhatUserConfig = { forking: { url: process.env.PROVIDER_URL!, // Replace with your actual Alchemy/Infura URL }, + // Can't dynamically switch chain between tests, very inflexible, "hardhat_reset" doesn't work + chainId: 1, // Optional forking configurations (e.g., block number): // blockNumber: 12345678, }, diff --git a/tests/helpers/hardhat.ts b/tests/helpers/hardhat.ts new file mode 100644 index 00000000..bc102342 --- /dev/null +++ b/tests/helpers/hardhat.ts @@ -0,0 +1,91 @@ +import hre from 'hardhat'; +import type { EthereumProvider } from 'hardhat/types'; + +interface ForkChainInput { + rpcUrl?: string; + blockNumber?: number; + chainId?: number; +} + +interface SetBalanceInput { + address: string; + balance: number | bigint; +} + +interface ForkChainResult { + startFork: (options?: ForkChainInput) => Promise; + setBalance: (options: SetBalanceInput) => Promise; + impersonateAccount: (address: string) => Promise; + provider: EthereumProvider; + setupFork: (options: { + fork?: ForkChainInput; + accounts?: SetBalanceInput[]; + }) => Promise; +} + +export function forkChain(): ForkChainResult { + const startFork: ForkChainResult['startFork'] = async ({ + rpcUrl = process.env.PROVIDER_URL!, + blockNumber, + chainId, + } = {}) => { + await hre.network.provider.request({ + // forks chain + method: 'hardhat_reset', + params: [ + { + forking: { + jsonRpcUrl: rpcUrl, + // Optionally, specify the block number + // blockNumber: 12345678, + blockNumber, + chainId, + }, + // chainId: 1, // Set to Ethereum Mainnet's chainId + chainId, + }, + ], + }); + }; + + const impersonateAccount: ForkChainResult['impersonateAccount'] = async ( + address + ) => { + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [address], + }); + }; + + const setBalance: ForkChainResult['setBalance'] = async ({ + address, + balance, + }) => { + await hre.network.provider.send('hardhat_setBalance', [ + address, + `0x${balance.toString(16)}`, + ]); + }; + + const setupFork: ForkChainResult['setupFork'] = async ({ + fork, + accounts, + }) => { + await startFork(fork); + + if (accounts) { + for (const accountSetup of accounts) { + await setBalance(accountSetup); + await impersonateAccount(accountSetup.address); + } + } + }; + + return { + startFork, + provider: hre.network.provider, + setBalance, + impersonateAccount, + setupFork, + }; +} diff --git a/tests/legacy.test.ts b/tests/legacy.test.ts index 4803edd9..97c974eb 100644 --- a/tests/legacy.test.ts +++ b/tests/legacy.test.ts @@ -14,8 +14,8 @@ import BigNumber from 'bignumber.js'; import { APIError } from '../src/legacy'; import erc20abi from './abi/ERC20.json'; -import ganache from 'ganache'; import { assert } from 'ts-essentials'; +import { forkChain } from './helpers/hardhat'; dotenv.config(); @@ -37,26 +37,11 @@ const referrer = 'sdk-test'; const wallet = ethers.Wallet.createRandom(); -const ganacheProvider = ganache.provider({ - wallet: { - accounts: [{ balance: 8e18, secretKey: wallet.privateKey }], - }, - fork: { - url: PROVIDER_URL, - }, - chain: { - chainId: 1, - }, - logging: { - quiet: true, - }, -}); +const { provider, setupFork } = forkChain(); -const provider = new Web3(ganacheProvider as any); +const web3Provider = new Web3(provider as any); -const ethersProvider = new ethers.providers.Web3Provider( - ganacheProvider as any -); +const ethersProvider = new ethers.providers.Web3Provider(provider as any); const signer = wallet.connect(ethersProvider); const senderAddress = signer.address; @@ -65,8 +50,11 @@ describe('ParaSwap SDK', () => { let paraSwap: ParaSwap; beforeAll(async () => { + await setupFork({ + accounts: [{ address: senderAddress, balance: 8e18 }], + }); paraSwap = new ParaSwap({ chainId, fetch, version: '5' }).setWeb3Provider( - provider + web3Provider ); }); @@ -145,7 +133,7 @@ describe('ParaSwap SDK', () => { test('Get_Spender', async () => { const spender = await paraSwap.getTokenTransferProxy(); - expect(provider.utils.isAddress(spender as string)); + expect(web3Provider.utils.isAddress(spender as string)); }); test('Get_Allowance', async () => { diff --git a/tests/limitOrders.test.ts b/tests/limitOrders.test.ts index 8d2fc5e2..34f7effb 100644 --- a/tests/limitOrders.test.ts +++ b/tests/limitOrders.test.ts @@ -46,12 +46,11 @@ import { bytecode as ERC20MintableBytecode } from './bytecode/ERC20Mintable.json import AugustusRFQAbi from './abi/AugustusRFQ.json'; import { bytecode as AugustusRFQBytecode } from './bytecode/AugustusRFQ.json'; -import ganache from 'ganache'; - import type { BuildLimitOrderInput } from '../src/methods/limitOrders/buildOrder'; import { assert } from 'ts-essentials'; import { ZERO_ADDRESS } from '../src/methods/common/orders/buildOrderData'; import { buyErc20TokenForEth } from './helpers'; +import { forkChain } from './helpers/hardhat'; dotenv.config(); @@ -85,28 +84,13 @@ const walletStable2 = ethers.Wallet.fromMnemonic( "m/44'/60'/0'/0/1" ); -const ganacheProvider = ganache.provider({ - wallet: { - accounts: [ - { balance: 80e18, secretKey: walletStable.privateKey }, - { balance: 80e18, secretKey: walletStable2.privateKey }, - ], - }, - fork: { - url: PROVIDER_URL, - }, - chain: { - chainId, - }, - logging: { - quiet: true, - }, -}); +const { provider, setupFork } = forkChain(); + // if test against tenderly fork, make sure accounts have enough ETH and zero nonce const tenderlyForkUrl = process.env.TENDERLY_FORK_URL; const ethersProvider = tenderlyForkUrl ? new ethers.providers.JsonRpcProvider(tenderlyForkUrl) - : new ethers.providers.Web3Provider(ganacheProvider as any); + : new ethers.providers.Web3Provider(provider as any); const signer = walletStable.connect(ethersProvider); const senderAddress = signer.address; @@ -131,7 +115,7 @@ const takerEthersContractCaller = constructEthersContractCaller( walletStable2.address ); -const web3provider = new Web3(ganacheProvider as any); +const web3provider = new Web3(provider as any); const web3ContractCaller = constructWeb3ContractCaller( web3provider, @@ -298,6 +282,13 @@ describe('Limit Orders', () => { // let initialChainId2verifyingContract = { ...chainId2verifyingContract }; beforeAll(async () => { + await setupFork({ + accounts: [ + { balance: 80e18, address: walletStable.address }, + { balance: 80e18, address: walletStable2.address }, + ], + }); + orderInput = { nonce: 1, expiry: orderExpiry, diff --git a/tests/nftOrders.test.ts b/tests/nftOrders.test.ts index 7293b029..77629c58 100644 --- a/tests/nftOrders.test.ts +++ b/tests/nftOrders.test.ts @@ -48,8 +48,6 @@ import { bytecode as ERC721MintableBytecode } from './bytecode/ERC721Mintable.js import AugustusRFQAbi from './abi/AugustusRFQ.json'; import { bytecode as AugustusRFQBytecode } from './bytecode/AugustusRFQ.json'; -import ganache from 'ganache'; - import { BuildNFTOrderInput, SignableNFTOrderData, @@ -57,6 +55,7 @@ import { import { assert } from 'ts-essentials'; import { ZERO_ADDRESS } from '../src/methods/common/orders/buildOrderData'; import { buyErc20TokenForEth } from './helpers'; +import { forkChain } from './helpers/hardhat'; dotenv.config(); @@ -91,35 +90,13 @@ const walletStable2 = ethers.Wallet.fromMnemonic( "m/44'/60'/0'/0/1" ); -const ganacheProvider = ganache.provider({ - wallet: { - accounts: [ - { - balance: '0x' + new BigNumber(1000).multipliedBy(10 ** 18).toString(16), - secretKey: walletStable.privateKey, - }, - { - balance: '0x' + new BigNumber(1000).multipliedBy(10 ** 18).toString(16), - secretKey: walletStable2.privateKey, - }, - ], - }, - fork: { - url: process.env.PROVIDER_URL, - }, - chain: { - chainId, - }, - logging: { - quiet: true, - }, -}); +const { provider, setupFork } = forkChain(); // if test against tenderly fork, make sure accounts have enough ETH and zero nonce const tenderlyForkUrl = process.env.TENDERLY_FORK_URL; const ethersProvider = tenderlyForkUrl ? new ethers.providers.JsonRpcProvider(tenderlyForkUrl) - : new ethers.providers.Web3Provider(ganacheProvider as any); + : new ethers.providers.Web3Provider(provider as any); const signer = walletStable.connect(ethersProvider); const senderAddress = signer.address; @@ -143,7 +120,7 @@ const takerEthersContractCaller = constructEthersContractCaller( walletStable2.address ); -const web3provider = new Web3(ganacheProvider as any); +const web3provider = new Web3(provider as any); const web3ContractCaller = constructWeb3ContractCaller( web3provider, @@ -320,6 +297,13 @@ describe('NFT Orders', () => { // let initialChainId2verifyingContract = { ...chainId2verifyingContract }; beforeAll(async () => { + await setupFork({ + accounts: [ + { balance: 1000e18, address: walletStable.address }, + { balance: 1000e18, address: walletStable2.address }, + ], + }); + orderInput = { nonce: 1, expiry: orderExpiry, diff --git a/tests/partialSdk.test.ts b/tests/partialSdk.test.ts index f00160d9..1fb3a1ce 100644 --- a/tests/partialSdk.test.ts +++ b/tests/partialSdk.test.ts @@ -36,13 +36,13 @@ import BigNumber from 'bignumber.js'; import erc20abi from './abi/ERC20.json'; -import ganache from 'ganache'; import { assert } from 'ts-essentials'; import type { ContractCallerFunctions, StaticContractCallerFn, TransactionContractCallerFn, } from '../src/types'; +import { forkChain } from './helpers/hardhat'; dotenv.config(); @@ -67,26 +67,11 @@ const referrer = 'sdk-test'; const wallet = ethers.Wallet.createRandom(); -const ganacheProvider = ganache.provider({ - wallet: { - accounts: [{ balance: 8e18, secretKey: wallet.privateKey }], - }, - fork: { - url: PROVIDER_URL, - }, - chain: { - chainId: 1, - }, - logging: { - quiet: true, - }, -}); +const { setBalance, provider, startFork, impersonateAccount } = forkChain(); -const web3provider = new Web3(ganacheProvider as any); +const web3provider = new Web3(provider as any); -const ethersProvider = new ethers.providers.Web3Provider( - ganacheProvider as any -); +const ethersProvider = new ethers.providers.Web3Provider(provider as any); const fetchFetcher = constructFetchFetcher(fetch); const axiosFetcher = constructAxiosFetcher(axios); @@ -108,7 +93,7 @@ const web3ContractCaller = constructWeb3ContractCaller( ); const customGanacheContractCaller = constructProviderOnlyContractCaller( - ganacheProvider, + provider, senderAddress ); @@ -124,7 +109,11 @@ describe.each([ BuildTxFunctions & GetSwapTxFunctions; - beforeAll(() => { + beforeAll(async () => { + await startFork({ chainId }); + await setBalance({ address: senderAddress, balance: 8e18 }); + await impersonateAccount(senderAddress); + paraSwap = constructPartialSDK( { chainId, fetcher, version: '5' }, constructGetBalances, diff --git a/tests/simpleSdk.test.ts b/tests/simpleSdk.test.ts index bd6dcf5b..15bccee4 100644 --- a/tests/simpleSdk.test.ts +++ b/tests/simpleSdk.test.ts @@ -8,10 +8,10 @@ import BigNumber from 'bignumber.js'; import erc20abi from './abi/ERC20.json'; -import ganache from 'ganache'; import { assert } from 'ts-essentials'; import { constructSimpleSDK, SimpleSDK } from '../src/sdk/simple'; +import { forkChain } from './helpers/hardhat'; dotenv.config(); @@ -36,26 +36,11 @@ const referrer = 'sdk-test'; const wallet = ethers.Wallet.createRandom(); -const ganacheProvider = ganache.provider({ - wallet: { - accounts: [{ balance: 8e18, secretKey: wallet.privateKey }], - }, - fork: { - url: PROVIDER_URL, - }, - chain: { - chainId: 1, - }, - logging: { - quiet: true, - }, -}); +const { setBalance, provider, startFork } = forkChain(); -const web3provider = new Web3(ganacheProvider as any); +const web3provider = new Web3(provider as any); -const ethersProvider = new ethers.providers.Web3Provider( - ganacheProvider as any -); +const ethersProvider = new ethers.providers.Web3Provider(provider as any); const signer = wallet.connect(ethersProvider); const senderAddress = signer.address; @@ -66,7 +51,10 @@ describe.each([ ])('ParaSwap SDK: fetcher made with: %s', (testName, fetcherOptions) => { let paraSwap: SimpleFetchSDK; - beforeAll(() => { + beforeAll(async () => { + await startFork(); + await setBalance({ address: senderAddress, balance: 8e18 }); + paraSwap = constructSimpleSDK({ chainId, ...fetcherOptions, version: '5' }); }); test('getBalance', async () => { diff --git a/tests/test.test.ts b/tests/test.test.ts new file mode 100644 index 00000000..dddd840e --- /dev/null +++ b/tests/test.test.ts @@ -0,0 +1,368 @@ +import * as dotenv from 'dotenv'; +import Web3 from 'web3'; +import { BigNumber as BigNumberEthers, ethers } from 'ethers'; +import axios from 'axios'; +import fetch from 'isomorphic-unfetch'; +import { isAllowance, SwapSide, SimpleFetchSDK } from '../src'; +import BigNumber from 'bignumber.js'; + +import erc20abi from './abi/ERC20.json'; + +import { assert } from 'ts-essentials'; + +import { constructSimpleSDK, SimpleSDK } from '../src/sdk/simple'; +import { forkChain } from './helpers/hardhat'; + +dotenv.config(); + +jest.setTimeout(30 * 1000); + +declare let process: any; + +const ETH = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; +const DAI = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; +// const HEX = '0x2b591e99afe9f32eaa6214f7b7629768c40eeb39'; + +const DUMMY_ADDRESS_FOR_TESTING_ALLOWANCES = + '0xb9A079479A7b0F4E7F398F7ED3946bE6d9a40E79'; + +const PROVIDER_URL = process.env.PROVIDER_URL; +const chainId = 1; +const srcToken = ETH; +const destToken = DAI; +const srcAmount = (1 * 1e18).toString(); //The source amount multiplied by its decimals + +const referrer = 'sdk-test'; + +const wallet = ethers.Wallet.createRandom(); + +const { provider, setupFork } = forkChain(); + +const web3provider = new Web3(provider as any); + +const ethersProvider = new ethers.providers.Web3Provider(provider as any); + +const signer = wallet.connect(ethersProvider); +const senderAddress = signer.address; + +describe.skip.each([ + ['fetch', { fetch }], + ['axios', { axios }], +])('ParaSwap SDK: fetcher made with: %s', (testName, fetcherOptions) => { + let paraSwap: SimpleFetchSDK; + let paraSwapArbitrum: SimpleFetchSDK; + + beforeAll(async () => { + await setupFork({ + accounts: [{ address: senderAddress, balance: 8e18 }], + }); + + paraSwapArbitrum = constructSimpleSDK({ + chainId: 42161, + version: '6.2', + // apiURL: 'https://api-partners.paraswap.io/', + // apiKey: 'oXF4dtiLJ34kJTod3fcNH5WJtKRZ9cr95O4yaMvD', + ...fetcherOptions, + }); + paraSwap = constructSimpleSDK({ chainId, ...fetcherOptions }); + }); + test('getBalance', async () => { + const balance = await paraSwap.swap.getBalance(senderAddress, ETH); + expect(balance).toBeDefined(); + }); + + test('Get_Markets', async () => { + const markets = await paraSwap.swap.getAdapters(); + expect(markets.length).toBeGreaterThan(15); + }); + + test('Get_Tokens', async () => { + const tokens = await paraSwap.swap.getTokens(); + + expect(Array.isArray(tokens)).toBe(true); + expect(tokens.length).toBeGreaterThan(0); + expect(tokens[0]).toEqual( + expect.objectContaining({ + symbol: expect.any(String), + address: expect.any(String), + decimals: expect.any(Number), + }) + ); + }); + + test('TEST', async () => { + const priceRoute = await paraSwapArbitrum.swap.getRate({ + srcToken: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', // DAI on Arbitrum + srcDecimals: 18, + destToken: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', // WETH on Arbitrum + destDecimals: 6, + amount: '1000000000000000000000000', + // userAddress: wrappedLoan.address, + side: SwapSide.SELL, + options: { + // includeContractMethods: [ContractMethod.simpleSwap], + }, + }); + console.log( + '🚀 ~ file: test.test.ts:113 ~ test.only ~ priceRoute:', + priceRoute + ); + }); + + test('Get_Rates', async () => { + const priceRoute = await paraSwap.swap.getRate({ + srcToken: ETH, + destToken: DAI, + amount: srcAmount, + userAddress: senderAddress, + side: SwapSide.SELL, + options: { + includeDEXS: ['UniswapV2'], + otherExchangePrices: true, + }, + }); + + const { destAmount, bestRoute, others } = priceRoute; + + expect(typeof destAmount).toBe('string'); + + expect(Array.isArray(bestRoute)).toBe(true); + + const swapExchange = bestRoute[0]?.swaps[0]?.swapExchanges[0]; + + assert(swapExchange, 'exchange available at swapExchanges[0]'); + + expect(typeof swapExchange.destAmount).toBe('string'); + expect(new BigNumber(swapExchange.destAmount).isNaN()).toBe(false); + + expect(typeof swapExchange.exchange).toBe('string'); + + const firstBestRoute = bestRoute[0]; + assert(firstBestRoute, 'route available at bestRoute[0]'); + + expect(typeof firstBestRoute.percent).toBe('number'); + expect(new BigNumber(firstBestRoute.percent).isNaN()).toBe(false); + + expect(typeof swapExchange.srcAmount).toBe('string'); + expect(new BigNumber(swapExchange.srcAmount).isNaN()).toBe(false); + + expect(Array.isArray(others)).toBe(true); + + const firstRoute = others?.[0]; + + assert(firstRoute, 'at least one route must exist'); + + expect(typeof firstRoute.exchange).toBe('string'); + + expect(typeof firstRoute.unit).toBe('string'); + expect(firstRoute.unit && new BigNumber(firstRoute.unit).isNaN()).toBe( + false + ); + }); + + test('Get_Spender', async () => { + const spender = await paraSwap.swap.getSpender(); + expect(web3provider.utils.isAddress(spender)); + }); + + test('Get_Allowance', async () => { + const allowance = await paraSwap.swap.getAllowance( + DUMMY_ADDRESS_FOR_TESTING_ALLOWANCES, + DAI + ); + + assert(isAllowance(allowance), 'hardcoded dummy address should be found'); + + expect(allowance.allowance).toEqual('123000000000000000'); + }); + + // test('Get_Adapters', async () => { + // const adapters = await paraSwap.swap.getAdapters(); + // expect(adapters['paraswappool']?.[0]?.adapter).toBeDefined(); + // expect(adapters['uniswapv2']?.[0]?.adapter).toBeDefined(); + // expect(adapters['uniswapv2']?.[0]?.index).toBeDefined(); + // expect(adapters['kyberdmm']?.[0]?.adapter).toBeDefined(); + // expect(adapters['kyberdmm']?.[0]?.index).toBeDefined(); + // }); + + test('Build_Tx', async () => { + const destToken = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'; + const priceRoute = await paraSwap.swap.getRate({ + srcToken, + destToken, + amount: srcAmount, + userAddress: senderAddress, + side: SwapSide.SELL, + options: { + includeDEXS: ['UniswapV2'], + }, + }); + + const destAmount = new BigNumber(priceRoute.destAmount) + .times(0.99) + .toFixed(0); + + const txParams = await paraSwap.swap.buildTx( + { + srcToken, + destToken, + srcAmount, + destAmount, + priceRoute, + userAddress: senderAddress, + partner: referrer, + }, + { ignoreChecks: true } + ); + + expect(typeof txParams).toBe('object'); + }); + test('Build_and_Send_Tx', async () => { + const priceRoute = await paraSwap.swap.getRate({ + srcToken, + destToken, + amount: srcAmount, + userAddress: senderAddress, + side: SwapSide.SELL, + options: { + includeDEXS: ['Uniswap', 'UniswapV2', 'Balancer', 'Oasis'], + }, + }); + + const destAmount = new BigNumber(priceRoute.destAmount) + .times(0.99) + .toFixed(0); + + const txParams = await paraSwap.swap.buildTx( + { + srcToken, + destToken, + srcAmount, + destAmount, + priceRoute, + userAddress: signer.address, + partner: referrer, + }, + { ignoreChecks: true } + ); + + const transaction = { + ...txParams, + gasPrice: + txParams.gasPrice && + '0x' + new BigNumber(txParams.gasPrice).toString(16), + maxFeePerGas: + txParams.maxFeePerGas && + '0x' + new BigNumber(txParams.maxFeePerGas).toString(16), + maxPriorityFeePerGas: + txParams.maxPriorityFeePerGas && + '0x' + new BigNumber(txParams.maxPriorityFeePerGas).toString(16), + gasLimit: '0x' + new BigNumber(5000000).toString(16), + value: '0x' + new BigNumber(txParams.value).toString(16), + }; + const toContract = new ethers.Contract(destToken, erc20abi, ethersProvider); + const beforeFromBalance = await ethersProvider.getBalance(signer.address); + const beforeToBalance = await toContract.balanceOf(signer.address); + + const txr = await signer.sendTransaction(transaction); + await txr.wait(1); + const afterFromBalance = await ethersProvider.getBalance(signer.address); + const afterToBalance = await toContract.balanceOf(signer.address); + expect(beforeFromBalance.gt(afterFromBalance)).toBeTruthy(); + expect(beforeToBalance.lt(afterToBalance)).toBeTruthy(); + }); + test('Build_and_Send_Tx_BUY', async () => { + const destAmount = srcAmount; + const priceRoute = await paraSwap.swap.getRate({ + srcToken, + destToken, + amount: destAmount, + userAddress: senderAddress, + side: SwapSide.BUY, + options: { includeDEXS: ['Uniswap', 'UniswapV2', 'Balancer', 'Oasis'] }, + }); + const _srcAmount = new BigNumber(priceRoute.srcAmount) + .times(1.1) + .toFixed(0); + + const txParams = await paraSwap.swap.buildTx( + { + srcToken, + destToken, + srcAmount: _srcAmount, + destAmount, + priceRoute, + userAddress: signer.address, + partner: referrer, + }, + { ignoreChecks: true } + ); + + const transaction = { + ...txParams, + gasPrice: + txParams.gasPrice && + '0x' + new BigNumber(txParams.gasPrice).toString(16), + maxFeePerGas: + txParams.maxFeePerGas && + '0x' + new BigNumber(txParams.maxFeePerGas).toString(16), + maxPriorityFeePerGas: + txParams.maxPriorityFeePerGas && + '0x' + new BigNumber(txParams.maxPriorityFeePerGas).toString(16), + gasLimit: '0x' + new BigNumber(5000000).toString(16), + value: '0x' + new BigNumber(txParams.value).toString(16), + }; + const toContract = new ethers.Contract(destToken, erc20abi, ethersProvider); + const beforeFromBalance = await ethersProvider.getBalance(signer.address); + const beforeToBalance = await toContract.balanceOf(signer.address); + + const txr = await signer.sendTransaction(transaction); + await txr.wait(1); + const afterFromBalance = await ethersProvider.getBalance(signer.address); + const afterToBalance = await toContract.balanceOf(signer.address); + expect(beforeFromBalance.gt(afterFromBalance)).toBeTruthy(); + expect(beforeToBalance.lt(afterToBalance)).toBeTruthy(); + }); +}); + +describe.skip.each([ + [ + 'fetch & ethers', + { fetch }, + { + ethersProviderOrSigner: signer, + EthersContract: ethers.Contract, + account: senderAddress, + }, + ], + ['axios & web3', { axios }, { web3: web3provider, account: senderAddress }], +])( + 'ParaSwap SDK: contract calling methods: %s', + (testName, fetcherOptions, providerOptions) => { + let paraSwap: SimpleSDK; + + beforeAll(() => { + paraSwap = constructSimpleSDK( + { chainId, ...fetcherOptions }, + providerOptions + ); + }); + test('approveToken', async () => { + const txHash = await paraSwap.swap.approveToken('12345', DAI); + + await ethersProvider.waitForTransaction(txHash); + + const toContract = new ethers.Contract( + destToken, + erc20abi, + ethersProvider + ); + const spender = await paraSwap.swap.getSpender(); + const allowance: BigNumberEthers = await toContract.allowance( + signer.address, + spender + ); + expect(allowance.toString()).toEqual('12345'); + }); + } +); diff --git a/tests/viem.test.ts b/tests/viem.test.ts index 0f1f07dc..c85552b7 100644 --- a/tests/viem.test.ts +++ b/tests/viem.test.ts @@ -11,26 +11,25 @@ import { } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { hardhat } from 'viem/chains'; -import hre from 'hardhat'; import { constructSimpleSDK, SimpleSDK } from '../src/sdk/simple'; import BigNumber from 'bignumber.js'; import { txParamsToViemTxParams } from '../src/helpers'; +import { forkChain } from './helpers/hardhat'; dotenv.config(); jest.setTimeout(30 * 1000); -const PROVIDER_URL = process.env.PROVIDER_URL; const chainId = 1; const TEST_MNEMONIC = 'radar blur cabbage chef fix engine embark joy scheme fiction master release'; const wallet = ethers.Wallet.fromMnemonic(TEST_MNEMONIC); -const ethersProvider = new ethers.providers.Web3Provider( - hre.network.provider as any -); +const { provider, startFork } = forkChain(); + +const ethersProvider = new ethers.providers.Web3Provider(provider as any); const signer = wallet.connect(ethersProvider); const senderAddress = signer.address as Hex; @@ -38,7 +37,7 @@ const senderAddress = signer.address as Hex; const viemTestClient = createTestClient({ chain: hardhat, mode: 'hardhat', - transport: custom(hre.network.provider), + transport: custom(provider), }).extend(publicActions); const viemWalletClient = createWalletClient({ @@ -47,7 +46,7 @@ const viemWalletClient = createWalletClient({ // to be able to sign transactions account: privateKeyToAccount(wallet.privateKey as Hex), chain: hardhat, - transport: custom(hre.network.provider), + transport: custom(provider), }); describe('ParaSwap SDK: contract calling methods', () => { @@ -77,20 +76,7 @@ describe('ParaSwap SDK: contract calling methods', () => { let spender: Hex; beforeAll(async () => { - await hre.network.provider.request({ - // forks chain - method: 'hardhat_reset', - params: [ - { - forking: { - jsonRpcUrl: PROVIDER_URL, - // Optionally, specify the block number - // blockNumber: 12345678, - }, - // chainId: 1, // Set to Ethereum Mainnet's chainId - }, - ], - }); + // await startFork(); await viemTestClient.setBalance({ address: senderAddress,