Skip to content

Commit b4963d2

Browse files
authored
feat: refactor upgrade-helper to use DiamondCut for module updates (#235)
2 parents 3b43823 + 7c758c9 commit b4963d2

File tree

5 files changed

+68
-38
lines changed

5 files changed

+68
-38
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
on:
2-
push:
3-
branches:
4-
- feature/*
5-
- bugfix/*
6-
- develop
7-
- release/*
8-
- hotfix/*
9-
- main
10-
- v5
2+
pull_request:
113

124
jobs:
135
# Note: changing the name of the job disables Slither checks with the error:
@@ -48,7 +40,7 @@ jobs:
4840
- name: Run static analysis with Slither
4941
uses: crytic/[email protected]
5042
with:
51-
target: "contracts/tools/testing/slither/"
43+
target: 'contracts/tools/testing/slither/'
5244
solc-version: '0.8.21'
5345
slither-args: --checklist --markdown-root ${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/
5446
fail-on: none # TODO set this to high or other

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Target latest EVM version (#239)
88
- Adapt contracts file tree (#238)
99
- Use namespaced storage (#236, #237)
10+
- Fix script folder (#235)
1011
- Format all solidity files (#233)
1112
- Rename ERC1538 architure to diamond Proxy architecture(#226, #229, #230, #234)
1213
- Remove ENS module (#225)

scripts/boost/1_add-modules-to-proxy.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { time } from '@nomicfoundation/hardhat-network-helpers';
55
import { BytesLike, ZeroHash } from 'ethers';
66
import { deployments, ethers } from 'hardhat';
77
import {
8-
IexecPocoBoostAccessors__factory,
9-
IexecPocoBoost__factory,
8+
IexecPocoBoostAccessorsFacet__factory,
9+
IexecPocoBoostFacet__factory,
1010
TimelockController__factory,
1111
} from '../../typechain';
1212
import { Ownable__factory } from '../../typechain/factories/rlc-faucet-contract/contracts';
@@ -24,19 +24,28 @@ import {
2424
if (!deploymentOptions.DiamondProxy) {
2525
throw new Error('DiamondProxy is required');
2626
}
27+
if (!deploymentOptions.IexecLibOrders_v5) {
28+
throw new Error('IexecLibOrders_v5 is required');
29+
}
2730
const diamondProxyAddress = deploymentOptions.DiamondProxy;
2831
const iexecPocoBoostFacetAddress = (await deployments.get('IexecPocoBoostFacet')).address; // Bellecour: 0x8425229f979AB3b0dDDe00D475D762cA4d6a5eFc
2932
const iexecPocoBoostAccessorsFacetAddress = (
3033
await deployments.get('IexecPocoBoostAccessorsFacet')
3134
).address; // Bellecour: 0x56185a2b0dc8b556BBfBAFB702BC971Ed75e868C
3235
const [account] = await ethers.getSigners();
3336
const timelockAddress = await Ownable__factory.connect(diamondProxyAddress, account).owner(); // Bellecour: 0x4611B943AA1d656Fc669623b5DA08756A7e288E9
37+
38+
const iexecLibOrders = {
39+
['contracts/libs/IexecLibOrders_v5.sol:IexecLibOrders_v5']:
40+
deploymentOptions.IexecLibOrders_v5,
41+
};
42+
3443
const iexecPocoBoostProxyUpdate = encodeModuleProxyUpdate(
35-
IexecPocoBoost__factory.createInterface(),
44+
new IexecPocoBoostFacet__factory(iexecLibOrders),
3645
iexecPocoBoostFacetAddress,
3746
);
3847
const iexecPocoBoostAccessorsProxyUpdate = encodeModuleProxyUpdate(
39-
IexecPocoBoostAccessors__factory.createInterface(),
48+
new IexecPocoBoostAccessorsFacet__factory(),
4049
iexecPocoBoostAccessorsFacetAddress,
4150
);
4251
// Salt but must be the same for schedule & execute

scripts/sponsoring/1_add-modules-to-proxy.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ export async function addModulesToProxy() {
3232
if (!deploymentOptions.DiamondProxy) {
3333
throw new Error('DiamondProxy is required');
3434
}
35+
if (!deploymentOptions.IexecLibOrders_v5) {
36+
throw new Error('IexecLibOrders_v5 is required');
37+
}
3538
const diamondProxyAddress = deploymentOptions.DiamondProxy;
3639
const iexecOrderManagementAddress = (await hre.deployments.get('IexecOrderManagementFacet'))
3740
.address;
@@ -46,20 +49,26 @@ export async function addModulesToProxy() {
4649
diamondProxyAddress,
4750
ethers.provider,
4851
).owner();
52+
53+
const iexecLibOrders = {
54+
['contracts/libs/IexecLibOrders_v5.sol:IexecLibOrders_v5']:
55+
deploymentOptions.IexecLibOrders_v5,
56+
};
57+
4958
const iexecOrderManagementProxyUpdate = encodeModuleProxyUpdate(
50-
IexecOrderManagementFacet__factory.createInterface(),
59+
new IexecOrderManagementFacet__factory(iexecLibOrders),
5160
iexecOrderManagementAddress,
5261
);
5362
const iexecPoco1ProxyUpdate = encodeModuleProxyUpdate(
54-
IexecPoco1Facet__factory.createInterface(),
63+
new IexecPoco1Facet__factory(iexecLibOrders),
5564
iexecPoco1FacetAddress,
5665
);
5766
const iexecPoco2ProxyUpdate = encodeModuleProxyUpdate(
58-
IexecPoco2Facet__factory.createInterface(),
67+
new IexecPoco2Facet__factory(),
5968
iexecPoco2FacetAddress,
6069
);
6170
const iexecPocoAccessorsProxyUpdate = encodeModuleProxyUpdate(
62-
IexecPocoAccessorsFacet__factory.createInterface(),
71+
new IexecPocoAccessorsFacet__factory(iexecLibOrders),
6372
iexecPocoAccessorsFacetAddress,
6473
);
6574
// The salt must be the same for a given schedule & execute operation set

scripts/upgrades/upgrade-helper.ts

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
// SPDX-FileCopyrightText: 2024-2025 IEXEC BLOCKCHAIN TECH <[email protected]>
22
// SPDX-License-Identifier: Apache-2.0
33

4-
import { Interface } from 'ethers';
4+
import { ContractFactory, ZeroAddress } from 'ethers';
55
import { ethers } from 'hardhat';
6-
import { ERC1538Query, ERC1538Query__factory, ERC1538Update__factory } from '../../typechain';
7-
8-
function encodeModuleProxyUpdate(ModuleInterface: Interface, moduleAddress: string) {
9-
let moduleFunctions = '';
10-
ModuleInterface.forEachFunction((functionFragment) => {
11-
const func = functionFragment.format();
12-
console.log(`- ${func}`);
13-
moduleFunctions += func + ';';
14-
});
15-
const moduleProxyUpdateData = ERC1538Update__factory.createInterface().encodeFunctionData(
16-
'updateContract',
17-
[moduleAddress, moduleFunctions, ''],
6+
import { FacetCutAction } from 'hardhat-deploy/dist/types';
7+
import { DiamondCutFacet__factory, DiamondLoupeFacet__factory } from '../../typechain';
8+
import { getFunctionSelectors } from '../../utils/proxy-tools';
9+
10+
function encodeModuleProxyUpdate(contractFactory: ContractFactory, moduleAddress: string) {
11+
// Get function selectors from the contract factory
12+
const functionSelectors = getFunctionSelectors(contractFactory);
13+
14+
// Create FacetCut for adding the module
15+
const facetCut = {
16+
facetAddress: moduleAddress,
17+
action: FacetCutAction.Add,
18+
functionSelectors: functionSelectors,
19+
};
20+
21+
// Encode diamondCut call
22+
const moduleProxyUpdateData = DiamondCutFacet__factory.createInterface().encodeFunctionData(
23+
'diamondCut',
24+
[[facetCut], ZeroAddress, '0x'],
1825
);
1926
return moduleProxyUpdateData;
2027
}
@@ -29,17 +36,29 @@ async function printBlockTime() {
2936
}
3037
}
3138

32-
// TODO: update this function to use DiamondLoup
3339
async function printFunctions(diamondProxyAddress: string) {
34-
const diamondQueryInstance: ERC1538Query = ERC1538Query__factory.connect(
40+
const diamondLoupeInstance = DiamondLoupeFacet__factory.connect(
3541
diamondProxyAddress,
3642
ethers.provider,
3743
);
38-
const functionCount = Number(await diamondQueryInstance.totalFunctions());
39-
console.log(`DiamondProxy supports ${functionCount} functions:`);
40-
for (let i = 0; i < functionCount; i++) {
41-
const [method, , contract] = await diamondQueryInstance.functionByIndex(i);
42-
console.log(`[${i}] ${contract} ${method}`);
44+
const facets = await diamondLoupeInstance.facets();
45+
46+
let totalFunctions = 0;
47+
facets.forEach((facet) => {
48+
totalFunctions += facet.functionSelectors.length;
49+
});
50+
51+
console.log(`DiamondProxy supports ${totalFunctions} functions:`);
52+
53+
let functionIndex = 0;
54+
for (const facet of facets) {
55+
for (const selector of facet.functionSelectors) {
56+
// Try to decode the selector to a readable function signature
57+
// Note: We can't easily get the full function signature from just the selector
58+
// This is a limitation compared to ERC1538Query.functionByIndex
59+
console.log(`[${functionIndex}] ${facet.facetAddress} ${selector}`);
60+
functionIndex++;
61+
}
4362
}
4463
}
4564

0 commit comments

Comments
 (0)