Skip to content

Commit

Permalink
Merge pull request #494 from bancorprotocol/fork-creation-fix
Browse files Browse the repository at this point in the history
fix fork creation
  • Loading branch information
ivanzhelyazkov authored Oct 29, 2024
2 parents 60fa652 + fb784e4 commit be4144b
Show file tree
Hide file tree
Showing 10 changed files with 1,694 additions and 1,904 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ jobs:
access_token: ${{ github.token }}

- name: Check out the repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '16'
node-version: '20'

- name: Get yarn cache directory path
id: yarn-cache-dir-path
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/health.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ jobs:

steps:
- name: Check out the repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '16'
node-version: '20'

- name: Get yarn cache directory path
id: yarn-cache-dir-path
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
should-run: ${{ steps.should-run.outputs.should-run }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Check the latest commit
id: should-run
Expand Down Expand Up @@ -44,9 +44,9 @@ jobs:
uses: actions/checkout@v2

- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '16'
node-version: '20'

- name: Get yarn cache directory path
id: yarn-cache-dir-path
Expand Down
4 changes: 1 addition & 3 deletions contracts/token/Token.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ pragma solidity 0.8.13;
* @dev the main purpose of the Token interfaces is to ensure artificially that we won't use ERC20's standard functions,
* but only their safe versions, which are provided by SafeERC20 and SafeERC20Ex via the TokenLibrary contract
*/
interface Token {

}
interface Token {}
7 changes: 1 addition & 6 deletions contracts/vaults/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,7 @@ abstract contract Vault is IVault, Upgradeable, PausableUpgradeable, ReentrancyG
}

// allows execution only by an authorized operation
modifier whenAuthorized(
address caller,
Token token,
address payable target,
uint256 amount
) {
modifier whenAuthorized(address caller, Token token, address payable target, uint256 amount) {
if (!isAuthorizedWithdrawal(caller, token, target, amount)) {
revert AccessDenied();
}
Expand Down
130 changes: 61 additions & 69 deletions deploy/tests/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,40 +310,34 @@ import { getNamedAccounts } from 'hardhat';
for (const { token, whale, decimals } of Object.values(pools)) {
const tknDepositAmount = toWei(100, decimals);

for (let i = 0; i < 5; i++) {
const { liquidity: prevLiquidity } = await poolCollection.poolData(token);
const { liquidity: prevLiquidity } = await poolCollection.poolData(token);

await depositTKN(token, whale, tknDepositAmount);
await depositTKN(token, whale, tknDepositAmount);

const liquidity = await poolCollection.poolLiquidity(token);
expect(liquidity.stakedBalance).to.equal(prevLiquidity.stakedBalance.add(tknDepositAmount));
}
const liquidity = await poolCollection.poolLiquidity(token);
expect(liquidity.stakedBalance).to.equal(prevLiquidity.stakedBalance.add(tknDepositAmount));
}

// perform a few BNT deposit tests
// perform BNT deposit tests
const bntDepositAmount = toWei(10);

await vbntGovernance
.connect(foundationMultisig)
.grantRole(Roles.TokenGovernance.ROLE_GOVERNOR, daoMultisig.address);
await vbntGovernance.connect(daoMultisig).grantRole(Roles.TokenGovernance.ROLE_MINTER, bntPool.address);

for (let i = 0; i < 5; i++) {
const prevBNBNTAmount = await bnBNT.balanceOf(bntWhale.address);
const prevVBNTTokenAmount = await vbnt.balanceOf(bntWhale.address);
const prevTotalSupply = await bnt.totalSupply();
const prevBNBNTAmount = await bnBNT.balanceOf(bntWhale.address);
const prevVBNTTokenAmount = await vbnt.balanceOf(bntWhale.address);
const prevTotalSupply = await bnt.totalSupply();

await depositBNT(bntDepositAmount);
await depositBNT(bntDepositAmount);

const receivedBNBNTAmount = (await bnBNT.balanceOf(bntWhale.address)).sub(prevBNBNTAmount);
const receivedBNBNTAmount = (await bnBNT.balanceOf(bntWhale.address)).sub(prevBNBNTAmount);

expect(receivedBNBNTAmount).to.be.gt(0);
expect(await vbnt.balanceOf(bntWhale.address)).to.equal(
prevVBNTTokenAmount.add(receivedBNBNTAmount)
);
expect(receivedBNBNTAmount).to.be.gt(0);
expect(await vbnt.balanceOf(bntWhale.address)).to.equal(prevVBNTTokenAmount.add(receivedBNBNTAmount));

expect(await bnt.totalSupply()).to.equal(prevTotalSupply.sub(bntDepositAmount));
}
expect(await bnt.totalSupply()).to.equal(prevTotalSupply.sub(bntDepositAmount));
});
});

