Skip to content

Commit

Permalink
replace ganache with hardhat
Browse files Browse the repository at this point in the history
  • Loading branch information
Velenir committed Oct 23, 2024
1 parent e11a89c commit 57a9f24
Show file tree
Hide file tree
Showing 9 changed files with 518 additions and 131 deletions.
2 changes: 2 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down
91 changes: 91 additions & 0 deletions tests/helpers/hardhat.ts
Original file line number Diff line number Diff line change
@@ -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<void>;
setBalance: (options: SetBalanceInput) => Promise<void>;
impersonateAccount: (address: string) => Promise<void>;
provider: EthereumProvider;
setupFork: (options: {
fork?: ForkChainInput;
accounts?: SetBalanceInput[];
}) => Promise<void>;
}

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,
};
}
30 changes: 9 additions & 21 deletions tests/legacy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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;
Expand All @@ -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
);
});

Expand Down Expand Up @@ -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 () => {
Expand Down
33 changes: 12 additions & 21 deletions tests/limitOrders.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
38 changes: 11 additions & 27 deletions tests/nftOrders.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,14 @@ 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,
} from '../src/methods/nftOrders/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();

Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
31 changes: 10 additions & 21 deletions tests/partialSdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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);
Expand All @@ -108,7 +93,7 @@ const web3ContractCaller = constructWeb3ContractCaller(
);

const customGanacheContractCaller = constructProviderOnlyContractCaller(
ganacheProvider,
provider,
senderAddress
);

Expand All @@ -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,
Expand Down
Loading

0 comments on commit 57a9f24

Please sign in to comment.