Skip to content

Commit

Permalink
Merge pull request bancorprotocol#124 from bancorprotocol/tenderly-te…
Browse files Browse the repository at this point in the history
…stnet-support

Tenderly testnet support
  • Loading branch information
ivanzhelyazkov authored Nov 29, 2023
2 parents bf9854d + 9f6c683 commit 0f37fe2
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 10 deletions.
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

0 comments on commit 0f37fe2

Please sign in to comment.