Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
28e8bce
chore: Merge duplicate v6 and v8 files
zguesmi Oct 13, 2025
9ca27e0
chore: Upgrade all contracts except registries to solidity v8
zguesmi Oct 13, 2025
52306f8
chore: Remove unused token swap facet
zguesmi Oct 13, 2025
d5ed77e
chore: Create new solidity v8 IexecHubInterface
zguesmi Oct 13, 2025
803617d
chore: Merge branch 'main' into chore/solidity-v8
zguesmi Oct 14, 2025
aa24086
chore: Copy referenced iexec-solidity contracts
zguesmi Oct 14, 2025
6253cb1
chore: Bump upgradability contracts to solidity v8
zguesmi Oct 14, 2025
74e680c
chore: Fix deploy script
zguesmi Oct 14, 2025
4c8fff6
fix: Fix migrated function
zguesmi Oct 14, 2025
0bd5fc9
chore: Migrate registries to Solidity v8
zguesmi Oct 14, 2025
c4555ec
chore: Remove comment
zguesmi Oct 14, 2025
2290871
test: Fix tests
zguesmi Oct 14, 2025
ed949b6
chore: Clean IexecHub v3 interface
zguesmi Oct 14, 2025
fe64f64
chore: Clean copied `Address` library
zguesmi Oct 14, 2025
8939418
chore: Update ABIs
zguesmi Oct 14, 2025
8a84932
test: Fix tests
zguesmi Oct 14, 2025
172fb20
chore: Clean
zguesmi Oct 14, 2025
3a9a34d
chore: Merge branch 'main' into chore/solidity-v8
zguesmi Oct 16, 2025
9843456
chore: Merge branch 'main' into chore/solidity-v8
zguesmi Oct 20, 2025
4495c42
Merge branch 'main' into chore/solidity-v8
zguesmi Oct 24, 2025
6e9655e
chore: Fix deployment
zguesmi Oct 24, 2025
ecaf5fb
Merge branch 'main' into chore/solidity-v8
zguesmi Oct 24, 2025
df0c137
Merge branch 'main' into chore/solidity-v8
Le-Caignec Oct 28, 2025
0d38aad
chore: Merge branch 'main' into chore/solidity-v8
zguesmi Oct 30, 2025
1d937ca
chore: Apply copilot suggestions
zguesmi Oct 30, 2025
5f29e02
chore: Merge branch 'main' into chore/solidity-v8
zguesmi Nov 3, 2025
18c4087
chore: Clean
zguesmi Nov 3, 2025
a96cf86
chore: Merge branch 'main' into chore/solidity-v8
zguesmi Nov 3, 2025
543e3d6
chore: Update ABIs
zguesmi Nov 3, 2025
7931651
Merge branch 'main' into chore/solidity-v8
zguesmi Nov 4, 2025
0c76839
chore: Merge branch 'main' into chore/solidity-v8
zguesmi Nov 5, 2025
4bab677
chore: Add notes to registry contracts
zguesmi Nov 5, 2025
c7b8067
feat: make Solidity `V8` migration non breaking (#306)
Le-Caignec Nov 6, 2025
7f2865f
feat: clean OpenZeppelin dual-version setup (#308)
Le-Caignec Nov 6, 2025
f30ad4a
chore: Remove unused iexec NPM packages `@iexec/interface` and `@iexe…
zguesmi Nov 6, 2025
a8d8779
style: Run formatter (#317)
gfournierPro Nov 7, 2025
4100b90
feat: Enable deposit and match orders in a single tx (#316)
gfournierPro Nov 10, 2025
f181251
Merge branch 'main' into chore/solidity-v8
Le-Caignec Nov 12, 2025
d2c510f
fix: fix doc (#322)
Le-Caignec Nov 12, 2025
2ce2be0
fix: update doc
Le-Caignec Nov 12, 2025
25c5720
docs: Remove outdated FacetBase and IexecERC20Base sections
Le-Caignec Nov 12, 2025
f2b61e1
feat: enhance order matching logic for dataset tags compatibility
gfournierPro Nov 12, 2025
ba6c57d
fix: update generate doc command (#324)
gfournierPro Nov 12, 2025
b58d068
Merge branch 'chore/solidity-v8' into feat/deal-with-tag
gfournierPro Nov 12, 2025
900c30e
fix: Merge `IexecERC20Common` & `IexecERC20` (#321)
Le-Caignec Nov 12, 2025
f2ff3a5
fix: improve comments for dataset order compatibility logic
gfournierPro Nov 12, 2025
45be1d7
Merge branch 'chore/solidity-v8' into feat/deal-with-tag
gfournierPro Nov 12, 2025
af281bf
feat: receive approval generic (#323)
gfournierPro Nov 12, 2025
f9276e3
Merge branch 'chore/solidity-v8' into feat/deal-with-tag
gfournierPro Nov 12, 2025
b8414cc
feat: enhance order matching tests with new TEE framework tags and co…
gfournierPro Nov 12, 2025
ed046c3
fix: update TEE framework tags and constants for compatibility in tests
gfournierPro Nov 12, 2025
e29e89a
fix: correct dataset order bit references in compatibility tests
gfournierPro Nov 12, 2025
8095cdb
fix: update order tags for compatibility in IexecPoco1 tests
gfournierPro Nov 13, 2025
aa83d1a
fix: update comment to clarify ignored bits in dataset tag for compat…
gfournierPro Nov 13, 2025
55fb8c1
fix: update comments to clarify ignored bits in dataset tag for compa…
gfournierPro Nov 13, 2025
14b7718
Merge branch 'main' into feat/deal-with-tag
Le-Caignec Nov 13, 2025
e2e082d
fix: correct GPU bit value in tag constants documentation
gfournierPro Nov 14, 2025
7d10009
fix: clarify test description for tag compatibility check
gfournierPro Nov 14, 2025
8e0ed47
feat: add TODO for additional tag compatibility test cases
gfournierPro Nov 14, 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
21 changes: 16 additions & 5 deletions contracts/facets/IexecPoco1Facet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,15 @@ contract IexecPoco1Facet is
revert IncompatibleDatasetOrder("Requester restriction not satisfied");
}
// The deal's tag should include all tag bits of the dataset order.
// Deal: 0b0101, Dataset: 0b0101 => ok
// Deal: 0b0101, Dataset: 0b0001 => ok
// Deal: 0b0101, Dataset: 0b0010 => !ok
if ((deal.tag & datasetOrder.tag) != datasetOrder.tag) {
// For dataset orders: ignore Scone, Gramine, and TDX framework bits to allow
// dataset orders from SGX workerpools to be consumed on TDX workerpools and vice versa.
// Examples after masking:
// Deal: 0b0101, Dataset: 0b0101 => Masked Dataset: 0b0001 => ok
// Deal: 0b0101, Dataset: 0b0001 => Masked Dataset: 0b0001 => ok
// Deal: 0b1001 (TDX), Dataset: 0b0011 (Scone) => Masked Dataset: 0b0001 => ok (cross-framework compatibility)
bytes32 maskedDatasetTag = datasetOrder.tag &
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1;
if ((deal.tag & maskedDatasetTag) != maskedDatasetTag) {
revert IncompatibleDatasetOrder("Tag compatibility not satisfied");
}
}
Expand Down Expand Up @@ -239,7 +244,13 @@ contract IexecPoco1Facet is
"iExecV5-matchOrders-0x05"
);
// The workerpool tag should include all tag bits of dataset, app, and requester orders.
bytes32 tag = _apporder.tag | _datasetorder.tag | _requestorder.tag;
// For dataset orders: ignore Scone, Gramine, and TDX framework bits to allow
// dataset orders from SGX workerpools to be consumed on TDX workerpools and vice versa.
// Bit positions: bit 0 = TEE, bit 1 = Scone, bit 2 = Gramine, bit 3 = TDX
// Mask: ~(BIT_SCONE | BIT_GRAMINE | BIT_TDX) = ~0xE = 0xFFF...FF1
bytes32 maskedDatasetTag = _datasetorder.tag &
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1;
bytes32 tag = _apporder.tag | maskedDatasetTag | _requestorder.tag;
require(tag & ~_workerpoolorder.tag == 0x0, "iExecV5-matchOrders-0x06");
require((tag ^ _apporder.tag)[31] & 0x01 == 0x0, "iExecV5-matchOrders-0x07");

Expand Down
181 changes: 159 additions & 22 deletions test/byContract/IexecPoco/IexecPoco1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@ import {
IexecPocoAccessors__factory,
OwnableMock__factory,
} from '../../../typechain';
import { TAG_STANDARD, TAG_TEE } from '../../../utils/constants';
import {
TAG_ALL_TEE_FRAMEWORKS,
TAG_BIT_2,
TAG_BIT_4,
TAG_BIT_4_AND_TEE,
TAG_STANDARD,
TAG_TEE,
TAG_TEE_GRAMINE,
TAG_TEE_SCONE,
TAG_TEE_TDX,
} from '../../../utils/constants';
import {
IexecOrders,
OrdersActors,
Expand Down Expand Up @@ -627,6 +637,44 @@ describe('IexecPoco1', () => {
);
});

[
{
datasetTag: TAG_TEE_SCONE,
workerpoolTag: TAG_TEE_TDX,
description: 'Scone tag (0x3) and workerpool has TDX tag (0x9)',
},
{
datasetTag: TAG_TEE_GRAMINE,
workerpoolTag: TAG_TEE_TDX,
description: 'Gramine tag (0x5) and workerpool has TDX tag (0x9)',
},
{
datasetTag: TAG_TEE_TDX,
workerpoolTag: TAG_TEE_SCONE,
description: 'TDX tag (0x9) and workerpool has Scone tag (0x3)',
},
{
datasetTag: TAG_ALL_TEE_FRAMEWORKS,
workerpoolTag: TAG_TEE,
description: 'all TEE framework bits (0xF) and workerpool has TEE only (0x1)',
},
Comment on lines +641 to +660
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i thing there is many other case - but it's good like that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a todo thanks

].forEach(({ datasetTag, workerpoolTag, description }) => {
it(`Should match orders when dataset has ${description}`, async () => {
orders.dataset.tag = datasetTag;
orders.workerpool.tag = workerpoolTag;
orders.app.tag = TAG_TEE;
orders.requester.tag = TAG_TEE;

await depositForRequesterAndSchedulerWithDefaultPrices(volume);
await signOrders(iexecWrapper.getDomain(), orders, ordersActors);

await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.emit(
iexecPoco,
'OrdersMatched',
);
});
});

// TODO add success tests for:
// - identity groups
// - pre-signatures
Expand Down Expand Up @@ -680,32 +728,32 @@ describe('IexecPoco1', () => {
});

it('Should fail when workerpool tag does not satisfy app, dataset and request requirements', async () => {
orders.app.tag = '0x0000000000000000000000000000000000000000000000000000000000000001'; // 0b0001
orders.dataset.tag =
'0x0000000000000000000000000000000000000000000000000000000000000002'; // 0b0010
orders.requester.tag =
'0x0000000000000000000000000000000000000000000000000000000000000003'; // 0b0011
// Workerpool order is supposed to satisfy conditions of all actors.
// Bad tag, correct tag should be 0b0011.
orders.workerpool.tag =
'0x0000000000000000000000000000000000000000000000000000000000000004'; // 0b0100
// Match orders.
orders.app.tag = TAG_TEE; //0b0001
orders.dataset.tag = TAG_TEE_SCONE; // 0b0011
orders.requester.tag = TAG_TEE_SCONE; // 0b0011
orders.workerpool.tag = TAG_BIT_2; // 0b0100 - does not satisfy last bits of app, dataset, request
await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith(
'iExecV5-matchOrders-0x06',
);
});

it('Should fail when dataset has other bits set that are not ignored', async () => {
orders.dataset.tag = TAG_BIT_4_AND_TEE; // 0b10001 bit 4 set (not ignored)
orders.workerpool.tag = TAG_TEE;
orders.app.tag = TAG_TEE;
orders.requester.tag = TAG_TEE;

await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith(
'iExecV5-matchOrders-0x06',
);
});

it('Should fail when the last bit of app tag does not satisfy dataset or request requirements', async () => {
// The last bit of dataset and request tag is 1, but app tag does not set it
orders.app.tag = '0x0000000000000000000000000000000000000000000000000000000000000002'; // 0b0010
orders.dataset.tag =
'0x0000000000000000000000000000000000000000000000000000000000000003'; // 0b0011
orders.requester.tag =
'0x0000000000000000000000000000000000000000000000000000000000000003'; // 0b0011
orders.app.tag = TAG_BIT_2; // 0b0100
orders.dataset.tag = TAG_TEE_GRAMINE; // 0b0101
orders.requester.tag = TAG_TEE_GRAMINE;
// Set the workerpool tag in a way to pass first tag check.
orders.workerpool.tag =
'0x0000000000000000000000000000000000000000000000000000000000000003'; // 0b0011
// Match orders.
orders.workerpool.tag = TAG_TEE_GRAMINE;
await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith(
'iExecV5-matchOrders-0x07',
);
Expand Down Expand Up @@ -1253,11 +1301,11 @@ describe('IexecPoco1', () => {
.withArgs('Requester restriction not satisfied');
});

it('Should revert when tag compatibility is not satisfied', async () => {
it('Should revert when tag compatibility with deal is not satisfied', async () => {
// Create dataset order with incompatible tag
const incompatibleTagDatasetOrder = {
...compatibleDatasetOrder,
tag: '0x0000000000000000000000000000000000000000000000000000000000000010', // Different tag
tag: TAG_BIT_4, // Different tag
};
await signOrder(iexecWrapper.getDomain(), incompatibleTagDatasetOrder, datasetProvider);
await expect(
Expand All @@ -1269,6 +1317,95 @@ describe('IexecPoco1', () => {
.to.be.revertedWithCustomError(iexecPoco, 'IncompatibleDatasetOrder')
.withArgs('Tag compatibility not satisfied');
});

// TODO: Add more test cases for tag compatibility
[
{
datasetTag: TAG_TEE_SCONE,
dealTag: TAG_TEE_TDX,
description: 'Scone tag (0x3) and deal has TDX tag (0x9)',
saltPrefix: 'scone-tdx',
},
{
datasetTag: TAG_TEE_GRAMINE,
dealTag: TAG_TEE_TDX,
description: 'Gramine tag (0x5) and deal has TDX tag (0x9)',
saltPrefix: 'gramine-tdx',
},
{
datasetTag: TAG_TEE_TDX,
dealTag: TAG_TEE_SCONE,
description: 'TDX tag (0x9) and deal has Scone tag (0x3)',
saltPrefix: 'tdx-scone',
},
{
datasetTag: TAG_ALL_TEE_FRAMEWORKS,
dealTag: TAG_TEE,
description: 'all TEE framework bits (0xF) and deal has TEE only (0x1)',
saltPrefix: 'all-frameworks-tee',
},
].forEach(({ datasetTag, dealTag, description, saltPrefix }) => {
it(`Should not revert when dataset has ${description}`, async () => {
// Create a deal with the specified tag
const dealOrders = buildOrders({
assets: { ...ordersAssets, dataset: ZeroAddress },
prices: ordersPrices,
requester: requester.address,
tag: dealTag,
volume: volume,
});
dealOrders.app.salt = ethers.id(`${saltPrefix}-app-salt`);
dealOrders.workerpool.salt = ethers.id(`${saltPrefix}-workerpool-salt`);
dealOrders.requester.salt = ethers.id(`${saltPrefix}-requester-salt`);
await depositForRequesterAndSchedulerWithDefaultPrices(volume);
await signOrders(iexecWrapper.getDomain(), dealOrders, ordersActors);
const dealId = getDealId(iexecWrapper.getDomain(), dealOrders.requester);
await iexecPocoAsRequester.matchOrders(...dealOrders.toArray());

// Create dataset order with the specified tag
const datasetOrder = {
...compatibleDatasetOrder,
tag: datasetTag,
salt: ethers.id(`${saltPrefix}-dataset-salt`),
};
await signOrder(iexecWrapper.getDomain(), datasetOrder, datasetProvider);

// Should not revert because bits 1-3 of dataset tag are ignored
await expect(iexecPoco.assertDatasetDealCompatibility(datasetOrder, dealId)).to.not
.be.reverted;
});
});

it('Should revert when dataset has bit 4 set (not masked) and deal does not', async () => {
// Create a deal with TEE only (0b0001 = 0x1)
const teeOnlyOrders = buildOrders({
assets: { ...ordersAssets, dataset: ZeroAddress },
prices: ordersPrices,
requester: requester.address,
tag: TAG_TEE, // TEE only
volume: volume,
});
teeOnlyOrders.app.salt = ethers.id('tee-bit4-app-salt');
teeOnlyOrders.workerpool.salt = ethers.id('tee-bit4-workerpool-salt');
teeOnlyOrders.requester.salt = ethers.id('tee-bit4-requester-salt');
await depositForRequesterAndSchedulerWithDefaultPrices(volume);
await signOrders(iexecWrapper.getDomain(), teeOnlyOrders, ordersActors);
const teeOnlyDealId = getDealId(iexecWrapper.getDomain(), teeOnlyOrders.requester);
await iexecPocoAsRequester.matchOrders(...teeOnlyOrders.toArray());

// Create dataset order with bit 4 set (0b10001 = 0x11)
const bit4DatasetOrder = {
...compatibleDatasetOrder,
tag: TAG_BIT_4_AND_TEE,
salt: ethers.id('bit4-dataset-salt'),
};
await signOrder(iexecWrapper.getDomain(), bit4DatasetOrder, datasetProvider);

// Should revert because bit 4 is NOT masked and the deal doesn't have it
await expect(iexecPoco.assertDatasetDealCompatibility(bit4DatasetOrder, teeOnlyDealId))
.to.be.revertedWithCustomError(iexecPoco, 'IncompatibleDatasetOrder')
.withArgs('Tag compatibility not satisfied');
});
});

/**
Expand Down
17 changes: 17 additions & 0 deletions utils/constants.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH <[email protected]>
// SPDX-License-Identifier: Apache-2.0

/**
* Tag constants:
* - Bit 0: TEE
* - Bit 1: Scone
* - Bit 2: Gramine
* - Bit 3: TDX
* - Bit 4: GPU (0x10)
*/
export const TAG_STANDARD = '0x0000000000000000000000000000000000000000000000000000000000000000';
export const TAG_TEE = '0x0000000000000000000000000000000000000000000000000000000000000001';
export const TAG_TEE_SCONE = '0x0000000000000000000000000000000000000000000000000000000000000003'; // 0b0011 = TEE + Scone
export const TAG_TEE_GRAMINE = '0x0000000000000000000000000000000000000000000000000000000000000005'; // 0b0101 = TEE + Gramine
export const TAG_TEE_TDX = '0x0000000000000000000000000000000000000000000000000000000000000009'; // 0b1001 = TEE + TDX
export const TAG_ALL_TEE_FRAMEWORKS =
'0x000000000000000000000000000000000000000000000000000000000000000F'; // 0b1111 = TEE + Scone + Gramine + TDX
export const TAG_BIT_2 = '0x0000000000000000000000000000000000000000000000000000000000000004'; // 0b0100
export const TAG_BIT_4 = '0x0000000000000000000000000000000000000000000000000000000000000010'; // 0b10000 (bit 4 in 0-indexed)
export const TAG_BIT_4_AND_TEE =
'0x0000000000000000000000000000000000000000000000000000000000000011'; // 0b10001

export const NULL = {
BYTES32: '0x0000000000000000000000000000000000000000000000000000000000000000',
Expand Down
Loading