Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tenderly testnet support #124

Merged
merged 2 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
ETHEREUM_PROVIDER_URL=
ETHEREUM_RINKEBY_PROVIDER_URL=
TENDERLY_TESTNET_PROVIDER_URL=
TENDERLY_TESTNET_ID=
TENDERLY_FORK_ID=
TENDERLY_PROJECT=
TENDERLY_USERNAME=
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ contracts/hardhat-dependency-compiler
deployments/mainnet/solcInputs/*
deployments/hardhat/*
deployments/tenderly/*
deployments/tenderly-testnet/*

fork-*.zip
testnet-*.zip

.coverage_artifacts
.coverage_contracts
Expand Down
15 changes: 11 additions & 4 deletions data/named-accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { DeploymentNetwork } from '../utils/Constants';

const mainnet = (address: string) => ({
[DeploymentNetwork.Mainnet]: address,
[DeploymentNetwork.Tenderly]: address
[DeploymentNetwork.Tenderly]: address,
[DeploymentNetwork.TenderlyTestnet]: address
});

const rinkeby = (address: string) => ({
Expand All @@ -20,11 +21,14 @@ const TestNamedAccounts = {
...mainnet('0x55FE002aefF02F77364de339a1292923A15844B8')
},
wbtcWhale: {
...mainnet('0x7f62f9592b823331E012D3c5DdF2A7714CfB9de2')
...mainnet('0x77134cbC06cB00b66F4c7e623D5fdBF6777635EC')
},
bntWhale: {
...mainnet('0x221A0e3C9AcEa6B3f1CC9DfC7063509c89bE7BC3')
}
},
linkWhale: {
...mainnet('0xc6bed363b30DF7F35b601a5547fE56cd31Ec63DA')
},
};

const TokenNamedAccounts = {
Expand All @@ -42,7 +46,10 @@ const TokenNamedAccounts = {
},
bnt: {
...mainnet('0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C')
}
},
link: {
...mainnet('0x514910771AF9Ca656af840dff83E8264EcF986CA')
},
};

const BancorNamedAccounts = {
Expand Down
182 changes: 182 additions & 0 deletions deployments/setup-testnet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import Contracts from '../components/Contracts';
import { getNamedSigners, isTenderlyTestnet, runPendingDeployments } from '../utils/Deploy';
import Logger from '../utils/Logger';
import { ZERO_ADDRESS } from '../utils/Constants';
import { NATIVE_TOKEN_ADDRESS } from '../utils/TokenData';
import { toWei } from '../utils/Types';
import '@nomiclabs/hardhat-ethers';
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
import '@tenderly/hardhat-tenderly';
import '@typechain/hardhat';
import AdmZip from 'adm-zip';
import { BigNumber } from 'ethers';
import { getNamedAccounts } from 'hardhat';
import 'hardhat-deploy';
import { capitalize } from 'lodash';
import path from 'path';

interface EnvOptions {
DEV_ADDRESSES: string;
TESTNET_NAME: string;
TENDERLY_PROJECT: string;
TENDERLY_USERNAME: string;
TENDERLY_TESTNET_ID: string;
TENDERLY_FORK_NETWORK_NAME: string;
TENDERLY_TESTNET_PROVIDER_URL?: string;
}

const {
DEV_ADDRESSES,
TESTNET_NAME,
TENDERLY_PROJECT,
TENDERLY_USERNAME,
TENDERLY_TESTNET_ID: testnetId = '',
TENDERLY_FORK_NETWORK_NAME = 'mainnet',
TENDERLY_TESTNET_PROVIDER_URL: testnetRpcUrl
}: EnvOptions = process.env as any as EnvOptions;

interface FundingRequest {
token: string;
tokenName: string;
amount: BigNumber;
whale: SignerWithAddress;
}

const fundAccount = async (account: string, fundingRequests: FundingRequest[]) => {
Logger.log(`Funding ${account}...`);

for (const fundingRequest of fundingRequests) {
// for tokens which are missing on a network skip funding request
if (fundingRequest.token === ZERO_ADDRESS) {
continue;
}
if (fundingRequest.token === NATIVE_TOKEN_ADDRESS) {
await fundingRequest.whale.sendTransaction({
value: fundingRequest.amount,
to: account
});

continue;
}

const tokenContract = await Contracts.ERC20.attach(fundingRequest.token);
await tokenContract.connect(fundingRequest.whale).transfer(account, fundingRequest.amount);
}
};

const fundAccounts = async () => {
Logger.log('Funding test accounts...');
Logger.log();

const { dai, link, usdc, wbtc, bnt } = await getNamedAccounts();
const { ethWhale, bntWhale, daiWhale, linkWhale, usdcWhale, wbtcWhale } = await getNamedSigners();

const fundingRequests = [
{
token: NATIVE_TOKEN_ADDRESS,
tokenName: 'eth',
amount: toWei(1000),
whale: ethWhale
},
{
token: bnt,
tokenName: 'bnt',
amount: toWei(10_000),
whale: bntWhale
},
{
token: dai,
tokenName: 'dai',
amount: toWei(100_000),
whale: daiWhale
},
{
token: link,
tokenName: 'link',
amount: toWei(10_000),
whale: linkWhale
},
{
token: usdc,
tokenName: 'usdc',
amount: toWei(100_000, 6),
whale: usdcWhale
},
{
token: wbtc,
tokenName: 'wbtc',
amount: toWei(100, 8),
whale: wbtcWhale
}
];

const devAddresses = DEV_ADDRESSES.split(',');

for(const fundingRequest of fundingRequests) {
if(fundingRequest.token == ZERO_ADDRESS) {
Logger.log(`Skipping funding for ${fundingRequest.tokenName}`);
}
}

for (const account of devAddresses) {
await fundAccount(account, fundingRequests);
}

Logger.log();
};

const runDeployments = async () => {
Logger.log('Running pending deployments...');
Logger.log();

await runPendingDeployments();

Logger.log();
};

const archiveArtifacts = async () => {
const zip = new AdmZip();

const srcDir = path.resolve(path.join(__dirname, './tenderly-testnet'));
const dest = path.resolve(path.join(__dirname, `../testnet-${testnetId}.zip`));

zip.addLocalFolder(srcDir);
zip.writeZip(dest);

Logger.log(`Archived ${srcDir} to ${dest}...`);
Logger.log();
};

const main = async () => {
if (!isTenderlyTestnet()) {
throw new Error('Invalid network');
}

Logger.log();

await runDeployments();

await fundAccounts();

await archiveArtifacts();

const networkName = capitalize(TENDERLY_FORK_NETWORK_NAME);

const description = `${networkName} ${TESTNET_NAME ? TESTNET_NAME : ""} Tenderly Testnet`;

Logger.log('********************************************************************************');
Logger.log();
Logger.log(description);
Logger.log('‾'.repeat(description.length));
Logger.log(` RPC: ${testnetRpcUrl}`);
Logger.log(` Dashboard: https://dashboard.tenderly.co/${TENDERLY_USERNAME}/${TENDERLY_PROJECT}/testnet/${testnetId}`);
Logger.log();
Logger.log('********************************************************************************');
};

main()
.then(() => process.exit(0))
.catch((error) => {
Logger.error(error);
process.exit(1);
});
12 changes: 11 additions & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'solidity-coverage';
interface EnvOptions {
ETHEREUM_PROVIDER_URL?: string;
ETHEREUM_RINKEBY_PROVIDER_URL?: string;
TENDERLY_TESTNET_PROVIDER_URL?: string;
ETHERSCAN_API_KEY?: string;
GAS_PRICE?: number | 'auto';
NIGHTLY?: boolean;
Expand All @@ -33,6 +34,7 @@ interface EnvOptions {
const {
ETHEREUM_PROVIDER_URL = '',
ETHEREUM_RINKEBY_PROVIDER_URL = '',
TENDERLY_TESTNET_PROVIDER_URL = '',
ETHERSCAN_API_KEY,
GAS_PRICE: gasPrice = 'auto',
NIGHTLY: isNightly,
Expand Down Expand Up @@ -90,6 +92,13 @@ const config: HardhatUserConfig = {
saveDeployments: true,
live: true,
gas: 6000000
},
[DeploymentNetwork.TenderlyTestnet]: {
chainId: 1,
url: TENDERLY_TESTNET_PROVIDER_URL,
autoImpersonate: true,
saveDeployments: true,
live: true
}
},

Expand Down Expand Up @@ -137,7 +146,8 @@ const config: HardhatUserConfig = {
external: {
deployments: {
[DeploymentNetwork.Mainnet]: [`deployments/${DeploymentNetwork.Mainnet}`],
[DeploymentNetwork.Tenderly]: [`deployments/${DeploymentNetwork.Tenderly}`]
[DeploymentNetwork.Tenderly]: [`deployments/${DeploymentNetwork.Tenderly}`],
[DeploymentNetwork.TenderlyTestnet]: [`deployments/${DeploymentNetwork.TenderlyTestnet}`]
}
},

Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,21 @@
"export:storage": "pnpm cleanbuild && hardhat run deployments/storage-layout.ts",
"deploy:prepare": "rm -rf ./node_modules && rm pnpm-lock.yaml && pnpm install && pnpm cleanbuild",
"deploy:prepare:fork": "rm -rf deployments/tenderly && cp -rf deployments/mainnet/. deployments/tenderly",
"deploy:prepare:testnet": "rm -rf deployments/tenderly-testnet && cp -rf deployments/mainnet/. deployments/tenderly-testnet",
"deploy:mainnet": "HARDHAT_NETWORK=mainnet hardhat deploy",
"deploy:rinkeby": "HARDHAT_NETWORK=rinkeby hardhat deploy",
"deploy:fork": "pnpm deploy:prepare:fork && HARDHAT_NETWORK=tenderly hardhat deploy",
"deploy:testnet": "pnpm deploy:prepare:testnet && HARDHAT_NETWORK=tenderly-testnet hardhat deploy",
"verify:mainnet": "HARDHAT_NETWORK=mainnet hardhat etherscan-verify --license None --force-license",
"verify:rinkeby": "HARDHAT_NETWORK=rinkeby hardhat etherscan-verify --license None --force-license",
"setup:fork": "pnpm deploy:prepare:fork && ./deployments/run-fork.sh pnpm run:fork deployments/setup-fork.ts",
"setup:fork:main": "FORK_NAME=Main pnpm setup:fork",
"setup:fork:research": "FORK_NAME=Research FORK_RESEARCH=1 pnpm setup:fork",
"setup:fork:all": "pnpm setup:fork:main && pnpm setup:fork:research",
"setup:testnet": "pnpm deploy:prepare:testnet && HARDHAT_NETWORK=tenderly-testnet hardhat deploy && pnpm run:testnet deployments/setup-testnet.ts",
"run:mainnet": "HARDHAT_NETWORK=mainnet hardhat run",
"run:fork": "HARDHAT_NETWORK=tenderly hardhat run",
"run:testnet": "HARDHAT_NETWORK=tenderly-testnet hardhat run",
"pol:enable:trading:check:mainnet": "pnpm run:mainnet scripts/enableTrading.ts",
"pol:enable:trading:check:fork": "pnpm run:fork scripts/enableTrading.ts",
"pol:enable:trading:mainnet": "ENABLE_TRADING=1 pnpm run:mainnet scripts/enableTrading.ts",
Expand Down
3 changes: 2 additions & 1 deletion utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export enum DeploymentNetwork {
Mainnet = 'mainnet',
Rinkeby = 'rinkeby',
Hardhat = 'hardhat',
Tenderly = 'tenderly'
Tenderly = 'tenderly',
TenderlyTestnet = 'tenderly-testnet'
}

export const EXP2_INPUT_TOO_HIGH = new Decimal(16).div(new Decimal(2).ln());
Expand Down
9 changes: 5 additions & 4 deletions utils/Deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ export const DeployedContracts = {
};

export const isTenderlyFork = () => getNetworkName() === DeploymentNetwork.Tenderly;
export const isMainnetFork = () => isTenderlyFork();
export const isMainnet = () => getNetworkName() === DeploymentNetwork.Mainnet || isMainnetFork();
export const isTenderlyTestnet = () => getNetworkName() === DeploymentNetwork.TenderlyTestnet;
export const isMainnet = () => getNetworkName() === DeploymentNetwork.Mainnet || isTenderly();
export const isRinkeby = () => getNetworkName() === DeploymentNetwork.Rinkeby;
export const isLive = () => (isMainnet() && !isMainnetFork()) || isRinkeby();
export const isLive = () => (isMainnet() && !isTenderly()) || isRinkeby();
export const isTenderly = () => isTenderlyFork() || isTenderlyTestnet();

const TEST_MINIMUM_BALANCE = toWei(10);
const TEST_FUNDING = toWei(10);
Expand All @@ -90,7 +91,7 @@ export const getNamedSigners = async (): Promise<Record<string, SignerWithAddres
};

export const fundAccount = async (account: string | SignerWithAddress, amount?: BigNumberish) => {
if (!isMainnetFork()) {
if (!isTenderly()) {
return;
}

Expand Down
Loading