Expand Down Expand Up @@ -490,64 +484,62 @@ import { getNamedAccounts } from 'hardhat';

const tradeAmount = toWei(10, decimals);

for (let i = 0; i < 5; i++) {
if (!isNativeToken) {
const tokenContract = await Contracts.ERC20.attach(token);
await tokenContract.connect(whale).approve(network.address, tradeAmount);
}
if (!isNativeToken) {
const tokenContract = await Contracts.ERC20.attach(token);
await tokenContract.connect(whale).approve(network.address, tradeAmount);
}

const prevTokenBalance = await getBalance(tokenWithAddress, whale);
const prevBNTBalance = await bnt.balanceOf(whale.address);

const hop1Params = [
token,
bnt.address,
tradeAmount,
1,
MAX_UINT256,
ZERO_ADDRESS,
{
value: isNativeToken ? tradeAmount : BigNumber.from(0)
}
] as const;
const receivedBNTAmount = await network
.connect(whale)
.callStatic.tradeBySourceAmount(...hop1Params);
const res = await network.connect(whale).tradeBySourceAmount(...hop1Params);

let transactionCost = BigNumber.from(0);
if (isNativeToken) {
transactionCost = await getTransactionCost(res);
const prevTokenBalance = await getBalance(tokenWithAddress, whale);
const prevBNTBalance = await bnt.balanceOf(whale.address);

const hop1Params = [
token,
bnt.address,
tradeAmount,
1,
MAX_UINT256,
ZERO_ADDRESS,
{
value: isNativeToken ? tradeAmount : BigNumber.from(0)
}
] as const;
const receivedBNTAmount = await network
.connect(whale)
.callStatic.tradeBySourceAmount(...hop1Params);
const res = await network.connect(whale).tradeBySourceAmount(...hop1Params);

let transactionCost = BigNumber.from(0);
if (isNativeToken) {
transactionCost = await getTransactionCost(res);
}

const newBNTBalance = await bnt.balanceOf(whale.address);

expect(await getBalance(tokenWithAddress, whale)).to.equal(
prevTokenBalance.sub(tradeAmount).sub(transactionCost)
);
expect(receivedBNTAmount).to.be.gt(0);
expect(newBNTBalance).to.equal(prevBNTBalance.add(receivedBNTAmount));
const newBNTBalance = await bnt.balanceOf(whale.address);

await bnt.connect(whale).approve(network.address, newBNTBalance);
expect(await getBalance(tokenWithAddress, whale)).to.equal(
prevTokenBalance.sub(tradeAmount).sub(transactionCost)
);
expect(receivedBNTAmount).to.be.gt(0);
expect(newBNTBalance).to.equal(prevBNTBalance.add(receivedBNTAmount));

const prevTokenBalance2 = await getBalance(tokenWithAddress, whale);
await bnt.connect(whale).approve(network.address, newBNTBalance);

const hop2Params = [bnt.address, token, newBNTBalance, 1, MAX_UINT256, ZERO_ADDRESS] as const;
const receivedTokenAmount = await network
.connect(whale)
.callStatic.tradeBySourceAmount(...hop2Params);
const res2 = await network.connect(whale).tradeBySourceAmount(...hop2Params);
let transactionCost2 = BigNumber.from(0);
if (isNativeToken) {
transactionCost2 = await getTransactionCost(res2);
}
const prevTokenBalance2 = await getBalance(tokenWithAddress, whale);

expect(receivedTokenAmount).to.be.gt(0);
expect(await getBalance(tokenWithAddress, whale)).to.equal(
prevTokenBalance2.add(receivedTokenAmount).sub(transactionCost2)
);
expect(await bnt.balanceOf(whale.address)).to.be.equal(0);
const hop2Params = [bnt.address, token, newBNTBalance, 1, MAX_UINT256, ZERO_ADDRESS] as const;
const receivedTokenAmount = await network
.connect(whale)
.callStatic.tradeBySourceAmount(...hop2Params);
const res2 = await network.connect(whale).tradeBySourceAmount(...hop2Params);
let transactionCost2 = BigNumber.from(0);
if (isNativeToken) {
transactionCost2 = await getTransactionCost(res2);
}

expect(receivedTokenAmount).to.be.gt(0);
expect(await getBalance(tokenWithAddress, whale)).to.equal(
prevTokenBalance2.add(receivedTokenAmount).sub(transactionCost2)
);
expect(await bnt.balanceOf(whale.address)).to.be.equal(0);
}
});
});
Expand Down
8 changes: 7 additions & 1 deletion deployments/run-fork.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ else
project=${TENDERLY_PROJECT}
fi

