Skip to content

Commit 50b772f

Browse files
chore: Update upgrade report and clean upgrade script (#296)
Co-authored-by: gfournieriExec <[email protected]>
1 parent 6b91de4 commit 50b772f

File tree

10 files changed

+119
-115
lines changed

10 files changed

+119
-115
lines changed

.github/workflows/deploy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ jobs:
4848
run: npm run build
4949

5050
# TODO activate later.
51+
# Checks of initial state fails (e.g., balanceOf(proxyAddress) !== 0).
5152
# - name: Run fork tests
5253
# run: |
5354
# if [ "${{ inputs.network }}" == "arbitrumSepolia" ]; then

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: PoCo Contracts CI
33
on:
44
push:
55
branches:
6-
- main
6+
- main # To trigger coverage updates of `main` on Codecov
77
pull_request:
88
workflow_call:
99

contracts/IexecInterfaceToken.sol

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import {IexecRelay} from "./interfaces/IexecRelay.sol";
1919
import {IexecTokenSpender} from "./interfaces/IexecTokenSpender.sol";
2020
import {IOwnable} from "./interfaces/IOwnable.sol";
2121

22+
// TODO see if Diamond interfaces should be added here ??
23+
// IDiamond, IDiamondLoupe, IDiamondCut, IERC165, IERC173 (ownership)
24+
2225
/**
2326
* A global interface that aggregates all the interfaces needed to interact with
2427
* the PoCo contracts in token mode.

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ import {
1212
import { Ownable__factory } from '../../typechain/factories/rlc-faucet-contract/contracts';
1313
import config from '../../utils/config';
1414
import { getDeployerAndOwnerSigners } from '../../utils/deploy-tools';
15-
import {
16-
encodeModuleProxyUpdate,
17-
printBlockTime,
18-
printFunctions,
19-
} from '../upgrades/upgrade-helper';
15+
import { encodeModuleProxyUpdate, printBlockTime } from '../upgrades/upgrade-helper';
16+
import { printOnchainProxyFunctions } from '../../utils/proxy-tools';
2017

2118
(async () => {
2219
const chainId = (await ethers.provider.getNetwork()).chainId;
@@ -78,7 +75,7 @@ import {
7875
await time.increase(delay);
7976
console.log('Time traveling..');
8077
await printBlockTime();
81-
await printFunctions(diamondProxyAddress);
78+
await printOnchainProxyFunctions(diamondProxyAddress);
8279
console.log('Executing proxy update..');
8380
await timelockInstance
8481
.connect(timelockAdminSigner)
@@ -87,5 +84,5 @@ import {
8784
console.log(tx);
8885
tx.wait();
8986
});
90-
await printFunctions(diamondProxyAddress);
87+
await printOnchainProxyFunctions(diamondProxyAddress);
9188
})();

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@ import {
1313
TimelockController__factory,
1414
} from '../../typechain';
1515
import config from '../../utils/config';
16-
import {
17-
encodeModuleProxyUpdate,
18-
printBlockTime,
19-
printFunctions,
20-
} from '../upgrades/upgrade-helper';
16+
import { encodeModuleProxyUpdate, printBlockTime } from '../upgrades/upgrade-helper';
17+
import { printOnchainProxyFunctions } from '../../utils/proxy-tools';
2118

2219
if (process.env.HANDLE_SPONSORING_UPGRADE_INTERNALLY != 'true') {
2320
(async () => {
@@ -42,7 +39,7 @@ export async function addModulesToProxy() {
4239
const iexecPoco2FacetAddress = (await hre.deployments.get('IexecPoco2Facet')).address;
4340
const iexecPocoAccessorsFacetAddress = (await hre.deployments.get('IexecPocoAccessorsFacet'))
4441
.address;
45-
await printFunctions(diamondProxyAddress);
42+
await printOnchainProxyFunctions(diamondProxyAddress);
4643

4744
console.log('Functions about to be added to proxy:');
4845
const timelockAddress = await Ownable__factory.connect(
@@ -126,7 +123,7 @@ export async function addModulesToProxy() {
126123

127124
async function executeUpgrade() {
128125
await printBlockTime();
129-
await printFunctions(diamondProxyAddress);
126+
await printOnchainProxyFunctions(diamondProxyAddress);
130127
console.log('Executing proxy update..');
131128
await timelockInstance
132129
.connect(timelockAdminSigner)
@@ -135,6 +132,6 @@ export async function addModulesToProxy() {
135132
console.log(x);
136133
return x.wait();
137134
});
138-
await printFunctions(diamondProxyAddress);
135+
await printOnchainProxyFunctions(diamondProxyAddress);
139136
}
140137
}

scripts/upgrades/upgrade-helper.ts

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

4-
import { ContractFactory, Interface, ZeroAddress } from 'ethers';
4+
import { ContractFactory, ZeroAddress } from 'ethers';
55
import { ethers } from 'hardhat';
66
import { FacetCutAction } from 'hardhat-deploy/dist/types';
7-
import {
8-
DiamondCutFacet__factory,
9-
DiamondLoupeFacet__factory,
10-
IexecAccessorsABILegacyFacet__factory,
11-
IexecCategoryManagerFacet__factory,
12-
IexecConfigurationExtraFacet__factory,
13-
IexecConfigurationFacet__factory,
14-
IexecERC20Facet__factory,
15-
IexecEscrowNativeFacet__factory,
16-
IexecEscrowTokenFacet__factory,
17-
IexecEscrowTokenSwapFacet__factory,
18-
IexecOrderManagementFacet__factory,
19-
IexecPoco1Facet__factory,
20-
IexecPoco2Facet__factory,
21-
IexecPocoAccessorsFacet__factory,
22-
IexecPocoBoostAccessorsFacet__factory,
23-
IexecPocoBoostFacet__factory,
24-
IexecRelayFacet__factory,
25-
OwnershipFacet__factory,
26-
} from '../../typechain';
7+
import { DiamondCutFacet__factory } from '../../typechain';
278
import { getFunctionSelectors } from '../../utils/proxy-tools';
289

2910
function encodeModuleProxyUpdate(contractFactory: ContractFactory, moduleAddress: string) {
@@ -55,72 +36,4 @@ async function printBlockTime() {
5536
}
5637
}
5738

58-
async function printFunctions(diamondProxyAddress: string) {
59-
const diamondLoupeInstance = DiamondLoupeFacet__factory.connect(
60-
diamondProxyAddress,
61-
ethers.provider,
62-
);
63-
const facets = await diamondLoupeInstance.facets();
64-
65-
const allInterfaces: Interface[] = [
66-
OwnershipFacet__factory.createInterface(),
67-
DiamondCutFacet__factory.createInterface(),
68-
DiamondLoupeFacet__factory.createInterface(),
69-
IexecAccessorsABILegacyFacet__factory.createInterface(),
70-
IexecCategoryManagerFacet__factory.createInterface(),
71-
IexecConfigurationExtraFacet__factory.createInterface(),
72-
IexecConfigurationFacet__factory.createInterface(),
73-
IexecERC20Facet__factory.createInterface(),
74-
IexecEscrowNativeFacet__factory.createInterface(),
75-
IexecEscrowTokenFacet__factory.createInterface(),
76-
IexecEscrowTokenSwapFacet__factory.createInterface(),
77-
IexecOrderManagementFacet__factory.createInterface(),
78-
IexecPoco1Facet__factory.createInterface(),
79-
IexecPoco2Facet__factory.createInterface(),
80-
IexecPocoAccessorsFacet__factory.createInterface(),
81-
IexecPocoBoostAccessorsFacet__factory.createInterface(),
82-
IexecPocoBoostFacet__factory.createInterface(),
83-
IexecRelayFacet__factory.createInterface(),
84-
];
85-
const selectorToName = new Map<string, string>();
86-
for (const iface of allInterfaces) {
87-
for (const fragment of iface.fragments) {
88-
if (fragment.type === 'function') {
89-
const signature = fragment.format();
90-
const funcFragment = iface.getFunction(signature);
91-
if (funcFragment) {
92-
selectorToName.set(funcFragment.selector, funcFragment.name);
93-
}
94-
}
95-
}
96-
}
97-
98-
let totalFunctions = 0;
99-
facets.forEach((facet) => {
100-
totalFunctions += facet.functionSelectors.length;
101-
});
102-
103-
console.log(`DiamondProxy supports ${totalFunctions} functions:`);
104-
105-
let functionIndex = 0;
106-
for (const facet of facets) {
107-
for (const selector of facet.functionSelectors) {
108-
let functionName = selector; // Default to selector if we can't decode
109-
// Special cases for special functions
110-
if (selector === '0x00000000') {
111-
functionName = 'receive()';
112-
} else if (selector === '0xffffffff') {
113-
functionName = 'fallback()';
114-
} else {
115-
const name = selectorToName.get(selector);
116-
if (name) {
117-
functionName = name;
118-
}
119-
}
120-
console.log(`[${functionIndex}] ${facet.facetAddress} ${functionName}`);
121-
functionIndex++;
122-
}
123-
}
124-
}
125-
126-
export { encodeModuleProxyUpdate, printBlockTime, printFunctions };
39+
export { encodeModuleProxyUpdate, printBlockTime };

scripts/upgrades/v6.1.0-bulk-processing.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@
1212

1313
## Summary of changes
1414

15+
- Removes unintentionally added constants getters by changing constants visibility to `internal`.
16+
These functions were introduced as a side-effect of the migration to the Diamond proxy but they are
17+
used nowhere. They are duplicate of other existing functions:
18+
- `CONTRIBUTION_DEADLINE_RATIO()`
19+
- `FINAL_DEADLINE_RATIO()`
20+
- `GROUPMEMBER_PURPOSE()`
21+
- `KITTY_ADDRESS()`
22+
- `KITTY_MIN()`
23+
- `KITTY_RATIO()`
24+
- `REVEAL_DEADLINE_RATIO()`
25+
- `WORKERPOOL_STAKE_RATIO()`
1526
- Add functions `viewApp`, `viewDataset`, and `viewWorkerpool` to read asset's details in a single transaction.
1627
- Add function `assertDatasetDealCompatibility` to allow the SMS to check compatibility of Bulk orders with a given deal.
1728

scripts/upgrades/v6.1.0-bulk-processing.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ import { Ownable__factory } from '../../typechain/factories/rlc-faucet-contract/
1616
import { FactoryDeployer } from '../../utils/FactoryDeployer';
1717
import config from '../../utils/config';
1818
import { getDeployerAndOwnerSigners } from '../../utils/deploy-tools';
19-
import { linkContractToProxy } from '../../utils/proxy-tools';
19+
import { linkContractToProxy, printOnchainProxyFunctions } from '../../utils/proxy-tools';
2020
import { tryVerify } from '../verify';
21-
import { printFunctions } from './upgrade-helper';
2221

2322
async function main() {
2423
console.log('Deploying and updating IexecPocoAccessorsFacet & IexecPoco1Facet...');
@@ -122,7 +121,7 @@ async function removeOldFacetsFromDiamond(diamondProxyAsOwner: DiamondCutFacet,
122121
});
123122

124123
console.log('Diamond functions before upgrade:');
125-
await printFunctions(diamondProxyAddress);
124+
await printOnchainProxyFunctions(diamondProxyAddress);
126125

127126
const removalCuts: IDiamond.FacetCutStruct[] = [];
128127

@@ -182,7 +181,7 @@ async function removeOldFacetsFromDiamond(diamondProxyAsOwner: DiamondCutFacet,
182181
await removeTx.wait();
183182
console.log(`Transaction hash: ${removeTx.hash}`);
184183
console.log('Diamond functions after removing old facets:');
185-
await printFunctions(diamondProxyAddress);
184+
await printOnchainProxyFunctions(diamondProxyAddress);
186185
}
187186
}
188187

@@ -208,7 +207,7 @@ async function linkNewFacetsToDiamond(
208207
console.log('New IexecPoco1Facet with assertDatasetDealCompatibility added successfully');
209208

210209
console.log('Diamond functions after adding new facets:');
211-
await printFunctions(diamondProxyAddress);
210+
await printOnchainProxyFunctions(diamondProxyAddress);
212211

213212
console.log('\nUpgrade completed successfully!');
214213
console.log(`New IexecPocoAccessorsFacet deployed at: ${iexecPocoAccessorsFacet}`);

utils/FactoryDeployer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class FactoryDeployer {
3333
call?: string,
3434
): Promise<string> {
3535
await this.initFactory();
36+
// TODO merge common parts of both deployment methods.
3637
if (this.factoryType === 'createx') {
3738
return await this.deployWithCreateX(contractFactory, constructorArgs, call);
3839
}

utils/proxy-tools.ts

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

4-
import { ContractFactory, ZeroAddress } from 'ethers';
4+
import { ContractFactory, FunctionFragment, Interface, ZeroAddress } from 'ethers';
55
import { ethers } from 'hardhat';
66
import { FacetCut, FacetCutAction } from 'hardhat-deploy/dist/types';
7-
import { DiamondCutFacet, DiamondLoupeFacet__factory } from '../typechain';
7+
import {
8+
DiamondCutFacet,
9+
DiamondCutFacet__factory,
10+
DiamondLoupeFacet__factory,
11+
OwnershipFacet__factory,
12+
IexecAccessorsABILegacyFacet__factory,
13+
IexecCategoryManagerFacet__factory,
14+
IexecConfigurationExtraFacet__factory,
15+
IexecConfigurationFacet__factory,
16+
IexecERC20Facet__factory,
17+
IexecEscrowNativeFacet__factory,
18+
IexecEscrowTokenFacet__factory,
19+
IexecEscrowTokenSwapFacet__factory,
20+
IexecOrderManagementFacet__factory,
21+
IexecPoco1Facet__factory,
22+
IexecPoco2Facet__factory,
23+
IexecPocoAccessorsFacet__factory,
24+
IexecPocoBoostAccessorsFacet__factory,
25+
IexecPocoBoostFacet__factory,
26+
IexecRelayFacet__factory,
27+
} from '../typechain';
828
import { getBaseNameFromContractFactory } from '../utils/deploy-tools';
929

1030
const POCO_STORAGE_LOCATION = '0x5862653c6982c162832160cf30593645e8487b257e44d77cdd6b51eee2651b00';
@@ -29,6 +49,8 @@ export async function linkContractToProxy(
2949
contractAddress: string,
3050
contractFactory: ContractFactory,
3151
) {
52+
const contractName = getBaseNameFromContractFactory(contractFactory);
53+
console.log(`Linking ${contractName} to proxy`);
3254
// Fetch existing selectors from the proxy.
3355
const existingSelectors = await DiamondLoupeFacet__factory.connect(
3456
await proxy.getAddress(),
@@ -39,7 +61,7 @@ export async function linkContractToProxy(
3961
// Get the contract selectors from its ABI.
4062
const contractSelectors = getFunctionSelectors(contractFactory);
4163
// Exclude existing selectors to avoid the error `CannotAddFunctionToDiamondThatAlreadyExists`.
42-
// This appears for `owner()` function.
64+
// This appears for `owner()` function for example.
4365
const selectors = contractSelectors.filter((selector) => !existingSelectors.includes(selector));
4466
const facetCut: FacetCut = {
4567
facetAddress: contractAddress,
@@ -50,7 +72,6 @@ export async function linkContractToProxy(
5072
.diamondCut([facetCut], ZeroAddress, '0x')
5173
.then((tx) => tx.wait())
5274
.catch((err) => {
53-
const contractName = getBaseNameFromContractFactory(contractFactory);
5475
console.log(`Failed to link ${contractName} to proxy:`);
5576
throw err;
5677
});
@@ -87,3 +108,64 @@ export function getFunctionSelectors(contractFactory: ContractFactory): string[]
87108
})
88109
);
89110
}
111+
112+
export function getAllLocalFacetFunctions(): Map<string, string> {
113+
// TODO update this when new facets are added.
114+
// TODO read `contracts/facets` folder to avoid manual updates.
115+
const allInterfaces: Interface[] = [
116+
DiamondCutFacet__factory.createInterface(),
117+
DiamondLoupeFacet__factory.createInterface(),
118+
OwnershipFacet__factory.createInterface(),
119+
IexecAccessorsABILegacyFacet__factory.createInterface(),
120+
IexecCategoryManagerFacet__factory.createInterface(),
121+
IexecConfigurationExtraFacet__factory.createInterface(),
122+
IexecConfigurationFacet__factory.createInterface(),
123+
IexecERC20Facet__factory.createInterface(),
124+
IexecEscrowNativeFacet__factory.createInterface(),
125+
IexecEscrowTokenFacet__factory.createInterface(),
126+
IexecEscrowTokenSwapFacet__factory.createInterface(),
127+
IexecOrderManagementFacet__factory.createInterface(),
128+
IexecPoco1Facet__factory.createInterface(),
129+
IexecPoco2Facet__factory.createInterface(),
130+
IexecPocoAccessorsFacet__factory.createInterface(),
131+
IexecPocoBoostAccessorsFacet__factory.createInterface(),
132+
IexecPocoBoostFacet__factory.createInterface(),
133+
IexecRelayFacet__factory.createInterface(),
134+
];
135+
// TODO update `getFunctionSelectors` and use it here to avoid duplication.
136+
const fragments: [string, string][] = allInterfaces
137+
.flatMap((iface) => iface.fragments)
138+
.filter((fragment) => fragment.type === 'function')
139+
.map((fragment) => fragment as FunctionFragment)
140+
.map((fragment) => [fragment.selector, fragment.name] as [string, string])
141+
.concat([
142+
['receive', '0x00000000'], // fragment.type is 'fallback'
143+
['fallback', '0xffffffff'], // fragment.type is 'fallback'
144+
]);
145+
const selectorToName = new Map<string, string>(fragments);
146+
return selectorToName;
147+
}
148+
149+
export async function printOnchainProxyFunctions(diamondProxyAddress: string) {
150+
const selectorToName = getAllLocalFacetFunctions();
151+
const facetsOnchain = await DiamondLoupeFacet__factory.connect(
152+
diamondProxyAddress,
153+
ethers.provider,
154+
).facets();
155+
let totalFunctions = 0;
156+
facetsOnchain.forEach((facet) => {
157+
totalFunctions += facet.functionSelectors.length;
158+
});
159+
console.log(
160+
`Onchain diamond proxy has ${facetsOnchain.length} facets and ${totalFunctions} total functions:`,
161+
);
162+
let i = 0;
163+
for (const facet of facetsOnchain) {
164+
for (const selector of facet.functionSelectors) {
165+
// Fallback to the selector if the name is not found.
166+
const functionName = selectorToName.get(selector) ?? selector;
167+
console.log(`[${i}] ${facet.facetAddress} ${functionName}`);
168+
i++;
169+
}
170+
}
171+
}

0 commit comments

Comments
 (0)