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

feat: add manual CI to simulate upgrades with tenderly #345

Draft
wants to merge 36 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
db102c4
feat: add script for simulating upgrades
viraj124 Oct 18, 2024
484052d
chore: add try/catch
viraj124 Oct 18, 2024
075af21
chore: add task args
viraj124 Oct 18, 2024
7c65435
chore: upddate comment
viraj124 Oct 18, 2024
30c3f1b
chore: minor touchup
viraj124 Oct 18, 2024
631081a
chore: reduce the manaual arguments
viraj124 Oct 21, 2024
15d727a
feat: add manual ci
viraj124 Oct 21, 2024
74d79e5
chore: add changeset
viraj124 Oct 21, 2024
5abd078
Merge branch 'main' into viraj124/206-add-simulation-for-upgrades
viraj124 Oct 21, 2024
afdeb0c
chore: resolve merge conflicts
viraj124 Oct 24, 2024
d212d7b
chore: use env vars in the script
viraj124 Oct 25, 2024
5268d89
chore: use env vars in the ci
viraj124 Oct 25, 2024
0bb1072
Merge branch 'main' into viraj124/206-add-simulation-for-upgrades
viraj124 Oct 25, 2024
48d8d00
chore: setup tenderly fork config
viraj124 Oct 29, 2024
d1133a6
chore: remove unused file
viraj124 Nov 1, 2024
f8c10e1
chore: add script for docker setup for integration tests
viraj124 Nov 1, 2024
5c851b0
chore: add placeholder contract
viraj124 Nov 1, 2024
20332d2
chore: add fork config in hardhat config
viraj124 Nov 1, 2024
dcf704a
feat: add docker setup for tenderly fork test suite
viraj124 Nov 1, 2024
b7a7df2
fix: deployed artifact path
Nov 2, 2024
7be93d2
Merge branch 'main' into viraj124/206-add-simulation-for-upgrades
viraj124 Nov 2, 2024
6f233f1
chore: docker config changes
viraj124 Nov 11, 2024
c50030a
chore: debug block committer integration issue
viraj124 Nov 20, 2024
a1f3583
chore: inject state contract address dynamically
viraj124 Nov 20, 2024
0c4ae58
chore: update fuel core version in e2e docker file
viraj124 Nov 22, 2024
7e23059
chore: update graphql endpoint
viraj124 Nov 22, 2024
9a3fe72
debug: fuel core issue
viraj124 Nov 22, 2024
6d60c8f
chore: update committer account
viraj124 Nov 26, 2024
1ea8cfe
fix: fuel core docker setup
viraj124 Nov 26, 2024
5ade961
fix: fuel core docker setup
viraj124 Nov 26, 2024
cc59923
fix: fuel core docker setup
viraj124 Nov 26, 2024
9007746
chore: add changeset
viraj124 Nov 26, 2024
f7cdbbf
chore: minor touchups
viraj124 Nov 26, 2024
f5d5574
Merge branch 'viraj124/363-update-block-committer-docker-setup' into …
viraj124 Nov 26, 2024
b089b32
feat: update docker setup
viraj124 Nov 26, 2024
52dcec4
chore: formatting
viraj124 Nov 26, 2024
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
5 changes: 5 additions & 0 deletions .changeset/silent-apples-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@fuel-bridge/solidity-contracts': minor
---

add manual CI to simulate upgrades with tenderly
35 changes: 35 additions & 0 deletions .github/workflows/manual-simulate-upgrade.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Manual Simulate Upgrade

on:
workflow_dispatch:
inputs:
vnetId:
description: 'Enter the tenderly virtual testnet id'
required: true
type: string
accessKey:
description: 'Enter the tenderly account access key'
required: true
type: string
rpc:
description: 'Enter tenderly virtual network rpc'
required: true
type: string

jobs:
simulate-upgrades:
runs-on: ubuntu-latest
env:
RPC_URL: ${{ github.event.inputs.rpc }}
VNET_ID: ${{ github.event.inputs.vnetId }}
ACCESS_KEY: ${{ github.event.inputs.accessKey }}
steps:
- uses: actions/checkout@v3
- uses: FuelLabs/github-actions/setups/node@master
with:
node-version: 20.16.0
pnpm-version: 9.0.6
- name: Simulate Upgrades
run: |
npx hardhat compile && npx hardhat simulate-upgrades --network mainnet
working-directory: ./packages/solidity-contracts
1 change: 1 addition & 0 deletions packages/solidity-contracts/scripts/hardhat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export * from './withdrawalResume';
export * from './withdrawalBlacklist';
export * from './withdrawalWhitelist';
export * from './verifyMainnetDeployment';
export * from './simulateUpgrades';
export * from './eventFilter';
140 changes: 140 additions & 0 deletions packages/solidity-contracts/scripts/hardhat/simulateUpgrades.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { task } from 'hardhat/config';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { ContractFactory, ethers } from 'ethers';

