Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e00141d
fix : avalancheFuji to avalancheFujiTestnet for hardhat network
gfournieriExec Apr 25, 2025
5ef06ce
fix: rename avalancheFuji to avalancheFujiTestnet and update related …
gfournieriExec Apr 25, 2025
6190635
fix: include bytecode and args in deployment saving process
gfournieriExec Apr 25, 2025
df8c19d
fix: update verification script path and enhance error handling
gfournieriExec Apr 25, 2025
7fef22f
feat: add deployment workflow and update config script for new networks
gfournieriExec Apr 25, 2025
adf39e5
docs: enhance deployment instructions and add GitHub Actions workflow…
gfournieriExec Apr 25, 2025
bad7092
add entry to changelog
gfournieriExec Apr 25, 2025
cb0e5a0
fix: add condition to skip config update and artifact saving for hard…
gfournieriExec Apr 25, 2025
1897a09
refactor: simplify environment variable handling in deployment workflow
gfournieriExec Apr 25, 2025
9889841
fix: set default network option to 'hardhat' in deployment workflow
gfournieriExec Apr 25, 2025
dffaef7
fix: update environment options name
gfournieriExec May 5, 2025
fa2a482
refactor(ci): combine environment variables steps in deploy workflow
gfournieriExec May 5, 2025
6343461
feat(deploy): integrate contract verification into deployment process
gfournieriExec May 5, 2025
7d39f18
refactor(docs): remove redundant GitHub Actions deployment and verifi…
gfournieriExec May 5, 2025
03e35cf
fix(ci): skip tests for mainnets environment in deployment workflow
gfournieriExec May 5, 2025
2118ea9
feat(ci): add validation for Bellecour mainnet deployments to ensure …
gfournieriExec May 5, 2025
562aeae
fix(ci): update validation for Bellecour mainnet deployments to requi…
gfournieriExec May 6, 2025
ba5cb6e
feat(ci): add API key environment variables for Avalanche Fuji and Ar…
gfournieriExec May 6, 2025
14cf5eb
refactor(scripts): simplify update-config.js by removing unused param…
gfournieriExec May 6, 2025
948bafa
fix(scripts): update update-config.js to use Hardhat for network chai…
gfournieriExec May 6, 2025
40ed84c
fix(scripts): import config in update-config.js and refactor local co…
gfournieriExec May 6, 2025
1999911
fix(scripts): remove redundant networkName argument from update-confi…
gfournieriExec May 12, 2025
b348f0c
feat(scripts): implement update-config.ts to manage ERC1538Proxy depl…
gfournieriExec May 12, 2025
83098d2
fix(scripts): update update-config.ts to use deployments.get for ERC1…
gfournieriExec May 12, 2025
94e4045
fix(scripts): update deploy workflow to use update-config.ts and remo…
gfournieriExec May 12, 2025
01ee9cf
fix(scripts): correct variable name from localconfig to localConfig i…
gfournieriExec May 12, 2025
c520fa3
fix(scripts): remove redundant deployment file check for ERC1538Proxy…
gfournieriExec May 13, 2025
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
104 changes: 104 additions & 0 deletions .github/workflows/deploy-smart-contracts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Deploy PoCo Contracts
on:
workflow_dispatch:
inputs:
network:
description: 'Network'
required: true
type: choice
options:
- hardhat
- avalancheFujiTestnet
- arbitrumSepolia
- bellecour
default: 'hardhat'
environment:
description: 'Environment'
required: true
type: choice
options:
- testnets
- mainnets
default: 'testnets'

jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Validate mainnet deployment conditions
run: |
#TODO remove this when we have other mainnets
if [[ "${{ inputs.environment }}" == "mainnets" && !("${{ inputs.network }}" == "bellecour" && "${{ github.ref }}" == "refs/heads/main") ]]; then
echo "::error::Bellecour mainnet deployments must be made from the main branch. Current branch: ${GITHUB_REF#refs/heads/}"
exit 1
fi