echo "Creating a Mainnet Tenderly Fork... "
echo

TENDERLY_FORK_API="https://api.tenderly.co/api/v1/account/${username}/project/${project}/fork"

cleanup() {
Expand All @@ -30,9 +33,12 @@ fork_id=$(curl -sX POST "${TENDERLY_FORK_API}" \
-H "Content-Type: application/json" -H "X-Access-Key: ${TENDERLY_ACCESS_KEY}" \
-d '{"network_id": "1"}' | jq -r '.simulation_fork.id')

echo "Created a fork ${fork_id} at ${username}/${project}..."
echo "Created Tenderly Fork ${fork_id} at ${username}/${project}..."
echo

# Create a new dir for the deploy script files and copy them there
rm -rf deployments/tenderly && cp -rf deployments/mainnet/. deployments/tenderly

command="TENDERLY_FORK_ID=${fork_id} ${@:1}"

echo "Running:"
Expand Down
54 changes: 47 additions & 7 deletions deployments/setup-fork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DeployedContracts, getNamedSigners, isTenderlyFork, runPendingDeploymen
import Logger from '../utils/Logger';
import { NATIVE_TOKEN_ADDRESS } from '../utils/TokenData';
import { toWei } from '../utils/Types';
import { ZERO_ADDRESS } from '../utils/Constants';
import '@nomiclabs/hardhat-ethers';
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
import '@tenderly/hardhat-tenderly';
Expand All @@ -11,6 +12,7 @@ import AdmZip from 'adm-zip';
import { BigNumber } from 'ethers';
import { getNamedAccounts } from 'hardhat';
import 'hardhat-deploy';
import { isEmpty } from 'lodash';
import path from 'path';

interface EnvOptions {
Expand Down Expand Up @@ -41,17 +43,31 @@ const fundAccount = async (account: string, fundingRequests: FundingRequest[]) =
Logger.log(`Funding ${account}...`);

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

continue;
}

const tokenContract = await Contracts.ERC20.attach(fundingRequest.token);
await tokenContract.connect(fundingRequest.whale).transfer(account, fundingRequest.amount);
const tokenContract = await Contracts.ERC20.attach(token);
// check if whale has enough balance
const whaleBalance = await tokenContract.balanceOf(whale.address);
if (whaleBalance.lt(amount)) {
Logger.error(`Whale ${whale.address} has insufficient balance for ${token}`);
continue;
}
await tokenContract.connect(whale).transfer(account, amount);
}
};

Expand Down Expand Up @@ -96,9 +112,33 @@ const fundAccounts = async () => {
}
];

if (isEmpty(DEV_ADDRESSES)) {
Logger.log('No dev addresses to fund');
return;
}

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

for (const account of devAddresses) {
for (const fundingRequest of fundingRequests) {
if (fundingRequest.token === ZERO_ADDRESS) {
Logger.log(`Skipping funding for ${fundingRequest.token}`);
}
const { whale } = fundingRequest;
if (!whale) {
continue;
}
const whaleBalance = await whale.getBalance();
// transfer ETH to the funding account if it doesn't have ETH

if (whaleBalance.lt(toWei(1))) {
await ethWhale.sendTransaction({
value: toWei(1),
to: whale.address
});
}
}

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

Expand Down Expand Up @@ -156,7 +196,7 @@ const main = async () => {

await archiveArtifacts();

const description = `${FORK_NAME} Fork`;
const description = FORK_NAME ? `Bancor V3 ${FORK_NAME} Fork` : 'Bancor V3 Mainnet Fork';

Logger.log('********************************************************************************');
Logger.log();
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,10 @@
},
"resolutions": {
"@tenderly/hardhat-tenderly/@nomiclabs/hardhat-ethers": "npm:[email protected]",
"solhint/@solidity-parser/parser": "0.16",
"solidity-coverage/@solidity-parser/parser": "0.16"
"solhint/@solidity-parser/parser": "0.16",
"solidity-coverage/@solidity-parser/parser": "0.16",
"@bancor/contracts-solidity/hardhat": "2.15.0",
"glob/path-scurry/lru-cache": "11.0.1"
},
"snyk": true
}
Loading

0 comments on commit be4144b

Please sign in to comment.