const SECURITY_COUNCIL_MULTISIG = '0x32da601374b38154f05904B16F44A1911Aa6f314';
const ETH_BALANCE_TO_SET = '0xDE0B6B3A7640000'; // 1 ether
const GAS_AMOUNT = '0x7a1200';
const GAS_PRICE = '0xF4241';

task(
'simulate-upgrades',
'Mocks proxy upgrades with tenderly simulation'
).setAction(
async (taskArgs: any, hre: HardhatRuntimeEnvironment): Promise<void> => {
const network = hre.network.name;

if (network !== 'mainnet') {
return;
}

const {
upgrades: { prepareUpgrade },
ethers,
} = hre;

console.log(
`Mocking proxy upgrades on ${network}:${hre.network.config.chainId}...`
);

const signer = await ethers.provider.getSigner(0);

// fund the signer for deploying the new implementation
const setBalancePayload = {
jsonrpc: '2.0',
method: 'tenderly_setBalance',
params: [[(await signer.getAddress()).toString()], ETH_BALANCE_TO_SET],
};

const rpc: string = process.env.RPC_URL!;

const deployments = await hre.deployments.all();

const apiUrl = `https://api.tenderly.co/api/v1/account/fuel-network/project/preprod/vnets/${process.env.VNET_ID}/transactions/simulate`;
const accessKey = process.env.ACCESS_KEY;

try {
await fetch(rpc, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(setBalancePayload),
});

for (const [contractName, deployment] of Object.entries(deployments)) {
if (deployment.abi.length == 0) continue;

// mocking the deployment for the new implementation too.
// we currently assume that this script will be ran, after the `upgradeVerification` script is executed so we have access to the updated `constructorArgs`, otherwise we can allow the contructor arguments to be entered manually.
const factory = (await ethers.getContractFactory(
deployment.linkedData.factory
)) as ContractFactory; // Typing bug in `getContractFactory`

const deploymentResponse = (await prepareUpgrade(
deployment.address,
factory,
{
kind: 'uups',
constructorArgs: deployment.linkedData.constructorArgs,
getTxResponse: true,
redeployImplementation: 'always',
}
)) as ethers.TransactionResponse;

const receipt = await hre.ethers.provider.getTransactionReceipt(
deploymentResponse.hash
);

const newImplementationAddress = receipt?.contractAddress!;

const proxyContractInstance = new ethers.Contract(
deployment.address,
deployment.abi
);

// simulating upgrade enables to impersonate the security council multisig, without the need of signatures
const encodedUpgradeData =
proxyContractInstance.interface.encodeFunctionData('upgradeTo', [
newImplementationAddress,
]);

const upgradeImplementationPayload = {
callArgs: {
from: SECURITY_COUNCIL_MULTISIG,
to: deployment.address,
gas: GAS_AMOUNT,
gasPrice: GAS_PRICE,
value: '0x0',
data: encodedUpgradeData,
},
blockNumber: 'latest',
};

const response = await fetch(apiUrl, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-Access-Key': accessKey,
},
body: JSON.stringify(upgradeImplementationPayload),
} as any); // typing bug with the request headers

// simulations don't result in visible state changes so not checking the new implementation here, so instead we check
// the event logs that the `Upgraded` event was emitted
if (response.ok) {
const responsePayload: any = await response.json();

if (responsePayload.logs[0].name === 'Upgraded') {
console.log(
`✅ Upgrade simulation successful for ${contractName} (${deployment.address})`
);
} else {
console.log(
`❌ Upgrade simulation failed for ${contractName} (${deployment.address})`
);
throw new Error('Upgrade simulation failed');
}
} else {
console.log(
`❌ Upgrade simulation failed for ${contractName} (${deployment.address})`
);
throw new Error('Upgrade simulation failed');
}
}
} catch (error) {
console.log(`❌ Upgrade simulation failed: ${error}`);
}
}
);
Loading