echo "Deployment validation passed!"
deploy:
needs: validate
runs-on: ubuntu-latest
permissions:
contents: write # Required for saving deployment
environment: ${{ inputs.environment }} # Use the selected environment
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Nodejs
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm' # Cache dependencies

- name: Install dependencies
run: npm ci

- name: Run tests
run: |
if [ "${{ inputs.network }}" == "arbitrumSepolia" ]; then
npm run test:arbitrumSepolia
elif [ "${{ inputs.network }}" == "avalancheFujiTestnet" ]; then
npm run test:fuji
else
npm run test
fi

- name: Set environment variables
id: set-env
run: |
echo "PRIVATE_KEY=${{ secrets.PRIVATE_KEY }}" >> $GITHUB_ENV
if [ "${{ inputs.network }}" == "avalancheFujiTestnet" ]; then
echo "FUJI_RPC_URL=${{ secrets.FUJI_RPC_URL }}" >> $GITHUB_ENV
echo "SNOWTRACE_API_KEY=${{ secrets.SNOWTRACE_API_KEY }}" >> $GITHUB_ENV
fi

if [ "${{ inputs.network }}" == "arbitrumSepolia" ]; then
echo "ARBITRUM_SEPOLIA_RPC_URL=${{ secrets.ARBITRUM_SEPOLIA_RPC_URL }}" >> $GITHUB_ENV
echo "ARBISCAN_API_KEY=${{ secrets.ARBISCAN_API_KEY }}" >> $GITHUB_ENV
fi

if [ "${{ inputs.network }}" == "bellecour" ]; then
echo "BELLECOUR_RPC_URL=${{ secrets.BELLECOUR_RPC_URL }}" >> $GITHUB_ENV
fi

- name: Deploy contracts
run: |
echo "Deploying to: ${{ inputs.network }} with ${{ inputs.environment }} environment"
npm run deploy -- --network ${{ inputs.network }}

- name: Update config.json with ERC1538Proxy address
if: inputs.network != 'hardhat'
run: npx hardhat run scripts/tools/update-config.ts --network ${{ inputs.network }}

- name: Save deployment artifacts and updated config
if: inputs.network != 'hardhat'
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'chore: save deployment artifacts for ${{ inputs.network }} (${{ inputs.environment }}, ${{ github.run_id }})'
file_pattern: 'deployments/${{ inputs.network }}/* config/config.json'
commit_user_name: 'GitHub Actions Bot'
commit_user_email: 'github-actions[bot]@users.noreply.github.com'
commit_author: 'GitHub Actions Bot <github-actions[bot]@users.noreply.github.com>'
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- [x] `IexecPoco2Delegate.sol`

### Features
- Add gitub action workflow for deployment (#218)
- Fix new testnets chain name (#217)
- Deploy on new testnet chains using CreateX factory (#216)
- Add CreateX factory for new chain deployment (#215)
Expand Down
29 changes: 24 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# iExec PoCo Smart Contracts

[![codecov](https://codecov.io/github/iExecBlockchainComputing/PoCo/graph/badge.svg)](https://codecov.io/github/iExecBlockchainComputing/PoCo)

# Introduction
Expand Down Expand Up @@ -117,23 +119,40 @@ npm run test

## Deploy

You can deploy the smart contracts according to the [deploy/0_deploy.ts](./deploy/0_deploy.ts) content. This will automatically save some addresses of the deployed artifacts to the `./build` folder.
The iExec PoCo contracts support automated deployment through both command-line interface and GitHub Actions workflows.

### Command Line Deployment

You can deploy the smart contracts according to the [deploy/0_deploy.ts](./deploy/0_deploy.ts) content. This will automatically save some addresses of the deployed artifacts to the `./deployments` folder.

To do so:
To deploy using the CLI:

1. Make sure you followed the "Configure a deployment" section;
2. Enter your targeted blockchain parameters in `hardhat.config.ts` configuration file;
1. Make sure you followed the "Configure a deployment" section above
2. Enter your targeted blockchain parameters in `hardhat.config.ts`
3. Run the deployment using:

```
npx hardhat deploy --network <your network name>
```

Example of "complex" deployment:
Example with custom salt:

```
SALT=0x0000000000000000000000000000000000000000000000000000000000000001 npx hardhat deploy --network hardhat
```


### Manual Verification

To manually verify contracts:

```
npx hardhat run ./scripts/verify.ts --network <your network name>
```

This script automatically reads all deployed contract addresses and their constructor arguments from the deployment artifacts and verifies them on the relevant block explorer.


## Formatting

Format a specific file or files in a directory:
Expand Down
9 changes: 8 additions & 1 deletion deploy/0_deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ import { linkContractToProxy } from '../utils/proxy-tools';
*/
export default async function deploy() {
console.log('Deploying PoCo..');
const chainId = (await ethers.provider.getNetwork()).chainId;
const network = await ethers.provider.getNetwork();
const chainId = network.chainId;
const [owner] = await ethers.getSigners();
const deploymentOptions = config.getChainConfigOrDefault(chainId);
const factoryDeployer = new FactoryDeployer(owner, chainId);
Expand Down Expand Up @@ -209,6 +210,12 @@ export default async function deploy() {
for (let i = 0; i < Number(catCountAfter); i++) {
console.log(`Category ${i}: ${await iexecAccessorsInstance.viewCategory(i)}`);
}

if (network.name !== 'hardhat' && network.name !== 'localhost') {
console.log('Waiting for block explorer to index the contracts...');
await new Promise((resolve) => setTimeout(resolve, 60000));
await import('../scripts/verify').then((module) => module.default());
}
}

async function getOrDeployRlc(token: string, owner: SignerWithAddress) {
Expand Down
15 changes: 9 additions & 6 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,10 @@ const config: HardhatUserConfig = {
},
},
// Add Fuji as a network
avalancheFuji: {
avalancheFujiTestnet: {
url: process.env.FUJI_RPC_URL || 'https://api.avax-test.network/ext/bc/C/rpc',
accounts: [
process.env.DEV_PRIVATE_KEY ||
process.env.PRIVATE_KEY ||
'0x0000000000000000000000000000000000000000000000000000000000000000',
],
...fujiBaseConfig,
Expand All @@ -187,7 +187,7 @@ const config: HardhatUserConfig = {
arbitrumSepolia: {
url: process.env.ARBITRUM_SEPOLIA_RPC_URL || 'https://sepolia-rollup.arbitrum.io/rpc',
accounts: [
process.env.DEV_PRIVATE_KEY ||
process.env.PRIVATE_KEY ||
'0x0000000000000000000000000000000000000000000000000000000000000000',
],
...arbitrumSepoliaBaseConfig,
Expand All @@ -204,7 +204,7 @@ const config: HardhatUserConfig = {
chainId: 134,
url: 'https://bellecour.iex.ec',
accounts: [
process.env.PROD_PRIVATE_KEY ||
process.env.PRIVATE_KEY ||
'0x0000000000000000000000000000000000000000000000000000000000000000',
],
...bellecourBaseConfig,
Expand All @@ -219,7 +219,7 @@ const config: HardhatUserConfig = {
etherscan: {
apiKey: {
mainnet: process.env.ETHERSCAN_API_KEY || '',
avalancheFuji: 'nothing', // a non-empty string is needed by the plugin.
avalancheFujiTestnet: 'nothing', // a non-empty string is needed by the plugin.
arbitrumSepolia: process.env.ARBISCAN_API_KEY || '',
viviani: 'nothing', // a non-empty string is needed by the plugin.
bellecour: 'nothing', // a non-empty string is needed by the plugin.
Expand All @@ -243,6 +243,9 @@ const config: HardhatUserConfig = {
},
],
},
sourcify: {
enabled: true,
},
typechain: {
outDir: 'typechain',
},
Expand Down Expand Up @@ -316,7 +319,7 @@ task('test').setAction(async (taskArgs: any, hre, runSuper) => {
networkName = 'arbitrumSepolia';
deploymentsCopied = await copyDeployments(networkName);
} else if (process.env.FUJI_FORK === 'true') {
networkName = 'avalancheFuji';
networkName = 'avalancheFujiTestnet';
deploymentsCopied = await copyDeployments(networkName);
}
await runSuper(taskArgs);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"clean": "rm -rf deployments/hardhat",
"test": "npm run clean && REPORT_GAS=true npx hardhat test",
"test:arbitrumSepolia": "npm run clean && ARBITRUM_SEPOLIA_FORK=true npx hardhat test",
"test:avalancheFuji": "npm run clean && FUJI_FORK=true npx hardhat test",
"test:avalancheFujiTestnet": "npm run clean && FUJI_FORK=true npx hardhat test",
"test:native": "npm run clean && TEST__IS_NATIVE_CHAIN=true npx hardhat test test/byContract/IexecEscrow/IexecEscrowNative.test.ts",
"coverage": "npx hardhat coverage",
"verify": "npx hardhat verify",
Expand Down
1 change: 1 addition & 0 deletions scripts/boost/0_deploy-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const genericFactoryAddress = require('@amxx/factory/deployments/GenericFactory.
await deployments.save(module.name, {
abi: [],
address: moduleAddress,
bytecode: module.bytecode,
});
}
})();
2 changes: 1 addition & 1 deletion scripts/sponsoring/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ npx hardhat --network bellecour etherscan-verify
```
and embedded `hardhat-verify` plugin of `hardhat` (v2.22.12):
```
npx hardhat run ./scripts/sponsoring/verify.ts --network bellecour
npx hardhat run ./scripts/verify.ts --network bellecour
```
by previously modifiying the `.json` file produced by:
```
Expand Down
22 changes: 0 additions & 22 deletions scripts/sponsoring/verify.ts

This file was deleted.

68 changes: 68 additions & 0 deletions scripts/tools/update-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as fs from 'fs';
import { deployments, ethers } from 'hardhat';
import * as path from 'path';
import config from '../../utils/config';

// Get the absolute path to the config file
const configPath = path.resolve('config/config.json');

async function main(): Promise<void> {
// Get network info from ethers
const network = await ethers.provider.getNetwork();
const networkName = network.name;
const chainId = network.chainId.toString();

console.log(`Working with network: ${networkName} (Chain ID: ${chainId})`);
const deployment = await deployments.get('ERC1538Proxy');
const contractAddress = deployment.address;

if (!contractAddress || contractAddress === 'null') {
console.error(`Failed to extract a valid ERC1538Proxy address from deployment file`);
process.exit(1);
}

console.log(`Found ERC1538Proxy address: ${contractAddress}`);
const localConfig = config;

// Ensure the chain structure exists
if (!localConfig.chains) {
localConfig.chains = {};
}

if (!localConfig.chains[chainId]) {
localConfig.chains[chainId] = {
_comment: `Chain ${chainId} (${networkName})`,
asset: 'Token', // Default value, update as needed
v3: {
Hub: null,
AppRegistry: null,
DatasetRegistry: null,
WorkerpoolRegistry: null,
},
v5: {},
};
}

if (!localConfig.chains[chainId].v5) {
localConfig.chains[chainId].v5 = {};
}

const contractKey = 'ERC1538Proxy';
const previousValue = localConfig.chains[chainId].v5[contractKey] || 'null';
localConfig.chains[chainId].v5[contractKey] = contractAddress;

// Write the updated config back to file
fs.writeFileSync(configPath, JSON.stringify(localConfig, null, 2));

console.log(`Updated ${chainId}.v5.${contractKey}:`);
console.log(`Previous: ${previousValue}`);
console.log(`New: ${contractAddress}`);
}

// Execute the main function and handle any errors
main()
.then(() => process.exit(0))
.catch((error) => {
console.error('Error in update-config script:', error);
process.exit(1);
});
Loading