diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 88a683345..018243273 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,6 +42,7 @@ jobs: test/byContract/IexecERC20/** \ test/byContract/IexecOrderManagement/** \ test/byContract/IexecRelay/** \ + test/byContract/IexecPoco/** \ test/*fullchain* - name: Run deployment # Basic deployment to make sure everything is ok. diff --git a/CHANGELOG.md b/CHANGELOG.md index 2614c1e4d..e9c41a743 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,9 @@ - Tests - ENSIntegration, IexecOrderManagement, IexecRelay (#195) - IexecCategoryManager, IexecERC20 (#192) - - test/*fullchain* (#190) - - IexecAccessors (#189, #191) + - test/*fullchain* (#190, #196) + - IexecAccessors (#189, #191, #196) + - IexecPoco (#196) - Migrate scripts to TypeScript: (#184) - `getFunctionSignatures.js`, `common-test-snapshot.js`, `test-storage.js`, `timelock.js` - Migrated utility files to TypeScript : (#183) diff --git a/test/000_fullchain-boost.test.ts b/test/000_fullchain-boost.test.ts index 991a43c76..bebc0a50b 100644 --- a/test/000_fullchain-boost.test.ts +++ b/test/000_fullchain-boost.test.ts @@ -39,12 +39,12 @@ import { IexecWrapper } from './utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer'; const teeDealTag = '0x0000000000000000000000000000000000000000000000000000000000000001'; -const taskIndex = 0; -const volume = taskIndex + 1; +const taskIndex = 0n; +const volume = taskIndex + 1n; const { results, resultDigest } = buildUtf8ResultAndDigest('result'); -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; describe('IexecPocoBoostDelegate (IT)', function () { let domain: TypedDataDomain; @@ -146,7 +146,7 @@ describe('IexecPocoBoostDelegate (IT)', function () { } = orders.toObject(); const dealPrice = (appPrice + datasetPrice + workerpoolPrice) * // task price - 1; // volume + 1n; // volume expect(await iexecInstance.balanceOf(proxyAddress)).to.be.equal(0); await iexecWrapper.depositInIexecAccount(requester, dealPrice); expect(await iexecInstance.balanceOf(requester.address)).to.be.equal(dealPrice); @@ -203,14 +203,12 @@ describe('IexecPocoBoostDelegate (IT)', function () { expect(deal.workerpoolOwner).to.be.equal(scheduler.address); expect(deal.workerpoolPrice).to.be.equal(workerpoolPrice); expect(deal.requester).to.be.equal(requester.address); - const schedulerRewardRatio = Number( - await WorkerpoolInterface__factory.connect( - workerpoolAddress, - anyone, - ).m_schedulerRewardRatioPolicy(), - ); + const schedulerRewardRatio = await WorkerpoolInterface__factory.connect( + workerpoolAddress, + anyone, + ).m_schedulerRewardRatioPolicy(); expect(deal.workerReward) - .to.be.equal((workerpoolPrice * (100 - schedulerRewardRatio)) / 100) + .to.be.equal((workerpoolPrice * (100n - schedulerRewardRatio)) / 100n) .to.be.greaterThan(0); expect(deal.deadline).to.be.equal(startTime + 7 * 300); // Category 0 expect(deal.botFirst).to.be.equal(0); @@ -302,7 +300,7 @@ describe('IexecPocoBoostDelegate (IT)', function () { const { appOrder, datasetOrder, workerpoolOrder, requestOrder } = orders.toObject(); const dealPrice = (appPrice + datasetPrice + workerpoolPrice) * // task price - 1; // volume + 1n; // volume expect(await iexecInstance.balanceOf(proxyAddress)).to.be.equal(0); expect(await iexecInstance.balanceOf(requester.address)).to.be.equal(0); expect(await iexecInstance.frozenOf(requester.address)).to.be.equal(0); @@ -370,14 +368,12 @@ describe('IexecPocoBoostDelegate (IT)', function () { expect(deal.workerpoolPrice).to.be.equal(workerpoolPrice); expect(deal.requester).to.be.equal(requester.address); expect(deal.sponsor).to.be.equal(sponsor.address); - const schedulerRewardRatio = Number( - await WorkerpoolInterface__factory.connect( - workerpoolAddress, - anyone, - ).m_schedulerRewardRatioPolicy(), - ); + const schedulerRewardRatio = await WorkerpoolInterface__factory.connect( + workerpoolAddress, + anyone, + ).m_schedulerRewardRatioPolicy(); expect(deal.workerReward) - .to.be.equal((workerpoolPrice * (100 - schedulerRewardRatio)) / 100) + .to.be.equal((workerpoolPrice * (100n - schedulerRewardRatio)) / 100n) .to.be.greaterThan(0); expect(deal.deadline).to.be.equal(startTime + 7 * 300); // Category 0 expect(deal.botFirst).to.be.equal(0); @@ -454,7 +450,7 @@ describe('IexecPocoBoostDelegate (IT)', function () { }); it('Should push result (TEE with contribution authorization signed by scheduler)', async function () { - const volume = 3; + const volume = 3n; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, @@ -503,7 +499,7 @@ describe('IexecPocoBoostDelegate (IT)', function () { expect(await iexecInstance.balanceOf(datasetProvider.address)).to.be.equal(0); expect(await iexecInstance.balanceOf(scheduler.address)).to.be.equal(0); expect(await iexecInstance.frozenOf(scheduler.address)).to.be.equal(schedulerDealStake); - const expectedWorkerReward = Number((await viewDealBoost(dealId)).workerReward); + const expectedWorkerReward = (await viewDealBoost(dealId)).workerReward; const schedulerBaseReward = workerpoolPrice - expectedWorkerReward; await expect( @@ -543,7 +539,7 @@ describe('IexecPocoBoostDelegate (IT)', function () { .withArgs(scheduler.address, schedulerBaseReward, taskId) .to.emit(iexecPocoBoostInstance, 'ResultPushedBoost') .withArgs(dealId, taskIndex, results); - const remainingTasksToPush = volume - 1; + const remainingTasksToPush = volume - 1n; expect(await iexecInstance.balanceOf(proxyAddress)).to.be.equal( (taskPrice + schedulerTaskStake) * remainingTasksToPush, ); @@ -611,8 +607,8 @@ describe('IexecPocoBoostDelegate (IT)', function () { describe('Claim', function () { it('Should refund requester on claim of non sponsored deal (TEE)', async function () { - const expectedVolume = 3; // > 1 to explicit taskPrice vs dealPrice - const claimedTasks = 1; + const expectedVolume = 3n; // > 1 to explicit taskPrice vs dealPrice + const claimedTasks = 1n; const taskPrice = appPrice + datasetPrice + workerpoolPrice; const dealPrice = taskPrice * expectedVolume; const orders = buildOrders({ @@ -693,8 +689,8 @@ describe('IexecPocoBoostDelegate (IT)', function () { }); it('Should refund sponsor on claim of a sponsored deal (TEE)', async function () { - const expectedVolume = 3; // > 1 to explicit taskPrice vs dealPrice - const claimedTasks = 1; + const expectedVolume = 3n; // > 1 to explicit taskPrice vs dealPrice + const claimedTasks = 1n; const taskPrice = appPrice + datasetPrice + workerpoolPrice; const dealPrice = taskPrice * expectedVolume; const orders = buildOrders({ diff --git a/test/000_fullchain.test.ts b/test/000_fullchain.test.ts index f3a6e583f..c48c72c1f 100644 --- a/test/000_fullchain.test.ts +++ b/test/000_fullchain.test.ts @@ -31,9 +31,9 @@ import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer'; const standardDealTag = '0x0000000000000000000000000000000000000000000000000000000000000000'; const teeDealTag = '0x0000000000000000000000000000000000000000000000000000000000000001'; -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; const callbackAddress = ethers.Wallet.createRandom().address; const { results, resultDigest } = buildUtf8ResultAndDigest('result'); const { resultsCallback, callbackResultDigest } = buildResultCallbackAndDigest(123); @@ -106,7 +106,7 @@ describe('Integration tests', function () { } it('[1] Sponsorship, beneficiary, callback, BoT, replication', async function () { - const volume = 3; + const volume = 3n; // Create deal. const workers = [worker1, worker2]; const orders = buildOrders({ @@ -135,9 +135,9 @@ describe('Integration tests', function () { const accountsInitialFrozens = await iexecWrapper.getInitialFrozens(accounts); const workerStakePerTask = await iexecPoco .viewDeal(dealId) - .then((deal) => Number(deal.workerStake)); + .then((deal) => deal.workerStake); // Finalize each task and check balance changes. - for (let taskIndex = 0; taskIndex < volume; taskIndex++) { + for (let taskIndex = 0n; taskIndex < volume; taskIndex++) { const taskId = await iexecWrapper.initializeTask(dealId, taskIndex); for (const worker of workers) { await iexecWrapper.contributeToTask( @@ -163,10 +163,10 @@ describe('Integration tests', function () { const expectedProxyBalanceChange = -( taskPrice + schedulerStakePerTask + - workerStakePerTask * workers.length + workerStakePerTask * BigInt(workers.length) ); const expectedWinningWorkerBalanceChange = - workerStakePerTask + workersRewardPerTask / workers.length; + workerStakePerTask + workersRewardPerTask / BigInt(workers.length); await expect(finalizeTx).to.changeTokenBalances( iexecPoco, [proxyAddress, ...accounts], @@ -182,22 +182,22 @@ describe('Integration tests', function () { ); // Multiply amount by the number of finalized tasks to correctly compute // stake and reward amounts. - const completedTasks = taskIndex + 1; + const completedTasks = taskIndex + 1n; // Calculate expected frozen changes const expectedFrozenChanges = [ -taskPrice * completedTasks, // Sponsor - 0, // Requester + 0n, // Requester -schedulerStakePerTask * completedTasks, // Scheduler - 0, // AppProvider - 0, // DatasetProvider, - ...workers.map(() => 0), // Add 0 for each worker + 0n, // AppProvider + 0n, // DatasetProvider, + ...workers.map(() => 0n), // Add 0 for each worker ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); } }); it('[2] No sponsorship, beneficiary, callback, BoT, replication', async function () { - const volume = 3; + const volume = 3n; // Create deal. const workers = [worker1, worker2]; const orders = buildOrders({ @@ -227,8 +227,8 @@ describe('Integration tests', function () { // Finalize each task and check balance changes. const workerStakePerTask = await iexecPoco .viewDeal(dealId) - .then((deal) => Number(deal.workerStake)); - for (let taskIndex = 0; taskIndex < volume; taskIndex++) { + .then((deal) => deal.workerStake); + for (let taskIndex = 0n; taskIndex < volume; taskIndex++) { const taskId = await iexecWrapper.initializeTask(dealId, taskIndex); for (const worker of workers) { await iexecWrapper.contributeToTask( @@ -254,10 +254,10 @@ describe('Integration tests', function () { const expectedProxyBalanceChange = -( taskPrice + schedulerStakePerTask + - workerStakePerTask * workers.length + workerStakePerTask * BigInt(workers.length) ); const expectedWinningWorkerBalanceChange = - workerStakePerTask + workersRewardPerTask / workers.length; + workerStakePerTask + workersRewardPerTask / BigInt(workers.length); await expect(finalizeTx).to.changeTokenBalances( iexecPoco, [proxyAddress, ...accounts], @@ -272,21 +272,21 @@ describe('Integration tests', function () { ); // Multiply amount by the number of finalized tasks to correctly compute // stake and reward amounts. - const completedTasks = taskIndex + 1; + const completedTasks = taskIndex + 1n; // Calculate expected frozen changes const expectedFrozenChanges = [ -taskPrice * completedTasks, // Requester -schedulerStakePerTask * completedTasks, // Scheduler - 0, // AppProvider - 0, // DatasetProvider - ...workers.map(() => 0), // Add 0 for each worker + 0n, // AppProvider + 0n, // DatasetProvider + ...workers.map(() => 0n), // Add 0 for each worker ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); } }); it('[3] Sponsorship, beneficiary, callback, BoT, no replication', async function () { - const volume = 3; + const volume = 3n; // Create deal. const orders = buildOrders({ assets: ordersAssets, @@ -312,7 +312,7 @@ describe('Integration tests', function () { const accounts = [sponsor, requester, scheduler, appProvider, datasetProvider, worker1]; const accountsInitialFrozens = await iexecWrapper.getInitialFrozens(accounts); // Finalize each task and check balance changes. - for (let taskIndex = 0; taskIndex < volume; taskIndex++) { + for (let taskIndex = 0n; taskIndex < volume; taskIndex++) { const taskId = await iexecWrapper.initializeTask(dealId, taskIndex); const { workerStakePerTask } = await iexecWrapper.contributeToTeeTask( dealId, @@ -349,22 +349,22 @@ describe('Integration tests', function () { ); // Multiply amount by the number of finalized tasks to correctly compute // stake and reward amounts. - const completedTasks = taskIndex + 1; + const completedTasks = taskIndex + 1n; // Calculate expected frozen changes const expectedFrozenChanges = [ -taskPrice * completedTasks, // Sponsor - 0, // Requester + 0n, // Requester -schedulerStakePerTask * completedTasks, // Scheduler - 0, // AppProvider - 0, // DatasetProvider - 0, // Worker + 0n, // AppProvider + 0n, // DatasetProvider + 0n, // Worker ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); } }); it('[4] No sponsorship, beneficiary, callback, BoT, no replication', async function () { - const volume = 3; + const volume = 3n; // Create deal. const orders = buildOrders({ assets: ordersAssets, @@ -390,7 +390,7 @@ describe('Integration tests', function () { const accounts = [requester, scheduler, appProvider, datasetProvider, worker1]; const accountsInitialFrozens = await iexecWrapper.getInitialFrozens(accounts); // Finalize each task and check balance changes. - for (let taskIndex = 0; taskIndex < volume; taskIndex++) { + for (let taskIndex = 0n; taskIndex < volume; taskIndex++) { const taskId = await iexecWrapper.initializeTask(dealId, taskIndex); const { workerStakePerTask } = await iexecWrapper.contributeToTeeTask( dealId, @@ -428,21 +428,21 @@ describe('Integration tests', function () { ); // Multiply amount by the number of finalized tasks to correctly compute // stake and reward amounts. - const completedTasks = taskIndex + 1; + const completedTasks = taskIndex + 1n; // Calculate expected frozen changes const expectedFrozenChanges = [ -taskPrice * completedTasks, // Requester -schedulerStakePerTask * completedTasks, // Scheduler - 0, // AppProvider - 0, // DatasetProvider - 0, // Worker + 0n, // AppProvider + 0n, // DatasetProvider + 0n, // Worker ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); } }); it('[5] No sponsorship, no beneficiary, no callback, no BoT, no replication', async function () { - const volume = 1; + const volume = 1n; // Create deal. const orders = buildOrders({ assets: ordersAssets, @@ -464,7 +464,7 @@ describe('Integration tests', function () { // Save frozens const accounts = [requester, scheduler, appProvider, datasetProvider, worker1]; const accountsInitialFrozens = await iexecWrapper.getInitialFrozens(accounts); - const taskIndex = 0; + const taskIndex = 0n; const taskId = await iexecWrapper.initializeTask(dealId, taskIndex); const { workerStakePerTask } = await iexecWrapper.contributeToTeeTask( dealId, @@ -501,9 +501,9 @@ describe('Integration tests', function () { const expectedFrozenChanges = [ -dealPrice, // Requester -schedulerStakePerTask, // Scheduler - 0, // AppProvider - 0, // DatasetProvider - 0, // Worker + 0n, // AppProvider + 0n, // DatasetProvider + 0n, // Worker ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); }); @@ -511,7 +511,7 @@ describe('Integration tests', function () { describe('Integration tests array of worker', function () { for (let workerNumber = 2; workerNumber < 6; workerNumber++) { it(`[6.${workerNumber - 1}] No sponsorship, no beneficiary, no callback, no BoT, up to ${workerNumber} workers`, async function () { - const volume = 1; + const volume = 1n; const allWorkers = [worker1, worker2, worker3, worker4, worker5]; const workers = allWorkers.slice(0, workerNumber); const accounts = [requester, scheduler, appProvider, datasetProvider, ...workers]; @@ -538,14 +538,14 @@ describe('Integration tests', function () { for (let i = 0; i < workerNumber; i++) { expect(await iexecPoco.viewScore(workers[i].address)).to.be.equal(0); } - const taskId = await iexecWrapper.initializeTask(dealId, 0); + const taskId = await iexecWrapper.initializeTask(dealId, 0n); // Finalize each task and check balance changes. const workerStakePerTask = await iexecPoco .viewDeal(dealId) - .then((deal) => Number(deal.workerStake)); + .then((deal) => deal.workerStake); for (let i = 0; i < workerNumber; i++) { - await iexecWrapper.contributeToTask(dealId, 0, resultDigest, workers[i]); + await iexecWrapper.contributeToTask(dealId, 0n, resultDigest, workers[i]); } for (let i = 0; i < workerNumber; i++) { await iexecPoco @@ -560,10 +560,10 @@ describe('Integration tests', function () { const expectedProxyBalanceChange = -( dealPrice + schedulerStakePerTask + - workerStakePerTask * workers.length + workerStakePerTask * BigInt(workers.length) ); const expectedWinningWorkerBalanceChange = - workerStakePerTask + workersRewardPerTask / workerNumber; + workerStakePerTask + workersRewardPerTask / BigInt(workerNumber); await expect(finalizeTx).to.changeTokenBalances( iexecPoco, [proxyAddress, ...accounts], @@ -582,9 +582,9 @@ describe('Integration tests', function () { const expectedFrozenChanges = [ -taskPrice, -schedulerStakePerTask, - 0, - 0, - ...workers.map(() => 0), + 0n, + 0n, + ...workers.map(() => 0n), ]; await iexecWrapper.checkFrozenChanges( accountsInitialFrozens, @@ -600,7 +600,7 @@ describe('Integration tests', function () { }); it('[7] No sponsorship, no beneficiary, no callback, no BoT, up to 5 workers with 1 bad worker', async function () { - const volume = 1; + const volume = 1n; const allWorkers = [worker1, worker2, worker3, worker4, worker5]; const { resultDigest: badResultDigest } = buildUtf8ResultAndDigest('bad-result'); const losingWorker = worker1; @@ -636,15 +636,15 @@ describe('Integration tests', function () { for (const contributor of contributions) { expect(await iexecPoco.viewScore(contributor.signer.address)).to.be.equal(0); } - const taskId = await iexecWrapper.initializeTask(dealId, 0); + const taskId = await iexecWrapper.initializeTask(dealId, 0n); // Finalize task and check balance changes. const workerStakePerTask = await iexecPoco .viewDeal(dealId) - .then((deal) => Number(deal.workerStake)); + .then((deal) => deal.workerStake); for (const contributor of contributions) { await iexecWrapper.contributeToTask( dealId, - 0, + 0n, contributor.resultDigest, contributor.signer, ); @@ -662,21 +662,21 @@ describe('Integration tests', function () { const finalizeTx = await iexecPoco.connect(scheduler).finalize(taskId, results, '0x'); await finalizeTx.wait(); - const totalWorkerPoolReward = workerpoolPrice + workerStakePerTask * 1; // bad wrokers lose their stake and add it to the pool price + const totalWorkerPoolReward = workerpoolPrice + workerStakePerTask * 1n; // bad wrokers lose their stake and add it to the pool price // compute expected worker reward for current task const workersRewardPerTask = await iexecWrapper.computeWorkersRewardForCurrentTask( totalWorkerPoolReward, dealId, ); const expectedWinningWorkerBalanceChange = - workerStakePerTask + workersRewardPerTask / winningWorkers.length; + workerStakePerTask + workersRewardPerTask / BigInt(winningWorkers.length); // compute expected scheduler reward for current task const schedulerRewardPerTask = totalWorkerPoolReward - workersRewardPerTask; const expectedSchedulerBalanceChange = schedulerStakePerTask + schedulerRewardPerTask; const expectedProxyBalanceChange = -( dealPrice + - workerStakePerTask * allWorkers.length + + workerStakePerTask * BigInt(allWorkers.length) + schedulerStakePerTask ); await expect(finalizeTx).to.changeTokenBalances( @@ -704,9 +704,9 @@ describe('Integration tests', function () { const expectedFrozenChanges = [ -dealPrice, -schedulerStakePerTask, - 0, - 0, - ...allWorkers.map(() => 0), + 0n, + 0n, + ...allWorkers.map(() => 0n), ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); }); diff --git a/test/200_fullchain-bot.test.ts b/test/200_fullchain-bot.test.ts index d4cdb76fd..fec2268cf 100644 --- a/test/200_fullchain-bot.test.ts +++ b/test/200_fullchain-bot.test.ts @@ -11,9 +11,9 @@ import { IexecWrapper } from './utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer'; const standardDealTag = '0x0000000000000000000000000000000000000000000000000000000000000000'; -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; let proxyAddress: string; let iexecPoco: IexecInterfaceNative; @@ -81,7 +81,7 @@ describe('Integration tests', function () { it('Task Lifecycle with BoT Replication and Error Handling', async function () { const workers = [worker1, worker2, worker3, worker4, worker5]; // Create deal. - const volume = 3; + const volume = 3n; const tasksAndWorkers: { [key: number]: { worker: SignerWithAddress; @@ -128,11 +128,11 @@ describe('Integration tests', function () { // Finalize each task and check balance changes. const workerStakePerTask = await iexecPoco .viewDeal(dealId) - .then((deal) => Number(deal.workerStake)); - for (let taskIndex = 0; taskIndex < volume; taskIndex++) { + .then((deal) => deal.workerStake); + for (let taskIndex = 0n; taskIndex < volume; taskIndex++) { const taskId = await iexecWrapper.initializeTask(dealId, taskIndex); const initialScores = await getInitialScores(workers); - const contributions = tasksAndWorkers[taskIndex]; + const contributions = tasksAndWorkers[Number(taskIndex)]; for (const contribution of contributions) { const { worker, useEnclave, result } = contribution; const { resultDigest } = buildUtf8ResultAndDigest(result); @@ -154,7 +154,9 @@ describe('Integration tests', function () { .then((tx) => tx.wait()); } } - const { results } = buildUtf8ResultAndDigest(tasksAndWorkers[taskIndex][0].result); + const { results } = buildUtf8ResultAndDigest( + tasksAndWorkers[Number(taskIndex)][0].result, + ); const finalizeTx = await iexecPoco.connect(scheduler).finalize(taskId, results, '0x'); await finalizeTx.wait(); expect((await iexecPoco.viewTask(taskId)).status).to.equal(TaskStatusEnum.COMPLETED); @@ -176,21 +178,21 @@ describe('Integration tests', function () { (worker) => !nonParticipantWorkers.includes(worker), ); const totalWorkerPoolReward = - workerpoolPrice + workerStakePerTask * loosingWorkers.length; // bad wrokers lose their stake and add it to the pool price + workerpoolPrice + workerStakePerTask * BigInt(loosingWorkers.length); // bad wrokers lose their stake and add it to the pool price // compute expected worker reward for current task const workersRewardPerTask = await iexecWrapper.computeWorkersRewardForCurrentTask( totalWorkerPoolReward, dealId, ); const expectedWinningWorkerBalanceChange = - workerStakePerTask + workersRewardPerTask / winningWorkers.length; + workerStakePerTask + workersRewardPerTask / BigInt(winningWorkers.length); // compute expected scheduler reward for current task const schedulerRewardPerTask = totalWorkerPoolReward - workersRewardPerTask; const expectedSchedulerBalanceChange = schedulerStakePerTask + schedulerRewardPerTask; const expectedProxyBalanceChange = -( taskPrice + - workerStakePerTask * participantWorkers.length + + workerStakePerTask * BigInt(participantWorkers.length) + schedulerStakePerTask ); @@ -216,14 +218,14 @@ describe('Integration tests', function () { ); // Multiply amount by the number of finalized tasks to correctly compute // stake and reward amounts. - const completedTasks = taskIndex + 1; + const completedTasks = taskIndex + 1n; // Calculate expected frozen changes const expectedFrozenChanges = [ -taskPrice * completedTasks, // Requester -schedulerStakePerTask * completedTasks, // Scheduler - 0, // AppProvider - 0, // DatasetProvider - ...workers.map(() => 0), // Add 0 for each worker + 0n, // AppProvider + 0n, // DatasetProvider + ...workers.map(() => 0n), // Add 0 for each worker ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); await validateScores( @@ -237,35 +239,35 @@ describe('Integration tests', function () { async function getInitialScores( workers: SignerWithAddress[], - ): Promise<{ [address: string]: number }> { - const scores: { [address: string]: number } = {}; + ): Promise<{ [address: string]: bigint }> { + const scores: { [address: string]: bigint } = {}; for (const worker of workers) { - scores[worker.address] = Number(await iexecPoco.viewScore(worker.address)); + scores[worker.address] = await iexecPoco.viewScore(worker.address); } return scores; } }); async function validateScores( - initialScores: { [address: string]: number }, + initialScores: { [address: string]: bigint }, winningWorkers: SignerWithAddress[], loosingWorkers: SignerWithAddress[], nonParticipantWorkers: SignerWithAddress[], ) { for (const winningWorker of winningWorkers) { - const currentScore = Number(await iexecPoco.viewScore(winningWorker.address)); + const currentScore = await iexecPoco.viewScore(winningWorker.address); expect(currentScore, `Worker ${winningWorker.address} score mismatch`).to.equal( - initialScores[winningWorker.address] + 1, + initialScores[winningWorker.address] + 1n, ); } for (const loosingWorker of loosingWorkers) { - const currentScore = Number(await iexecPoco.viewScore(loosingWorker.address)); + const currentScore = await iexecPoco.viewScore(loosingWorker.address); expect(currentScore, `Worker ${loosingWorker.address} score mismatch`).to.equal( - initialScores[loosingWorker.address] - 1, + initialScores[loosingWorker.address] - 1n, ); } for (const nonParticipantWorker of nonParticipantWorkers) { - const currentScore = Number(await iexecPoco.viewScore(nonParticipantWorker.address)); + const currentScore = await iexecPoco.viewScore(nonParticipantWorker.address); expect(currentScore, `Worker ${nonParticipantWorker.address} score mismatch`).to.equal( initialScores[nonParticipantWorker.address], ); diff --git a/test/201_fullchain-multi-orders.test.ts b/test/201_fullchain-multi-orders.test.ts index 63b1ff150..12a1fb3e8 100644 --- a/test/201_fullchain-multi-orders.test.ts +++ b/test/201_fullchain-multi-orders.test.ts @@ -24,14 +24,15 @@ import { buildUtf8ResultAndDigest, getIexecAccounts, } from '../utils/poco-tools'; +import { maxBigInt, minBigInt } from '../utils/tools'; import { IexecWrapper } from './utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer'; const standardDealTag = '0x0000000000000000000000000000000000000000000000000000000000000000'; -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice1 = 1_000_000_015; -const workerpoolPrice2 = 1_000_000_025; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice1 = 1_000_000_015n; +const workerpoolPrice2 = 1_000_000_025n; const { results, resultDigest } = buildUtf8ResultAndDigest('result'); let proxyAddress: string; @@ -73,7 +74,7 @@ describe('Integration tests', function () { ordersPrices = { app: appPrice, dataset: datasetPrice, - workerpool: 0, // Overridden below. + workerpool: 0n, // Overridden below. }; } @@ -82,11 +83,11 @@ describe('Integration tests', function () { * for the same workerpool and only 1 request order. */ it('[1] No sponsorship, no beneficiary, no callback, BoT, no replication, 2 workerpool orders', async function () { - const volume = 3; - const workerpoolOrderVolume1 = 2; - const workerpoolOrderVolume2 = 10; - const dealVolume1 = Math.min(workerpoolOrderVolume1, volume); // min(2, 3); - const dealVolume2 = Math.min(workerpoolOrderVolume2, volume - dealVolume1); // min(10, 1) + const volume = 3n; + const workerpoolOrderVolume1 = 2n; + const workerpoolOrderVolume2 = 10n; + const dealVolume1 = minBigInt(workerpoolOrderVolume1, volume); // min(2, 3); + const dealVolume2 = minBigInt(workerpoolOrderVolume2, volume - dealVolume1); // min(10, 1) const taskPrice1 = appPrice + datasetPrice + workerpoolPrice1; const taskPrice2 = appPrice + datasetPrice + workerpoolPrice2; // Create default orders. @@ -109,7 +110,7 @@ describe('Integration tests', function () { workerpoolOrder1.workerpoolprice = workerpoolPrice1; workerpoolOrder2.volume = workerpoolOrderVolume2; workerpoolOrder2.workerpoolprice = workerpoolPrice2; - requestOrder.workerpoolmaxprice = Math.max(workerpoolPrice1, workerpoolPrice2); + requestOrder.workerpoolmaxprice = maxBigInt(workerpoolPrice1, workerpoolPrice2); // Match both workerpool orders with the same request order. const dealOrders1 = new IexecOrders( appOrder, @@ -167,7 +168,7 @@ describe('Integration tests', function () { // Finalize each task and run checks. await runTaskThenCheckBalancesAndVolumes( dealId1, - Number(taskIndex1), + taskIndex1, taskPrice1, schedulerStakePerTaskOfDeal1, schedulerRewardPerTaskOfDeal1, @@ -175,7 +176,7 @@ describe('Integration tests', function () { ); await runTaskThenCheckBalancesAndVolumes( dealId1, - Number(taskIndex1) + 1, + taskIndex1 + 1n, taskPrice1, schedulerStakePerTaskOfDeal1, schedulerRewardPerTaskOfDeal1, @@ -183,7 +184,7 @@ describe('Integration tests', function () { ); await runTaskThenCheckBalancesAndVolumes( dealId2, - Number(taskIndex2), + taskIndex2, taskPrice2, schedulerStakePerTaskOfDeal2, schedulerRewardPerTaskOfDeal2, @@ -201,11 +202,11 @@ describe('Integration tests', function () { async function runTaskThenCheckBalancesAndVolumes( dealId: string, - taskIndex: number, - taskPrice: number, - schedulerStake: number, - schedulerReward: number, - workerReward: number, + taskIndex: bigint, + taskPrice: bigint, + schedulerStake: bigint, + schedulerReward: bigint, + workerReward: bigint, ) { // Save frozens before task execution. const accounts = [requester, scheduler, appProvider, datasetProvider, worker1]; @@ -246,9 +247,9 @@ describe('Integration tests', function () { const expectedFrozenChanges = [ -taskPrice, // Requester -schedulerStake, // Scheduler - 0, // AppProvider - 0, // DatasetProvider - 0, // Worker + 0n, // AppProvider + 0n, // DatasetProvider + 0n, // Worker ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); } diff --git a/test/300_fullchain-reopen.test.ts b/test/300_fullchain-reopen.test.ts index 4babbaa77..0ea76dced 100644 --- a/test/300_fullchain-reopen.test.ts +++ b/test/300_fullchain-reopen.test.ts @@ -20,9 +20,9 @@ import { import { IexecWrapper } from './utils/IexecWrapper'; const standardDealTag = '0x0000000000000000000000000000000000000000000000000000000000000000'; -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; const { results, resultDigest } = buildUtf8ResultAndDigest('result'); let proxyAddress: string; @@ -101,7 +101,7 @@ describe('Integration tests', function () { * - Verify that winning workers receive a positive score, while losing workers do not. */ it(`[1] Task lifecycle with contributions and reopening`, async function () { - const volume = 1; + const volume = 1n; const workers = [worker1, worker2, worker3, worker4]; const firstContributors = workers.slice(0, 2); const secondContributors = workers.slice(2, 4); @@ -126,12 +126,12 @@ describe('Integration tests', function () { for (const worker of workers) { expect(await iexecPoco.viewScore(worker.address)).to.be.equal(0); } - const taskId = await iexecWrapper.initializeTask(dealId, 0); + const taskId = await iexecWrapper.initializeTask(dealId, 0n); const workerStakePerTask = await iexecPoco .viewDeal(dealId) - .then((deal) => Number(deal.workerStake)); + .then((deal) => deal.workerStake); for (const contributor of firstContributors) { - await iexecWrapper.contributeToTask(dealId, 0, resultDigest, contributor); + await iexecWrapper.contributeToTask(dealId, 0n, resultDigest, contributor); } const task = await iexecPoco.viewTask(taskId); expect(task.status).to.equal(TaskStatusEnum.REVEALING); @@ -170,7 +170,7 @@ describe('Integration tests', function () { } // Contribute and reveal with new workers. for (const contributor of secondContributors) { - await iexecWrapper.contributeToTask(dealId, 0, resultDigest, contributor); + await iexecWrapper.contributeToTask(dealId, 0n, resultDigest, contributor); } for (const contributor of secondContributors) { await iexecPoco @@ -182,20 +182,20 @@ describe('Integration tests', function () { await finalizeTx.wait(); // Bad workers lose their stake and add it to the pool price const totalWorkerPoolReward = - workerpoolPrice + workerStakePerTask * firstContributors.length; + workerpoolPrice + workerStakePerTask * BigInt(firstContributors.length); const workersRewardPerTask = await iexecWrapper.computeWorkersRewardForCurrentTask( totalWorkerPoolReward, dealId, ); const expectedWinningWorkerBalanceChange = - workerStakePerTask + workersRewardPerTask / secondContributors.length; + workerStakePerTask + workersRewardPerTask / BigInt(secondContributors.length); // compute expected scheduler reward for current task const schedulerRewardPerTask = totalWorkerPoolReward - workersRewardPerTask; const expectedProxyBalanceChange = -( dealPrice + - workerStakePerTask * workers.length + + workerStakePerTask * BigInt(workers.length) + schedulerStakePerTask ); await expect(finalizeTx).to.changeTokenBalances( @@ -215,9 +215,9 @@ describe('Integration tests', function () { const expectedFrozenChanges = [ -taskPrice, -schedulerStakePerTask, - 0, - 0, - ...workers.map(() => 0), + 0n, + 0n, + ...workers.map(() => 0n), ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); diff --git a/test/byContract/IexecAccessors/IexecAccessors.test.ts b/test/byContract/IexecAccessors/IexecAccessors.test.ts index 99c58ae09..dc102f55a 100644 --- a/test/byContract/IexecAccessors/IexecAccessors.test.ts +++ b/test/byContract/IexecAccessors/IexecAccessors.test.ts @@ -34,9 +34,9 @@ import { hashDomain } from '../IexecMaintenance/IexecMaintenance.test'; * Test state view functions. */ -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; const { results, resultDigest } = buildUtf8ResultAndDigest('result'); const { resultsCallback, callbackResultDigest } = buildResultCallbackAndDigest(123); @@ -91,7 +91,7 @@ describe('IexecAccessors', async () => { }); it('balanceOf', async function () { - const amount = 3; + const amount = 3n; await iexecWrapper.depositInIexecAccount(anyone, amount); expect(await iexecPoco.balanceOf(anyone.address)).to.equal(amount); }); @@ -103,7 +103,7 @@ describe('IexecAccessors', async () => { }); it('allowance', async function () { - const amount = 10; + const amount = 10n; const spender = ethers.Wallet.createRandom().address; await iexecWrapper.depositInIexecAccount(anyone, amount); await iexecPoco.connect(anyone).approve(spender, amount); @@ -114,7 +114,7 @@ describe('IexecAccessors', async () => { await createDeal(); // Lock some requester funds. const dealPrice = appPrice + datasetPrice + workerpoolPrice; // Stake some funds. - const stakedBalance = 3; + const stakedBalance = 3n; await iexecWrapper.depositInIexecAccount(requester, stakedBalance); // Check staked and locked amounts. const account = await iexecPoco.viewAccount(requester.address); @@ -176,8 +176,8 @@ describe('IexecAccessors', async () => { const { dealId, taskId, taskIndex, startTime, timeRef } = await createDeal(); await iexecWrapper.initializeTask(dealId, taskIndex); - const contributionDeadlineRatio = Number(await iexecPoco.contribution_deadline_ratio()); - const finalDeadlineRatio = Number(await iexecPoco.final_deadline_ratio()); + const contributionDeadlineRatio = await iexecPoco.contribution_deadline_ratio(); + const finalDeadlineRatio = await iexecPoco.final_deadline_ratio(); const task = await iexecPoco.viewTask(taskId); expect(task.status).to.equal(TaskStatusEnum.ACTIVE); @@ -314,13 +314,13 @@ describe('IexecAccessors', async () => { }); it('Should not get result when task is not completed', async function () { - const { dealId } = await createDeal(3); + const { dealId } = await createDeal(3n); - const unsetTaskId = getTaskId(dealId, 0); - const activeTaskId = await iexecWrapper.initializeTask(dealId, 1); + const unsetTaskId = getTaskId(dealId, 0n); + const activeTaskId = await iexecWrapper.initializeTask(dealId, 1n); const { taskId: revealingTaskId } = await iexecWrapper - .initializeTask(dealId, 2) - .then(() => iexecWrapper.contributeToTask(dealId, 2, resultDigest, worker1)); + .initializeTask(dealId, 2n) + .then(() => iexecWrapper.contributeToTask(dealId, 2n, resultDigest, worker1)); await verifyTaskStatusAndResult(unsetTaskId, TaskStatusEnum.UNSET); await verifyTaskStatusAndResult(activeTaskId, TaskStatusEnum.ACTIVE); @@ -332,7 +332,7 @@ describe('IexecAccessors', async () => { /** * Helper function to create a deal with a specific volume. */ -async function createDeal(volume: number = 1) { +async function createDeal(volume: bigint = 1n) { const orders = buildOrders({ assets: ordersAssets, prices: ordersPrices, @@ -343,7 +343,7 @@ async function createDeal(volume: number = 1) { ...orders.toArray(), ); const dealCategory = (await iexecPoco.viewDeal(dealId)).category; - const timeRef = Number((await iexecPoco.viewCategory(dealCategory)).workClockTimeRef); + const timeRef = (await iexecPoco.viewCategory(dealCategory)).workClockTimeRef; return { dealId, taskId, taskIndex, startTime, timeRef, orders }; } diff --git a/test/byContract/IexecPoco/IexecPoco1.test.ts b/test/byContract/IexecPoco/IexecPoco1.test.ts index 768952715..a05b0f25f 100644 --- a/test/byContract/IexecPoco/IexecPoco1.test.ts +++ b/test/byContract/IexecPoco/IexecPoco1.test.ts @@ -1,14 +1,12 @@ -// SPDX-FileCopyrightText: 2020-2024 IEXEC BLOCKCHAIN TECH +// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 -import { AddressZero, HashZero } from '@ethersproject/constants'; -import { Contract, ContractTransaction } from '@ethersproject/contracts'; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { expect } from 'chai'; +import { Contract, ContractTransactionResponse, Wallet, ZeroAddress, ZeroHash } from 'ethers'; import { ethers } from 'hardhat'; import { - ERC1271Mock, ERC1271Mock__factory, IERC721__factory, IexecInterfaceNative, @@ -16,7 +14,6 @@ import { IexecLibOrders_v5, IexecPocoAccessors, IexecPocoAccessors__factory, - OwnableMock, OwnableMock__factory, } from '../../../typechain'; import { IexecPoco1 } from '../../../typechain/contracts/modules/interfaces/IexecPoco1.v8.sol/IexecPoco1'; @@ -46,15 +43,15 @@ import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deploy * TODO add Standard tests. */ -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; const standardDealTag = '0x0000000000000000000000000000000000000000000000000000000000000000'; const teeDealTag = '0x0000000000000000000000000000000000000000000000000000000000000001'; -const volume = 1; -const botVolume = 321; +const volume = 1n; +const botVolume = 321n; const someMessage = 'some-message'; -const someWallet = ethers.Wallet.createRandom(); +const someWallet = Wallet.createRandom(); /** * Note: TEE is the default in tests. @@ -84,11 +81,11 @@ describe('IexecPoco1', () => { let ordersPrices: OrdersPrices; let orders: IexecOrders; let [randomAddress, randomSignature]: string[] = []; - let randomContract: OwnableMock; - let erc1271MockContract: ERC1271Mock; + let randomContractAddress: string; + let erc1271MockContractAddress: string; let orderManagement: { [key: string]: { - iexecPocoSignManageOrder: () => Promise; + iexecPocoSignManageOrder: () => Promise; providerAddress: string; order: | IexecLibOrders_v5.AppOrderStruct @@ -142,14 +139,16 @@ describe('IexecPoco1', () => { const randomWallet = ethers.Wallet.createRandom(); randomAddress = randomWallet.address; randomSignature = await randomWallet.signMessage('random'); - randomContract = await new OwnableMock__factory() + randomContractAddress = await new OwnableMock__factory() .connect(anyone) .deploy() - .then((contract) => contract.deployed()); - erc1271MockContract = await new ERC1271Mock__factory() + .then((contract) => contract.waitForDeployment()) + .then((deployedContract) => deployedContract.getAddress()); + erc1271MockContractAddress = await new ERC1271Mock__factory() .connect(anyone) .deploy() - .then((contract) => contract.deployed()); + .then((contract) => contract.waitForDeployment()) + .then((deployedContract) => deployedContract.getAddress()); } describe('Verify signature', () => { @@ -157,9 +156,9 @@ describe('IexecPoco1', () => { it(`Should ${verifySignatureFunction} of smart contract`, async () => { expect( await iexecPocoContract[verifySignatureFunction]( - erc1271MockContract.address, - HashZero, // any is fine here - ethers.utils.id('valid-signature'), + erc1271MockContractAddress, + ZeroHash, // any is fine here + ethers.id('valid-signature'), ), ).to.be.true; }); @@ -167,9 +166,9 @@ describe('IexecPoco1', () => { it(`Should fail to ${verifySignatureFunction} of smart contract when validation returns false`, async () => { expect( await iexecPocoContract[verifySignatureFunction]( - erc1271MockContract.address, - HashZero, // any is fine here - ethers.utils.id('invalid-signature'), + erc1271MockContractAddress, + ZeroHash, // any is fine here + ethers.id('invalid-signature'), ), ).to.be.false; }); @@ -177,9 +176,9 @@ describe('IexecPoco1', () => { it(`Should fail to ${verifySignatureFunction} of smart contract when validation reverts`, async () => { expect( await iexecPocoContract[verifySignatureFunction]( - erc1271MockContract.address, - HashZero, // any is fine here - ethers.utils.id('reverting-signature'), + erc1271MockContractAddress, + ZeroHash, // any is fine here + ethers.id('reverting-signature'), ), ).to.be.false; }); @@ -188,7 +187,7 @@ describe('IexecPoco1', () => { expect( await iexecPocoContract[verifySignatureFunction]( someWallet.address, - ethers.utils.hashMessage(someMessage), + ethers.hashMessage(someMessage), someWallet.signMessage(someMessage), ), ).to.be.true; @@ -198,11 +197,11 @@ describe('IexecPoco1', () => { const compactEoaSignature = compactSignature( await someWallet.signMessage(someMessage), ); - expect(ethers.utils.arrayify(compactEoaSignature).length).equal(64); + expect(ethers.getBytes(compactEoaSignature).length).equal(64); expect( await iexecPocoContract[verifySignatureFunction]( someWallet.address, - ethers.utils.hashMessage(someMessage), + ethers.hashMessage(someMessage), compactEoaSignature, ), ).to.be.true; @@ -212,7 +211,7 @@ describe('IexecPoco1', () => { await expect( iexecPocoContract[verifySignatureFunction]( someWallet.address, - ethers.utils.hashMessage(someMessage), + ethers.hashMessage(someMessage), '0x01', // bad signature format ), ).to.be.revertedWith('invalid-signature-format'); @@ -222,7 +221,7 @@ describe('IexecPoco1', () => { expect( await iexecPocoContract[verifySignatureFunction]( someWallet.address, // some EOA - ethers.utils.hashMessage(someMessage), + ethers.hashMessage(someMessage), ethers.Wallet.createRandom() // signature from another EOA .signMessage(someMessage), ), @@ -331,9 +330,7 @@ describe('IexecPoco1', () => { it(`Should fail to ${verifyPresignatureFunction} for an unknown messageHash for ${asset}`, async () => { const { providerAddress } = orderManagement[asset]; - const unknownMessageHash = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes('unknown'), - ); + const unknownMessageHash = ethers.keccak256(ethers.toUtf8Bytes('unknown')); const args = [ providerAddress, @@ -386,8 +383,8 @@ describe('IexecPoco1', () => { await iexecWrapper.depositInIexecAccount(requester, dealPrice); await iexecWrapper.depositInIexecAccount(scheduler, schedulerStake); // Save frozen balances before match. - const requesterFrozenBefore = (await iexecPoco.frozenOf(requester.address)).toNumber(); - const schedulerFrozenBefore = (await iexecPoco.frozenOf(scheduler.address)).toNumber(); + const requesterFrozenBefore = await iexecPoco.frozenOf(requester.address); + const schedulerFrozenBefore = await iexecPoco.frozenOf(scheduler.address); // Sign and match orders. const startTime = await setNextBlockTimestamp(); await signOrders(iexecWrapper.getDomain(), fullConfigOrders, ordersActors); @@ -398,7 +395,7 @@ describe('IexecPoco1', () => { await iexecPocoAccessors.computeDealVolume(...fullConfigOrders.toArray()), ).to.equal(botVolume); - expect(await iexecPoco.callStatic.matchOrders(...fullConfigOrders.toArray())).to.equal( + expect(await iexecPoco.matchOrders.staticCall(...fullConfigOrders.toArray())).to.equal( dealId, ); const tx = iexecPocoAsRequester.matchOrders(...fullConfigOrders.toArray()); @@ -522,18 +519,18 @@ describe('IexecPoco1', () => { ); // Check deal const deal = await iexecPoco.viewDeal(dealId); - expect(deal.beneficiary).to.equal(AddressZero); + expect(deal.beneficiary).to.equal(ZeroAddress); expect(deal.botSize).to.equal(1); - expect(deal.callback).to.equal(AddressZero); + expect(deal.callback).to.equal(ZeroAddress); expect(deal.trust).to.equal(1); }); it('Should match orders without: dataset', async () => { - orders.dataset.dataset = AddressZero; - orders.requester.dataset = AddressZero; + orders.dataset.dataset = ZeroAddress; + orders.requester.dataset = ZeroAddress; // Set dataset volume lower than other assets to make sure // it does not impact final volume computation. - orders.dataset.volume = botVolume - 1; + orders.dataset.volume = botVolume - 1n; orders.app.volume = botVolume; orders.workerpool.volume = botVolume; orders.requester.volume = botVolume; @@ -547,7 +544,7 @@ describe('IexecPoco1', () => { await iexecWrapper.depositInIexecAccount(requester, dealPrice); await iexecWrapper.depositInIexecAccount(scheduler, schedulerStake); // Save frozen balances before match. - const requesterFrozenBefore = (await iexecPoco.frozenOf(requester.address)).toNumber(); + const requesterFrozenBefore = await iexecPoco.frozenOf(requester.address); // Sign and match orders. await signOrders(iexecWrapper.getDomain(), orders, ordersActors); const dealId = getDealId(iexecWrapper.getDomain(), orders.requester); @@ -566,8 +563,8 @@ describe('IexecPoco1', () => { await expect(tx).to.emit(iexecPoco, 'OrdersMatched'); // Check deal const deal = await iexecPoco.viewDeal(dealId); - expect(deal.dataset.pointer).to.equal(AddressZero); - expect(deal.dataset.owner).to.equal(AddressZero); + expect(deal.dataset.pointer).to.equal(ZeroAddress); + expect(deal.dataset.owner).to.equal(ZeroAddress); expect(deal.dataset.price).to.equal(0); // BoT size should not be impacted even if the dataset order is the order with the lowest volume expect(deal.botSize).to.equal(botVolume); @@ -625,7 +622,7 @@ describe('IexecPoco1', () => { }); it(`Should match orders with any workerpool when request order has no workerpool restriction`, async () => { - orders.requester.workerpool = AddressZero; // No restriction. + orders.requester.workerpool = ZeroAddress; // No restriction. await depositForRequesterAndSchedulerWithDefaultPrices(volume); // Sign and match orders. await signOrders(iexecWrapper.getDomain(), orders, ordersActors); @@ -644,44 +641,44 @@ describe('IexecPoco1', () => { // - multiple matches of the same order it('Should fail when categories are different', async () => { - orders.requester.category = Number(orders.workerpool.category) + 1; // Valid but different category. + orders.requester.category = BigInt(orders.workerpool.category) + 1n; // Valid but different category. await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x00', ); }); it('Should fail when category is unknown', async () => { - const lastCategoryIndex = (await iexecPoco.countCategory()).toNumber() - 1; - orders.requester.category = lastCategoryIndex + 1; - orders.workerpool.category = lastCategoryIndex + 1; + const lastCategoryIndex = (await iexecPoco.countCategory()) - 1n; + orders.requester.category = lastCategoryIndex + 1n; + orders.workerpool.category = lastCategoryIndex + 1n; await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x01', ); }); it('Should fail when requested trust is above workerpool trust', async () => { - orders.requester.trust = Number(orders.workerpool.trust) + 1; + orders.requester.trust = BigInt(orders.workerpool.trust) + 1n; await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x02', ); }); it('Should fail when app max price is less than app price', async () => { - orders.requester.appmaxprice = Number(orders.app.appprice) - 1; + orders.requester.appmaxprice = BigInt(orders.app.appprice) - 1n; await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x03', ); }); it('Should fail when dataset max price is less than dataset price', async () => { - orders.requester.datasetmaxprice = Number(orders.dataset.datasetprice) - 1; + orders.requester.datasetmaxprice = BigInt(orders.dataset.datasetprice) - 1n; await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x04', ); }); it('Should fail when workerpool max price is less than workerpool price', async () => { - orders.requester.workerpoolmaxprice = Number(orders.workerpool.workerpoolprice) - 1; + orders.requester.workerpoolmaxprice = BigInt(orders.workerpool.workerpoolprice) - 1n; await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x05', ); @@ -738,7 +735,7 @@ describe('IexecPoco1', () => { await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x12', ); - orders.requester.workerpool = randomContract.address; + orders.requester.workerpool = randomContractAddress; await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x12', ); @@ -783,7 +780,7 @@ describe('IexecPoco1', () => { ); // SC // @ts-ignore - orders[orderName][assetName + 'restrict'] = randomContract.address; // e.g. orders.app.datasetrestrict = 0xSC + orders[orderName][assetName + 'restrict'] = randomContractAddress; // e.g. orders.app.datasetrestrict = 0xSC await expect(iexecPoco.matchOrders(...orders.toArray())).to.be.revertedWith( message, ); @@ -792,8 +789,8 @@ describe('IexecPoco1', () => { }); it('Should fail when app is not registered', async () => { - orders.app.app = randomContract.address; // Must be an Ownable contract. - orders.requester.app = randomContract.address; + orders.app.app = randomContractAddress; // Must be an Ownable contract. + orders.requester.app = randomContractAddress; await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x20', ); @@ -814,16 +811,16 @@ describe('IexecPoco1', () => { await IERC721__factory.connect(await iexecPoco.appregistry(), appProvider) .transferFrom( appProvider.address, - erc1271MockContract.address, + erc1271MockContractAddress, appAddress, // tokenId ) .then((tx) => tx.wait()); // Make sure the test does not fail because of another reason. - const signerAddress = ethers.utils.verifyMessage( + const signerAddress = ethers.verifyMessage( hashOrder(iexecWrapper.getDomain(), orders.app), orders.app.sign as any, ); - expect(signerAddress).to.not.equal(erc1271MockContract.address); // owner of app. + expect(signerAddress).to.not.equal(erc1271MockContractAddress); // owner of app. // Match orders. await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x21', @@ -831,8 +828,8 @@ describe('IexecPoco1', () => { }); it('Should fail when dataset is not registered', async () => { - orders.dataset.dataset = randomContract.address; // Must be an Ownable contract. - orders.requester.dataset = randomContract.address; + orders.dataset.dataset = randomContractAddress; // Must be an Ownable contract. + orders.requester.dataset = randomContractAddress; await signOrder(iexecWrapper.getDomain(), orders.app, appProvider); await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x30', @@ -854,16 +851,16 @@ describe('IexecPoco1', () => { await IERC721__factory.connect(await iexecPoco.datasetregistry(), datasetProvider) .transferFrom( datasetProvider.address, - erc1271MockContract.address, + erc1271MockContractAddress, datasetAddress, // tokenId ) .then((tx) => tx.wait()); // Make sure the test does not fail because of another reason. - const signerAddress = ethers.utils.verifyMessage( + const signerAddress = ethers.verifyMessage( hashOrder(iexecWrapper.getDomain(), orders.dataset), orders.dataset.sign as any, ); - expect(signerAddress).to.not.equal(erc1271MockContract.address); // owner of dataset. + expect(signerAddress).to.not.equal(erc1271MockContractAddress); // owner of dataset. // Match orders. await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x31', @@ -871,8 +868,8 @@ describe('IexecPoco1', () => { }); it('Should fail when workerpool is not registered', async () => { - orders.workerpool.workerpool = randomContract.address; // Must be an Ownable contract. - orders.requester.workerpool = randomContract.address; + orders.workerpool.workerpool = randomContractAddress; // Must be an Ownable contract. + orders.requester.workerpool = randomContractAddress; await signOrder(iexecWrapper.getDomain(), orders.app, appProvider); await signOrder(iexecWrapper.getDomain(), orders.dataset, datasetProvider); await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( @@ -895,16 +892,16 @@ describe('IexecPoco1', () => { await IERC721__factory.connect(await iexecPoco.workerpoolregistry(), scheduler) .transferFrom( scheduler.address, - erc1271MockContract.address, + erc1271MockContractAddress, workerpoolAddress, // tokenId ) .then((tx) => tx.wait()); // Make sure the test does not fail because of another reason. - const signerAddress = ethers.utils.verifyMessage( + const signerAddress = ethers.verifyMessage( hashOrder(iexecWrapper.getDomain(), orders.workerpool), orders.workerpool.sign as any, ); - expect(signerAddress).to.not.equal(erc1271MockContract.address); // owner of workerpool. + expect(signerAddress).to.not.equal(erc1271MockContractAddress); // owner of workerpool. // Match orders. await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x41', @@ -923,13 +920,13 @@ describe('IexecPoco1', () => { await signOrders(iexecWrapper.getDomain(), orders, ordersActors); orders.requester.sign = randomSignature; // Override signature. // Set the smart contract as the requester. - orders.requester.requester = erc1271MockContract.address; + orders.requester.requester = erc1271MockContractAddress; // Make sure the test does not fail because of another reason. - const signerAddress = ethers.utils.verifyMessage( + const signerAddress = ethers.verifyMessage( hashOrder(iexecWrapper.getDomain(), orders.requester), orders.requester.sign as any, ); - expect(signerAddress).to.not.equal(erc1271MockContract.address); // Requester. + expect(signerAddress).to.not.equal(erc1271MockContractAddress); // Requester. // Match orders. await expect(iexecPocoAsRequester.matchOrders(...orders.toArray())).to.be.revertedWith( 'iExecV5-matchOrders-0x50', @@ -942,8 +939,8 @@ describe('IexecPoco1', () => { // Needs more debugging. // // const appOrderHash = iexecWrapper.hashOrder(orders.app); - // const appOrderConsumedSlotIndex = ethers.utils.keccak256( - // ethers.utils.concat([ + // const appOrderConsumedSlotIndex = ethers.keccak256( + // ethers.concat([ // appOrderHash, // key in the mapping. // '0x12', // m_consumed mapping index. // ]) @@ -952,7 +949,7 @@ describe('IexecPoco1', () => { // await setStorageAt( // iexecPoco.address, // appOrderConsumedSlotIndex, - // ethers.utils.hexlify(Number(orders.app.volume)), + // ethers.toBeHex(orders.app.volume), // ); await depositForRequesterAndSchedulerWithDefaultPrices(botVolume); await signOrders(iexecWrapper.getDomain(), orders, ordersActors); @@ -968,7 +965,7 @@ describe('IexecPoco1', () => { volume, ); // Deposit less than deal price in the requester's account. - await iexecWrapper.depositInIexecAccount(requester, dealPrice - 1); + await iexecWrapper.depositInIexecAccount(requester, dealPrice - 1n); await iexecWrapper.depositInIexecAccount(scheduler, schedulerStake); expect(await iexecPoco.balanceOf(requester.address)).to.be.lessThan(dealPrice); expect(await iexecPoco.balanceOf(scheduler.address)).to.equal(schedulerStake); @@ -986,7 +983,7 @@ describe('IexecPoco1', () => { ); await iexecWrapper.depositInIexecAccount(requester, dealPrice); // Deposit less than stake value in the scheduler's account. - await iexecWrapper.depositInIexecAccount(scheduler, schedulerStake - 1); + await iexecWrapper.depositInIexecAccount(scheduler, schedulerStake - 1n); expect(await iexecPoco.balanceOf(requester.address)).to.equal(dealPrice); expect(await iexecPoco.balanceOf(scheduler.address)).to.be.lessThan(schedulerStake); await signOrders(iexecWrapper.getDomain(), orders, ordersActors); @@ -1002,7 +999,7 @@ describe('IexecPoco1', () => { const { appOrder, datasetOrder, workerpoolOrder, requestOrder } = orders.toObject(); // override volumes and set different value for each order // to make sure the smallest volume is considered. - const expectedVolume = 2; + const expectedVolume = 2n; appOrder.volume = 2; // smallest unconsumed volume among all orders datasetOrder.volume = 3; workerpoolOrder.volume = 4; @@ -1019,15 +1016,15 @@ describe('IexecPoco1', () => { await iexecWrapper.depositInIexecAccount(sponsor, dealPrice); await iexecWrapper.depositInIexecAccount(scheduler, schedulerStake); // Save frozen balances before match. - const sponsorFrozenBefore = (await iexecPoco.frozenOf(sponsor.address)).toNumber(); + const sponsorFrozenBefore = await iexecPoco.frozenOf(sponsor.address); // Sign and match orders. await signOrders(domain, orders, ordersActors); const dealId = getDealId(domain, orders.requester); expect( - await iexecPocoAsSponsor.callStatic.sponsorMatchOrders(...orders.toArray()), + await iexecPocoAsSponsor.sponsorMatchOrders.staticCall(...orders.toArray()), ).to.equal(dealId); expect( - await iexecPocoAccessors.callStatic.computeDealVolume(...orders.toArray()), + await iexecPocoAccessors.computeDealVolume.staticCall(...orders.toArray()), ).to.equal(expectedVolume); const tx = iexecPocoAsSponsor.sponsorMatchOrders(...orders.toArray()); // Check balances and frozen. @@ -1068,7 +1065,7 @@ describe('IexecPoco1', () => { volume, ); // Deposit less than deal price in the sponsor's account. - await iexecWrapper.depositInIexecAccount(sponsor, dealPrice - 1); + await iexecWrapper.depositInIexecAccount(sponsor, dealPrice - 1n); await iexecWrapper.depositInIexecAccount(scheduler, schedulerStake); // Sign and match orders. await signOrders(iexecWrapper.getDomain(), orders, ordersActors); @@ -1082,7 +1079,7 @@ describe('IexecPoco1', () => { * Helper function to deposit requester and scheduler stakes with * default prices for tests that do not rely on custom prices. */ - async function depositForRequesterAndSchedulerWithDefaultPrices(volume: number) { + async function depositForRequesterAndSchedulerWithDefaultPrices(volume: bigint) { const dealPrice = (appPrice + datasetPrice + workerpoolPrice) * volume; const schedulerStake = await iexecWrapper.computeSchedulerDealStake( workerpoolPrice, diff --git a/test/byContract/IexecPoco/IexecPoco2-claim.test.ts b/test/byContract/IexecPoco/IexecPoco2-claim.test.ts index 499d492c5..4d79bb2d3 100644 --- a/test/byContract/IexecPoco/IexecPoco2-claim.test.ts +++ b/test/byContract/IexecPoco/IexecPoco2-claim.test.ts @@ -1,10 +1,10 @@ -// SPDX-FileCopyrightText: 2024 IEXEC BLOCKCHAIN TECH +// SPDX-FileCopyrightText: 2024-2025 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { loadFixture, mine, time } from '@nomicfoundation/hardhat-network-helpers'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { expect } from 'chai'; -import { ethers } from 'hardhat'; +import { ZeroAddress, ethers } from 'ethers'; import { IexecInterfaceNative, IexecInterfaceNative__factory } from '../../../typechain'; import { OrdersAssets, OrdersPrices, buildOrders } from '../../../utils/createOrders'; import { @@ -19,14 +19,14 @@ import { IexecWrapper } from '../../utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; import * as constants from './../../../utils/constants'; -const categoryTime = 300; -const maxDealDuration = 10 * categoryTime; +const categoryTime = 300n; +const maxDealDuration = 10n * categoryTime; const { results, resultDigest } = buildUtf8ResultAndDigest('result'); -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; const taskPrice = appPrice + datasetPrice + workerpoolPrice; -const enclaveAddress = ethers.constants.AddressZero; +const enclaveAddress = ZeroAddress; describe('IexecPoco2#claim', async () => { let proxyAddress: string; @@ -71,8 +71,8 @@ describe('IexecPoco2#claim', async () => { * task after deadline. The task comes from a deal payed by a sponsor. */ it('Should claim task of deal payed by sponsor', async () => { - const expectedVolume = 3; // > 1 to explicit taskPrice vs dealPrice - const claimedTasks = 1; + const expectedVolume = 3n; // > 1 to explicit taskPrice vs dealPrice + const claimedTasks = 1n; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, @@ -89,9 +89,7 @@ describe('IexecPoco2#claim', async () => { const schedulerTaskStake = schedulerDealStake / expectedVolume; const kittyAddress = await iexecPoco.kitty_address(); await iexecPocoAsAnyone.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const workers = [worker1, worker2]; for (const worker of workers) { const { resultHash, resultSeal } = buildResultHashAndResultSeal( @@ -108,18 +106,11 @@ describe('IexecPoco2#claim', async () => { await iexecWrapper.depositInIexecAccount(worker, workerTaskStake); await iexecPoco .connect(worker) - .contribute( - taskId, - resultHash, - resultSeal, - ethers.constants.AddressZero, - '0x', - schedulerSignature, - ) + .contribute(taskId, resultHash, resultSeal, ZeroAddress, '0x', schedulerSignature) .then((tx) => tx.wait()); } - expect(await iexecPoco.balanceOf(iexecPoco.address)).to.be.equal( - dealPrice + schedulerDealStake + workerTaskStake * workers.length, + expect(await iexecPoco.balanceOf(proxyAddress)).to.be.equal( + dealPrice + schedulerDealStake + workerTaskStake * BigInt(workers.length), ); expect(await iexecPoco.balanceOf(requester.address)).to.be.equal(0); expect(await iexecPoco.frozenOf(requester.address)).to.be.equal(0); @@ -140,7 +131,7 @@ describe('IexecPoco2#claim', async () => { await claimTx.wait(); await expect(claimTx) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, sponsor.address, taskPrice) + .withArgs(proxyAddress, sponsor.address, taskPrice) .to.emit(iexecPoco, 'Unlock') .withArgs(sponsor.address, taskPrice) .to.emit(iexecPoco, 'Seize') @@ -152,7 +143,7 @@ describe('IexecPoco2#claim', async () => { for (const worker of workers) { await expect(claimTx) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, worker.address, workerTaskStake) + .withArgs(proxyAddress, worker.address, workerTaskStake) .to.emit(iexecPoco, 'Unlock') .withArgs(worker.address, workerTaskStake); } @@ -160,7 +151,7 @@ describe('IexecPoco2#claim', async () => { expect((await iexecPoco.viewTask(taskId)).status).to.equal(TaskStatusEnum.FAILED); const remainingTasksToClaim = expectedVolume - claimedTasks; - expect(await iexecPoco.balanceOf(iexecPoco.address)).to.be.equal( + expect(await iexecPoco.balanceOf(proxyAddress)).to.be.equal( taskPrice * remainingTasksToClaim + // sponsor has 2nd & 3rd task locked schedulerDealStake, // kitty value since 1st task seized ); @@ -204,7 +195,7 @@ describe('IexecPoco2#claim', async () => { await expect(iexecPocoAsAnyone.claim(taskId)) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, requester.address, taskPrice) + .withArgs(proxyAddress, requester.address, taskPrice) .to.emit(iexecPoco, 'Unlock') .withArgs(requester.address, taskPrice) .to.emit(iexecPoco, 'TaskClaimed'); @@ -259,9 +250,7 @@ describe('IexecPoco2#claim', async () => { enclaveAddress, scheduler, ); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); await iexecWrapper.depositInIexecAccount(worker1, workerTaskStake); await iexecPoco .connect(worker1) @@ -297,7 +286,7 @@ describe('IexecPoco2#claim', async () => { describe('Claim array', () => { it('Should claim array', async () => { - const volume = 3; + const volume = 3n; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, @@ -316,7 +305,7 @@ describe('IexecPoco2#claim', async () => { // Mine empty block so timestamp is accurate when static call is made await mine(); - expect(await iexecPocoAsAnyone.callStatic.claimArray(taskIds)).to.be.true; + expect(await iexecPocoAsAnyone.claimArray.staticCall(taskIds)).to.be.true; const claimArrayTx = await iexecPocoAsAnyone.claimArray(taskIds); await claimArrayTx.wait(); for (let taskId of taskIds) { @@ -325,7 +314,7 @@ describe('IexecPoco2#claim', async () => { }); it('Should not claim array when one is not claimable', async () => { - const volume = 2; + const volume = 2n; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, @@ -344,15 +333,15 @@ describe('IexecPoco2#claim', async () => { await time.setNextBlockTimestamp(startTime + maxDealDuration); // Check first task is claimable and second task is not claimable - await expect(iexecPoco.estimateGas.claim(taskId1)).to.not.be.revertedWithoutReason(); - await expect(iexecPoco.estimateGas.claim(taskId2)).to.be.revertedWithoutReason(); + await expect(iexecPoco.claim.estimateGas(taskId1)).to.not.be.revertedWithoutReason(); + await expect(iexecPoco.claim.estimateGas(taskId2)).to.be.revertedWithoutReason(); // Claim array will fail await expect(iexecPoco.claimArray([taskId1, taskId2])).to.be.revertedWithoutReason(); }); describe('Initialize and claim array', () => { it('Should initialize and claim array', async () => { - const volume = 3; + const volume = 3n; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, @@ -369,7 +358,7 @@ describe('IexecPoco2#claim', async () => { expect( await iexecPoco .connect(anyone) - .callStatic.initializeAndClaimArray(dealIds, taskIndexes), + .initializeAndClaimArray.staticCall(dealIds, taskIndexes), ).to.be.true; const initializeAndClaimArrayTx = await iexecPoco .connect(anyone) @@ -386,14 +375,14 @@ describe('IexecPoco2#claim', async () => { }); it('Should not initialize and claim array if incompatible length of inputs', async () => { - const dealId = ethers.utils.hashMessage('dealId'); + const dealId = ethers.hashMessage('dealId'); await expect( iexecPoco.initializeAndClaimArray([dealId, dealId], [0]), ).to.be.revertedWithoutReason(); }); it('Should not initialize and claim array if one specific fails', async () => { - const volume = 2; + const volume = 2n; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, diff --git a/test/byContract/IexecPoco/IexecPoco2-contribute-and-finalize.test.ts b/test/byContract/IexecPoco/IexecPoco2-contribute-and-finalize.test.ts index 7d0d4142d..4bc89d472 100644 --- a/test/byContract/IexecPoco/IexecPoco2-contribute-and-finalize.test.ts +++ b/test/byContract/IexecPoco/IexecPoco2-contribute-and-finalize.test.ts @@ -1,11 +1,10 @@ // SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 -import { AddressZero, HashZero } from '@ethersproject/constants'; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { expect } from 'chai'; -import { ethers } from 'hardhat'; +import { Wallet, ZeroAddress, ZeroHash, ethers } from 'ethers'; import { IexecInterfaceNative, IexecInterfaceNative__factory, @@ -27,16 +26,16 @@ import { IexecWrapper } from '../../utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; const CONFIG = require('../../../config/config.json'); -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; const taskPrice = appPrice + datasetPrice + workerpoolPrice; const timeRef = CONFIG.categories[0].workClockTimeRef; const trust = 1; -const volume = 1; +const volume = 1n; const teeDealTag = '0x0000000000000000000000000000000000000000000000000000000000000001'; -const standardDealTag = HashZero; -const emptyEnclaveAddress = AddressZero; +const standardDealTag = ZeroHash; +const emptyEnclaveAddress = ZeroAddress; const emptyEnclaveSignature = '0x'; const noCallbackData = '0x'; const noResultsData = '0x'; @@ -74,9 +73,9 @@ describe('IexecPoco2#contributeAndFinalize', () => { const { appAddress, datasetAddress, workerpoolAddress } = await iexecWrapper.createAssets(); iexecPoco = IexecInterfaceNative__factory.connect(proxyAddress, anyone); iexecPocoAsWorker = iexecPoco.connect(worker); - const appPrice = 1000; - const datasetPrice = 1_000_000; - const workerpoolPrice = 1_000_000_000; + const appPrice = 1000n; + const datasetPrice = 1_000_000n; + const workerpoolPrice = 1_000_000_000n; ordersAssets = { app: appAddress, dataset: datasetAddress, @@ -94,7 +93,8 @@ describe('IexecPoco2#contributeAndFinalize', () => { const callbackConsumer = await new TestClient__factory() .connect(anyone) .deploy() - .then((contract) => contract.deployed()); + .then((contract) => contract.waitForDeployment()); + const callbackConsumerAddress = await callbackConsumer.getAddress(); // Create deal and task. const { dealId, taskIndex, taskId } = await iexecWrapper.signAndMatchOrders( ...buildOrders({ @@ -104,7 +104,7 @@ describe('IexecPoco2#contributeAndFinalize', () => { volume, trust, tag: teeDealTag, - callback: callbackConsumer.address, + callback: callbackConsumerAddress, }).toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); @@ -183,10 +183,10 @@ describe('IexecPoco2#contributeAndFinalize', () => { // Check frozen changes. const expectedFrozenChanges = [ -taskPrice, // Requester (dealPrice) - 0, // App provider - 0, // Dataset provider + 0n, // App provider + 0n, // Dataset provider -schedulerStake, // Scheduler - 0, // Worker + 0n, // Worker ]; await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); // Check events. @@ -194,23 +194,23 @@ describe('IexecPoco2#contributeAndFinalize', () => { .to.emit(iexecPoco, 'Seize') .withArgs(requester.address, taskPrice, taskId) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, appProvider.address, appPrice) + .withArgs(proxyAddress, appProvider.address, appPrice) .to.emit(iexecPoco, 'Reward') .withArgs(appProvider.address, appPrice, taskId) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, datasetProvider.address, datasetPrice) + .withArgs(proxyAddress, datasetProvider.address, datasetPrice) .to.emit(iexecPoco, 'Reward') .withArgs(datasetProvider.address, datasetPrice, taskId) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, scheduler.address, schedulerStake) + .withArgs(proxyAddress, scheduler.address, schedulerStake) .to.emit(iexecPoco, 'Unlock') .withArgs(scheduler.address, schedulerStake) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, worker.address, workersReward) + .withArgs(proxyAddress, worker.address, workersReward) .to.emit(iexecPoco, 'Reward') .withArgs(worker.address, workersReward, taskId) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, scheduler.address, schedulerReward) + .withArgs(proxyAddress, scheduler.address, schedulerReward) .to.emit(iexecPoco, 'Reward') .withArgs(scheduler.address, schedulerReward, taskId); // Task events. @@ -267,7 +267,7 @@ describe('IexecPoco2#contributeAndFinalize', () => { const task = await iexecPoco.viewTask(taskId); expect(task.status).to.equal(TaskStatusEnum.COMPLETED); expect(task.resultDigest).to.equal(resultDigest); - expect(task.results).to.equal(ethers.utils.hexlify(results)); + expect(task.results).to.equal(ethers.hexlify(results)); expect(task.resultsCallback).to.equal(noCallbackData); // Check events. await expect(contributeAndFinalizeTx) @@ -397,7 +397,7 @@ describe('IexecPoco2#contributeAndFinalize', () => { volume, trust, tag: standardDealTag, - callback: ethers.Wallet.createRandom().address, // Using callback + callback: Wallet.createRandom().address, // Using callback }).toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); @@ -408,7 +408,7 @@ describe('IexecPoco2#contributeAndFinalize', () => { taskId, resultsCallbackDigest, noResultsData, - ethers.utils.hexlify(ethers.utils.randomBytes(32)), // Bad callback data. + ethers.hexlify(ethers.randomBytes(32)), // Bad callback data. emptyEnclaveAddress, emptyEnclaveSignature, await buildAndSignContributionAuthorizationMessage( diff --git a/test/byContract/IexecPoco/IexecPoco2-contribute.test.ts b/test/byContract/IexecPoco/IexecPoco2-contribute.test.ts index 4364a8980..c60308a6b 100644 --- a/test/byContract/IexecPoco/IexecPoco2-contribute.test.ts +++ b/test/byContract/IexecPoco/IexecPoco2-contribute.test.ts @@ -1,10 +1,10 @@ -// SPDX-FileCopyrightText: 2020-2024 IEXEC BLOCKCHAIN TECH +// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 -import { AddressZero, HashZero } from '@ethersproject/constants'; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { assert, expect } from 'chai'; +import { ZeroAddress, ZeroHash } from 'ethers'; import { IexecInterfaceNative, IexecInterfaceNative__factory } from '../../../typechain'; import { NULL } from '../../../utils/constants'; import { IexecOrders, OrdersAssets, OrdersPrices, buildOrders } from '../../../utils/createOrders'; @@ -24,12 +24,12 @@ import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deploy const CONFIG = require('../../../config/config.json'); const timeRef = CONFIG.categories[0].workClockTimeRef; -const volume = 3; +const volume = 3n; const teeDealTag = '0x0000000000000000000000000000000000000000000000000000000000000001'; -const standardDealTag = HashZero; +const standardDealTag = ZeroHash; const { resultDigest } = buildUtf8ResultAndDigest('result'); const { resultDigest: badResultDigest } = buildUtf8ResultAndDigest('bad-result'); -const emptyEnclaveAddress = AddressZero; +const emptyEnclaveAddress = ZeroAddress; const emptyEnclaveSignature = NULL.SIGNATURE; describe('IexecPoco2#contribute', () => { @@ -75,9 +75,9 @@ describe('IexecPoco2#contribute', () => { const { appAddress, datasetAddress, workerpoolAddress } = await iexecWrapper.createAssets(); iexecPoco = IexecInterfaceNative__factory.connect(proxyAddress, anyone); iexecPocoAsWorker = iexecPoco.connect(worker); - const appPrice = 1000; - const datasetPrice = 1_000_000; - const workerpoolPrice = 1_000_000_000; + const appPrice = 1000n; + const datasetPrice = 1_000_000n; + const workerpoolPrice = 1_000_000_000n; ordersAssets = { app: appAddress, dataset: datasetAddress, @@ -114,7 +114,7 @@ describe('IexecPoco2#contribute', () => { await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); const workerTaskStake = await iexecPoco .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + .then((deal) => deal.workerStake); const workers = [ { signer: worker1, resultDigest: resultDigest }, { signer: worker2, resultDigest: badResultDigest }, @@ -126,7 +126,7 @@ describe('IexecPoco2#contribute', () => { let task; let contributeBlockTimestamp; const viewFrozenOf = (address: string) => - iexecPoco.frozenOf(address).then((frozen) => frozen.toNumber()); + iexecPoco.frozenOf(address); for (let i = 0; i < workers.length; i++) { const worker = workers[i]; const workerAddress = worker.signer.address; @@ -166,12 +166,14 @@ describe('IexecPoco2#contribute', () => { task = await iexecPoco.viewTask(taskId); expect(task.contributors.length).equal(i + 1); expect(task.contributors[i]).equal(workerAddress); + + // The matcher 'emit' cannot be chained after 'changeTokenBalances' - https://hardhat.org/chaining-async-matchers + await expect(tx).to.changeTokenBalances( + iexecPoco, + [workerAddress, proxyAddress], + [-workerTaskStake, workerTaskStake], + ); await expect(tx) - .to.changeTokenBalances( - iexecPoco, - [workerAddress, proxyAddress], - [-workerTaskStake, workerTaskStake], - ) .to.emit(iexecPoco, 'Transfer') .withArgs(workerAddress, proxyAddress, workerTaskStake); expect(await viewFrozenOf(workerAddress)).equal(frozenBefore + workerTaskStake); @@ -218,7 +220,7 @@ describe('IexecPoco2#contribute', () => { await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); const workerTaskStake = await iexecPoco .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + .then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, resultDigest, @@ -249,7 +251,7 @@ describe('IexecPoco2#contribute', () => { await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); const workerTaskStake = await iexecPoco .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + .then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, resultDigest, @@ -343,7 +345,7 @@ describe('IexecPoco2#contribute', () => { await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); const workerTaskStake = await iexecPoco .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + .then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, resultDigest, diff --git a/test/byContract/IexecPoco/IexecPoco2-finalize.test.ts b/test/byContract/IexecPoco/IexecPoco2-finalize.test.ts index 189133fc6..915bd3242 100644 --- a/test/byContract/IexecPoco/IexecPoco2-finalize.test.ts +++ b/test/byContract/IexecPoco/IexecPoco2-finalize.test.ts @@ -1,10 +1,10 @@ -// SPDX-FileCopyrightText: 2024 IEXEC BLOCKCHAIN TECH +// SPDX-FileCopyrightText: 2024-2025 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 -import { AddressZero } from '@ethersproject/constants'; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { loadFixture, setStorageAt, time } from '@nomicfoundation/hardhat-network-helpers'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { expect } from 'chai'; +import { AbiCoder, Wallet, ZeroAddress } from 'ethers'; import { ethers } from 'hardhat'; import { IexecInterfaceNative, @@ -25,14 +25,14 @@ import { IexecWrapper } from '../../utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; const { results, resultDigest } = buildUtf8ResultAndDigest('result'); -const hexResults = ethers.utils.hexlify(results); +const hexResults = ethers.hexlify(results); const { resultsCallback, callbackResultDigest } = buildResultCallbackAndDigest(123); -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; const taskPrice = appPrice + datasetPrice + workerpoolPrice; -const emptyEnclaveAddress = AddressZero; +const emptyEnclaveAddress = ZeroAddress; const emptyEnclaveSignature = '0x'; describe('IexecPoco2#finalize', async () => { @@ -96,15 +96,15 @@ describe('IexecPoco2#finalize', async () => { const oracleConsumerInstance = await new TestClient__factory() .connect(anyone) .deploy() - .then((contract) => contract.deployed()); - const expectedVolume = 3; // > 1 to explicit taskPrice vs dealPrice + .then((contract) => contract.waitForDeployment()); + const expectedVolume = 3n; // > 1 to explicit taskPrice vs dealPrice const orders = buildOrders({ assets: ordersAssets, requester: requester.address, prices: ordersPrices, volume: expectedVolume, trust: 3, - callback: oracleConsumerInstance.address, + callback: await oracleConsumerInstance.getAddress(), }); const { dealId, taskId, taskIndex, dealPrice } = await iexecWrapper.signAndSponsorMatchOrders(...orders.toArray()); @@ -115,9 +115,7 @@ describe('IexecPoco2#finalize', async () => { const schedulerTaskStake = schedulerDealStake / expectedVolume; const kittyAddress = await iexecPoco.kitty_address(); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const { callbackResultDigest: wrongCallbackResultDigest } = buildResultCallbackAndDigest(567); const workers = [ @@ -167,14 +165,14 @@ describe('IexecPoco2#finalize', async () => { .then((tx) => tx.wait()); } const requesterFrozenBefore = await iexecPoco.frozenOf(requester.address); - const sponsorFrozenBefore = (await iexecPoco.frozenOf(sponsor.address)).toNumber(); - const schedulerFrozenBefore = (await iexecPoco.frozenOf(scheduler.address)).toNumber(); - const workersFrozenBefore: { [name: string]: number } = {}; + const sponsorFrozenBefore = await iexecPoco.frozenOf(sponsor.address); + const schedulerFrozenBefore = await iexecPoco.frozenOf(scheduler.address); + const workersFrozenBefore: { [name: string]: bigint } = {}; for (const worker of workers) { const workerAddress = worker.signer.address; workersFrozenBefore[workerAddress] = await iexecPoco .frozenOf(workerAddress) - .then((frozen) => frozen.toNumber()); + .then((frozen) => frozen); expect(await iexecPoco.viewScore(workerAddress)).to.be.equal(1); } const kittyFrozenBefore = await iexecPoco.frozenOf(kittyAddress); @@ -188,26 +186,26 @@ describe('IexecPoco2#finalize', async () => { .to.emit(iexecPoco, 'Seize') .withArgs(sponsor.address, taskPrice, taskId) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, appProvider.address, appPrice) + .withArgs(proxyAddress, appProvider.address, appPrice) .to.emit(iexecPoco, 'Reward') .withArgs(appProvider.address, appPrice, taskId) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, datasetProvider.address, datasetPrice) + .withArgs(proxyAddress, datasetProvider.address, datasetPrice) .to.emit(iexecPoco, 'Reward') .withArgs(datasetProvider.address, datasetPrice, taskId) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, scheduler.address, schedulerTaskStake) + .withArgs(proxyAddress, scheduler.address, schedulerTaskStake) .to.emit(iexecPoco, 'Unlock') .withArgs(scheduler.address, schedulerTaskStake); - const workerReward = 429000000; + const workerReward = 429000000n; for (const worker of winningWorkers) { await expect(finalizeTx) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, worker.address, workerTaskStake) + .withArgs(proxyAddress, worker.address, workerTaskStake) .to.emit(iexecPoco, 'Unlock') .withArgs(worker.address, workerTaskStake) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, worker.address, workerReward) + .withArgs(proxyAddress, worker.address, workerReward) .to.emit(iexecPoco, 'Reward') .withArgs(worker.address, workerReward, taskId) .to.emit(iexecPoco, 'AccurateContribution') @@ -220,11 +218,11 @@ describe('IexecPoco2#finalize', async () => { .withArgs(losingWorker.address, taskId); const schedulerReward = workerpoolPrice - - winningWorkers.length * workerReward + // winning workers rewards + BigInt(winningWorkers.length) * workerReward + // winning workers rewards workerTaskStake; // losing worker stake await expect(finalizeTx) .to.emit(iexecPoco, 'Transfer') - .withArgs(iexecPoco.address, scheduler.address, schedulerReward) + .withArgs(proxyAddress, scheduler.address, schedulerReward) .to.emit(iexecPoco, 'Reward') .withArgs(scheduler.address, schedulerReward, taskId) .to.emit(iexecPoco, 'TaskFinalize') @@ -256,7 +254,7 @@ describe('IexecPoco2#finalize', async () => { datasetPrice + workerpoolPrice + schedulerTaskStake + - workerTaskStake * workers.length + workerTaskStake * BigInt(workers.length) ), 0, // requester is unrelated to this test 0, // sponsor balance is unchanged, only frozen is changed @@ -294,7 +292,7 @@ describe('IexecPoco2#finalize', async () => { const orders = buildOrders({ assets: { app: appAddress, - dataset: AddressZero, + dataset: ZeroAddress, workerpool: workerpoolAddress, }, requester: requester.address, @@ -305,9 +303,7 @@ describe('IexecPoco2#finalize', async () => { ...orders.toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, resultDigest, @@ -335,21 +331,21 @@ describe('IexecPoco2#finalize', async () => { .connect(worker1) .reveal(taskId, resultDigest) .then((tx) => tx.wait()); - const requesterFrozenBefore = (await iexecPoco.frozenOf(requester.address)).toNumber(); + const requesterFrozenBefore = await iexecPoco.frozenOf(requester.address); const sponsorFrozenBefore = await iexecPoco.frozenOf(sponsor.address); - await expect(iexecPocoAsScheduler.finalize(taskId, results, '0x')) - .to.changeTokenBalances( - iexecPoco, - [requester, sponsor, appProvider, datasetProvider], - [ - 0, // requester balance is unchanged, only frozen is changed - 0, - appPrice, // app provider is rewarded - 0, // but dataset provider is not rewarded - ], - ) - .to.emit(iexecPoco, 'TaskFinalize'); + const txFinalize = iexecPocoAsScheduler.finalize(taskId, results, '0x'); + await expect(txFinalize).to.changeTokenBalances( + iexecPoco, + [requester, sponsor, appProvider, datasetProvider], + [ + 0, // requester balance is unchanged, only frozen is changed + 0, + appPrice, // app provider is rewarded + 0, // but dataset provider is not rewarded + ], + ); + await expect(txFinalize).to.emit(iexecPoco, 'TaskFinalize'); expect(await iexecPoco.frozenOf(requester.address)).to.be.equal( requesterFrozenBefore - taskPrice, ); @@ -359,7 +355,7 @@ describe('IexecPoco2#finalize', async () => { }); it('Should finalize task when callback address is EOA', async () => { - const callbackEOAAddress = ethers.Wallet.createRandom().address; + const callbackEOAAddress = Wallet.createRandom().address; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, @@ -371,9 +367,7 @@ describe('IexecPoco2#finalize', async () => { ...orders.toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, callbackResultDigest, @@ -408,24 +402,23 @@ describe('IexecPoco2#finalize', async () => { }); it('Should finalize task when callback address is non-EIP1154 contract', async () => { - const nonEip1154RandomContract = await new OwnableMock__factory() + const nonEip1154RandomContractAddress = await new OwnableMock__factory() .connect(anyone) .deploy() - .then((contract) => contract.deployed()); + .then((contract) => contract.waitForDeployment()) + .then((deployedContract) => deployedContract.getAddress()); const orders = buildOrders({ assets: ordersAssets, requester: requester.address, prices: ordersPrices, - callback: nonEip1154RandomContract.address, + callback: nonEip1154RandomContractAddress, }); const { dealId, taskId, taskIndex } = await iexecWrapper.signAndMatchOrders( ...orders.toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, callbackResultDigest, @@ -464,21 +457,21 @@ describe('IexecPoco2#finalize', async () => { { testInfo: 'scheduler gets 10% of the kitty when these 10% are greater than MIN_KITTY', // (MIN_KITTY=1RLC) - workerpoolPriceToFillKitty: 33_333_333_367, - expectedKittyBeforeFinalize: 10_000_000_010, // ~10 RLC - expectedSchedulerKittyPartReward: 1_000_000_001, // ~1.01 RLC (expectedKittyBeforeFinalize x 10%) + workerpoolPriceToFillKitty: 33_333_333_367n, + expectedKittyBeforeFinalize: 10_000_000_010n, // ~10 RLC + expectedSchedulerKittyPartReward: 1_000_000_001n, // ~1.01 RLC (expectedKittyBeforeFinalize x 10%) }, { testInfo: 'scheduler gets at least MIN_KITTY if available', - workerpoolPriceToFillKitty: 3_333_333_334, - expectedKittyBeforeFinalize: 1_000_000_000, // 1 RLC - expectedSchedulerKittyPartReward: 1_000_000_000, + workerpoolPriceToFillKitty: 3_333_333_334n, + expectedKittyBeforeFinalize: 1_000_000_000n, // 1 RLC + expectedSchedulerKittyPartReward: 1_000_000_000n, }, { testInfo: 'scheduler gets all kitty when the kitty is lower than MIN_KITTY', - workerpoolPriceToFillKitty: 3_333_333_330, - expectedKittyBeforeFinalize: 999_999_999, // ~0.99 RLC - expectedSchedulerKittyPartReward: 999_999_999, + workerpoolPriceToFillKitty: 3_333_333_330n, + expectedKittyBeforeFinalize: 999_999_999n, // ~0.99 RLC + expectedSchedulerKittyPartReward: 999_999_999n, }, ].forEach((testArgs) => { const { @@ -490,7 +483,7 @@ describe('IexecPoco2#finalize', async () => { it(`Should finalize task with scheduler kitty part reward where ${testInfo}`, async () => { // Fill kitty const kittyAddress = await iexecPoco.kitty_address(); - const kittyFillingDealVolume = 1; + const kittyFillingDealVolume = 1n; const kittyFillingSchedulerDealStake = await iexecWrapper.computeSchedulerDealStake( workerpoolPriceToFillKitty, kittyFillingDealVolume, @@ -502,35 +495,36 @@ describe('IexecPoco2#finalize', async () => { assets: ordersAssets, requester: requester.address, prices: { - app: 0, - dataset: 0, + app: 0n, + dataset: 0n, workerpool: workerpoolPriceToFillKitty, // 30% will go to kitty }, volume: kittyFillingDealVolume, - salt: ethers.utils.id(new Date().toISOString()), + salt: ethers.id(new Date().toISOString()), }).toArray(), ); await iexecPoco .initialize(kittyFillingDeal.dealId, kittyFillingDeal.taskIndex) .then((tx) => tx.wait()); - const kittyFrozenBeforeClaim = (await iexecPoco.frozenOf(kittyAddress)).toNumber(); + const kittyFrozenBeforeClaim = await iexecPoco.frozenOf(kittyAddress); await time.setNextBlockTimestamp( (await iexecPoco.viewTask(kittyFillingDeal.taskId)).finalDeadline, ); - await expect(iexecPoco.claim(kittyFillingDeal.taskId)) - .to.changeTokenBalances( - iexecPoco, - [iexecPoco, kittyAddress], - [ - -workerpoolPriceToFillKitty, // deal payer is refunded - 0, - ], - ) + const tx = iexecPoco.claim(kittyFillingDeal.taskId); + await expect(tx).to.changeTokenBalances( + iexecPoco, + [iexecPoco, kittyAddress], + [ + -workerpoolPriceToFillKitty, // deal payer is refunded + 0, + ], + ); + await expect(tx) .to.emit(iexecPoco, 'Reward') .withArgs(kittyAddress, kittyFillingSchedulerTaskStake, kittyFillingDeal.taskId) .to.emit(iexecPoco, 'Lock') .withArgs(kittyAddress, kittyFillingSchedulerTaskStake); - const kittyFrozenAfterClaim = (await iexecPoco.frozenOf(kittyAddress)).toNumber(); + const kittyFrozenAfterClaim = await iexecPoco.frozenOf(kittyAddress); expect(kittyFrozenAfterClaim).to.equal( kittyFrozenBeforeClaim + kittyFillingSchedulerTaskStake, ); @@ -541,12 +535,12 @@ describe('IexecPoco2#finalize', async () => { assets: ordersAssets, requester: requester.address, prices: { - app: 0, - dataset: 0, - workerpool: 0, + app: 0n, + dataset: 0n, + workerpool: 0n, }, - volume: 1, - salt: ethers.utils.id(new Date().toISOString()), + volume: 1n, + salt: ethers.id(new Date().toISOString()), }).toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); @@ -566,7 +560,7 @@ describe('IexecPoco2#finalize', async () => { await buildAndSignContributionAuthorizationMessage( worker1.address, taskId, - AddressZero, + ZeroAddress, scheduler, ), ) @@ -575,21 +569,19 @@ describe('IexecPoco2#finalize', async () => { .connect(worker1) .reveal(taskId, resultDigest) .then((tx) => tx.wait()); - await expect(iexecPocoAsScheduler.finalize(taskId, results, '0x')) - .to.changeTokenBalances( - iexecPoco, - [iexecPoco, scheduler, kittyAddress], - [-expectedSchedulerKittyPartReward, expectedSchedulerKittyPartReward, 0], - ) + + const txFinalize = iexecPocoAsScheduler.finalize(taskId, results, '0x'); + await expect(txFinalize).to.changeTokenBalances( + iexecPoco, + [iexecPoco, scheduler, kittyAddress], + [-expectedSchedulerKittyPartReward, expectedSchedulerKittyPartReward, 0], + ); + await expect(txFinalize) .to.emit(iexecPoco, 'TaskFinalize') .to.emit(iexecPoco, 'Seize') .withArgs(kittyAddress, expectedSchedulerKittyPartReward, taskId) .to.emit(iexecPoco, 'Transfer') - .withArgs( - iexecPoco.address, - scheduler.address, - expectedSchedulerKittyPartReward, - ) + .withArgs(proxyAddress, scheduler.address, expectedSchedulerKittyPartReward) .to.emit(iexecPoco, 'Reward') .withArgs(scheduler.address, expectedSchedulerKittyPartReward, taskId); expect(await iexecPoco.frozenOf(kittyAddress)).to.equal( @@ -600,21 +592,18 @@ describe('IexecPoco2#finalize', async () => { }); it('Should finalize task after reveal deadline with at least one reveal', async () => { - const volume = 1; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, prices: ordersPrices, - volume, + volume: 1n, trust: 3, }); const { dealId, taskId, taskIndex } = await iexecWrapper.signAndMatchOrders( ...orders.toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const workers = [worker1, worker2]; for (const worker of workers) { const { resultHash, resultSeal } = buildResultHashAndResultSeal( @@ -697,9 +686,7 @@ describe('IexecPoco2#finalize', async () => { }).toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, resultDigest, @@ -742,9 +729,7 @@ describe('IexecPoco2#finalize', async () => { }).toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const workers = [worker1, worker2]; for (const worker of workers) { const { resultHash, resultSeal } = buildResultHashAndResultSeal( @@ -791,9 +776,7 @@ describe('IexecPoco2#finalize', async () => { }).toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, resultDigest, @@ -833,24 +816,23 @@ describe('IexecPoco2#finalize', async () => { }); it('Should not finalize task when result callback is bad', async () => { - const oracleConsumerInstance = await new TestClient__factory() + const oracleConsumerAddress = await new TestClient__factory() .connect(anyone) .deploy() - .then((contract) => contract.deployed()); + .then((contract) => contract.waitForDeployment()) + .then((deployedContract) => deployedContract.getAddress()); const orders = buildOrders({ assets: ordersAssets, requester: requester.address, prices: ordersPrices, - callback: oracleConsumerInstance.address, + callback: oracleConsumerAddress, }); const { dealId, taskId, taskIndex } = await iexecWrapper.signAndMatchOrders( ...orders.toArray(), ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, callbackResultDigest, @@ -891,9 +873,9 @@ describe('IexecPoco2#finalize', async () => { }); async function setWorkerScoreInStorage(worker: string, score: number) { - const workerScoreSlot = ethers.utils.hexStripZeros( - ethers.utils.keccak256( - ethers.utils.defaultAbiCoder.encode( + const workerScoreSlot = ethers.stripZerosLeft( + ethers.keccak256( + AbiCoder.defaultAbiCoder().encode( ['address', 'uint256'], [ worker, diff --git a/test/byContract/IexecPoco/IexecPoco2-initialize.test.ts b/test/byContract/IexecPoco/IexecPoco2-initialize.test.ts index ffcdf55cc..6a21bb582 100644 --- a/test/byContract/IexecPoco/IexecPoco2-initialize.test.ts +++ b/test/byContract/IexecPoco/IexecPoco2-initialize.test.ts @@ -1,8 +1,8 @@ -// SPDX-FileCopyrightText: 2024 IEXEC BLOCKCHAIN TECH +// SPDX-FileCopyrightText: 2024-2025 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { expect } from 'chai'; import { ethers } from 'hardhat'; import { IexecInterfaceNative, IexecInterfaceNative__factory } from '../../../typechain'; @@ -16,11 +16,10 @@ import { TaskStatusEnum, getIexecAccounts, getTaskId } from '../../../utils/poco import { IexecWrapper } from '../../utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; -const categoryTime = 300; -const maxDealDuration = 10 * categoryTime; -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const categoryTime = 300n; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; describe('IexecPoco2#initialize', async () => { let proxyAddress: string; @@ -71,7 +70,7 @@ describe('IexecPoco2#initialize', async () => { ); expect((await iexecPoco.viewTask(taskId)).status).equal(TaskStatusEnum.UNSET); - expect(await iexecPocoAsAnyone.callStatic.initialize(dealId, taskIndex)).to.equal( + expect(await iexecPocoAsAnyone.initialize.staticCall(dealId, taskIndex)).to.equal( taskId, ); const initialize = await iexecPocoAsAnyone.initialize(dealId, taskIndex); @@ -84,8 +83,8 @@ describe('IexecPoco2#initialize', async () => { expect(task.dealid).equal(dealId); expect(task.idx).equal(taskIndex); expect(task.timeref).equal(categoryTime); - expect(task.contributionDeadline).equal(startTime + 7 * categoryTime); - expect(task.finalDeadline).equal(startTime + 10 * categoryTime); + expect(task.contributionDeadline).equal(startTime + 7n * categoryTime); + expect(task.finalDeadline).equal(startTime + 10n * categoryTime); // m_consensus does not have any getter }); @@ -94,7 +93,7 @@ describe('IexecPoco2#initialize', async () => { assets: ordersAssets, requester: requester.address, prices: ordersPrices, - volume: 10, + volume: 10n, }).toObject(); const workerpoolOrder0 = { ...createEmptyWorkerpoolOrder(), @@ -163,12 +162,11 @@ describe('IexecPoco2#initialize', async () => { describe('Initialize array', function () { it('Should initialize array', async function () { - const volume = 3; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, prices: ordersPrices, - volume, + volume: 3n, }); const { dealId } = await iexecWrapper.signAndMatchOrders(...orders.toArray()); const dealIds = [dealId, dealId, dealId]; @@ -178,7 +176,7 @@ describe('IexecPoco2#initialize', async () => { expect((await iexecPoco.viewTask(taskId)).status).equal(TaskStatusEnum.UNSET); } - expect(await iexecPocoAsAnyone.callStatic.initializeArray(dealIds, taskIndexes)).to.be + expect(await iexecPocoAsAnyone.initializeArray.staticCall(dealIds, taskIndexes)).to.be .true; const initializeArrayTx = await iexecPocoAsAnyone.initializeArray(dealIds, taskIndexes); await initializeArrayTx.wait(); @@ -192,19 +190,18 @@ describe('IexecPoco2#initialize', async () => { }); it('Should not initialize array if incompatible length of inputs', async function () { - const dealId = ethers.utils.hashMessage('dealId'); + const dealId = ethers.hashMessage('dealId'); await expect( iexecPoco.initializeArray([dealId, dealId], [0]), ).to.be.revertedWithoutReason(); }); it('Should not initialize array if one specific fails', async function () { - const volume = 2; const orders = buildOrders({ assets: ordersAssets, requester: requester.address, prices: ordersPrices, - volume, + volume: 2n, }); const { dealId } = await iexecWrapper.signAndMatchOrders(...orders.toArray()); const taskIndex0 = 0; diff --git a/test/byContract/IexecPoco/IexecPoco2-reopen.test.ts b/test/byContract/IexecPoco/IexecPoco2-reopen.test.ts index 53681fad6..7aee3af1e 100644 --- a/test/byContract/IexecPoco/IexecPoco2-reopen.test.ts +++ b/test/byContract/IexecPoco/IexecPoco2-reopen.test.ts @@ -1,11 +1,11 @@ -// SPDX-FileCopyrightText: 2024 IEXEC BLOCKCHAIN TECH +// SPDX-FileCopyrightText: 2024-2025 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 -import { AddressZero, HashZero } from '@ethersproject/constants'; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { loadFixture, mine, time } from '@nomicfoundation/hardhat-network-helpers'; import { setNextBlockTimestamp } from '@nomicfoundation/hardhat-network-helpers/dist/src/helpers/time'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { expect } from 'chai'; +import { ZeroAddress, ZeroHash } from 'ethers'; import { IexecInterfaceNative, IexecInterfaceNative__factory } from '../../../typechain'; import { OrdersAssets, OrdersPrices, buildOrders } from '../../../utils/createOrders'; import { @@ -20,9 +20,9 @@ import { import { IexecWrapper } from '../../utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; -const appPrice = 1000; -const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const appPrice = 1000n; +const datasetPrice = 1_000_000n; +const workerpoolPrice = 1_000_000_000n; const resultDigest = buildUtf8ResultAndDigest('result').resultDigest; describe('IexecPoco2#reopen', async () => { @@ -43,7 +43,7 @@ describe('IexecPoco2#reopen', async () => { let ordersAssets: OrdersAssets; let ordersPrices: OrdersPrices; let [dealId, taskId]: string[] = []; - let taskIndex: number; + let taskIndex: bigint; beforeEach('Deploy', async () => { // Deploy all contracts @@ -125,7 +125,7 @@ describe('IexecPoco2#reopen', async () => { // No getter for m_consensus. const taskAfter = await iexecPoco.viewTask(taskId); expect(taskAfter.status).to.equal(TaskStatusEnum.ACTIVE); - expect(taskAfter.consensusValue).to.equal(HashZero); + expect(taskAfter.consensusValue).to.equal(ZeroHash); expect(taskAfter.revealCounter).to.equal(0); expect(taskAfter.winnerCounter).to.equal(0); }); @@ -242,11 +242,9 @@ describe('IexecPoco2#reopen', async () => { * @param resultDigest */ async function contribute(worker: SignerWithAddress, resultDigest: string) { - const emptyEnclaveAddress = AddressZero; + const emptyEnclaveAddress = ZeroAddress; const emptyEnclaveSignature = '0x'; - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); await iexecWrapper.depositInIexecAccount(worker, workerTaskStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, diff --git a/test/byContract/IexecPoco/IexecPoco2-reveal.test.ts b/test/byContract/IexecPoco/IexecPoco2-reveal.test.ts index dca3cbb30..b613d77ca 100644 --- a/test/byContract/IexecPoco/IexecPoco2-reveal.test.ts +++ b/test/byContract/IexecPoco/IexecPoco2-reveal.test.ts @@ -1,11 +1,10 @@ -// SPDX-FileCopyrightText: 2020-2024 IEXEC BLOCKCHAIN TECH +// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 -import { AddressZero, HashZero } from '@ethersproject/constants'; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { expect } from 'chai'; -import { ethers } from 'hardhat'; +import { ZeroAddress, ZeroHash, ethers } from 'ethers'; import { IexecInterfaceNative, IexecInterfaceNative__factory } from '../../../typechain'; import { NULL } from '../../../utils/constants'; import { IexecOrders, OrdersAssets, OrdersPrices, buildOrders } from '../../../utils/createOrders'; @@ -21,11 +20,11 @@ import { import { IexecWrapper } from '../../utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; -const volume = 1; -const standardDealTag = HashZero; +const volume = 1n; +const standardDealTag = ZeroHash; const { resultDigest } = buildUtf8ResultAndDigest('result'); const { resultDigest: badResultDigest } = buildUtf8ResultAndDigest('bad-result'); -const emptyEnclaveAddress = AddressZero; +const emptyEnclaveAddress = ZeroAddress; const emptyEnclaveSignature = NULL.SIGNATURE; describe('IexecPoco2#reveal', () => { @@ -46,7 +45,7 @@ describe('IexecPoco2#reveal', () => { let ordersPrices: OrdersPrices; let orders: IexecOrders; let [dealId, taskId]: string[] = []; - let taskIndex: number; + let taskIndex: bigint; let [resultHash, resultSeal]: string[] = []; let schedulerSignature: string; @@ -62,9 +61,9 @@ describe('IexecPoco2#reveal', () => { const { appAddress, datasetAddress, workerpoolAddress } = await iexecWrapper.createAssets(); iexecPoco = IexecInterfaceNative__factory.connect(proxyAddress, anyone); iexecPocoAsWorker = iexecPoco.connect(worker); - const appPrice = 1000; - const datasetPrice = 1_000_000; - const workerpoolPrice = 1_000_000_000; + const appPrice = 1000n; + const datasetPrice = 1_000_000n; + const workerpoolPrice = 1_000_000_000n; ordersAssets = { app: appAddress, dataset: datasetAddress, @@ -87,9 +86,7 @@ describe('IexecPoco2#reveal', () => { ...orders.toArray(), )); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); await iexecWrapper.depositInIexecAccount(worker, workerTaskStake); ({ resultHash, resultSeal } = buildResultHashAndResultSeal(taskId, resultDigest, worker)); schedulerSignature = await buildAndSignContributionAuthorizationMessage( @@ -200,15 +197,13 @@ describe('IexecPoco2#reveal', () => { volume, trust: 3, tag: standardDealTag, - salt: ethers.utils.hexZeroPad('0x' + Date.now().toString(), 32), // make + salt: ethers.zeroPadValue(ethers.toBeHex(Date.now()), 32), // make }).toArray(), // app and dataset orders unique since already matched in // beforeEach. A useless salt is also added to workerpool and request // orders to get an easy one-liner declaration. ); await iexecPoco.initialize(dealId, taskIndex).then((tx) => tx.wait()); - const workerTaskStake = await iexecPoco - .viewDeal(dealId) - .then((deal) => deal.workerStake.toNumber()); + const workerTaskStake = await iexecPoco.viewDeal(dealId).then((deal) => deal.workerStake); const workers = [ { signer: worker1, resultDigest: resultDigest }, { signer: worker2, resultDigest: badResultDigest }, diff --git a/test/utils/IexecWrapper.ts b/test/utils/IexecWrapper.ts index 0ee9011a0..998f1d4f6 100644 --- a/test/utils/IexecWrapper.ts +++ b/test/utils/IexecWrapper.ts @@ -121,14 +121,12 @@ export class IexecWrapper { * @param volume number of tasks of a deal * @returns total amount to stake by the scheduler */ - async computeSchedulerDealStake(workerpoolPrice: number, volume: number): Promise { - const stakeRatio = Number( - await IexecAccessors__factory.connect( - this.proxyAddress, - this.accounts.anyone, - ).workerpool_stake_ratio(), - ); - return Math.floor((workerpoolPrice * stakeRatio) / 100) * volume; + async computeSchedulerDealStake(workerpoolPrice: bigint, volume: bigint): Promise { + const stakeRatio = await IexecAccessors__factory.connect( + this.proxyAddress, + this.accounts.anyone, + ).workerpool_stake_ratio(); + return ((workerpoolPrice * stakeRatio) / 100n) * volume; } /** @@ -138,15 +136,13 @@ export class IexecWrapper { * @param workerpoolPrice price of the workerpool * @returns value of worker stake */ - async computeWorkerTaskStake(workerpoolAddress: string, workerpoolPrice: number) { + async computeWorkerTaskStake(workerpoolAddress: string, workerpoolPrice: bigint) { // TODO make "m_workerStakeRatioPolicy()" as view function in IWorkerpool.v8 and use it. - const workerStakeRatio = Number( - await Workerpool__factory.connect( - workerpoolAddress, - this.accounts.anyone, - ).m_workerStakeRatioPolicy(), - ); - return Math.floor((workerpoolPrice * workerStakeRatio) / 100); + const workerStakeRatio = await Workerpool__factory.connect( + workerpoolAddress, + this.accounts.anyone, + ).m_workerStakeRatioPolicy(); + return (workerpoolPrice * workerStakeRatio) / 100n; } /** @@ -172,14 +168,12 @@ export class IexecWrapper { */ async computeWorkersRewardPerTask(dealId: string, mode: PocoMode) { if (mode === PocoMode.BOOST) { - return Number( - ( - await IexecPocoBoostAccessors__factory.connect( - this.proxyAddress, - ethers.provider, - ).viewDealBoost(dealId) - ).workerReward, - ); + return ( + await IexecPocoBoostAccessors__factory.connect( + this.proxyAddress, + ethers.provider, + ).viewDealBoost(dealId) + ).workerReward; } // CLASSIC mode. const deal = await IexecAccessors__factory.connect( @@ -187,8 +181,8 @@ export class IexecWrapper { ethers.provider, ).viewDeal(dealId); // reward = (workerpoolPrice * workersRatio) / 100 - const workersRewardRatio = 100 - Number(deal.schedulerRewardRatio); - return Math.floor((Number(deal.workerpool.price) * workersRewardRatio) / 100); + const workersRewardRatio = 100n - deal.schedulerRewardRatio; + return (deal.workerpool.price * workersRewardRatio) / 100n; } async setTeeBroker(brokerAddress: string) { @@ -271,27 +265,25 @@ export class IexecWrapper { this.proxyAddress, ethers.provider, ).viewConsumed(this.hashOrder(requestOrder)); - const dealId = getDealId(this.domain, requestOrder, Number(taskIndex)); - const taskId = getTaskId(dealId, Number(taskIndex)); - const volume = Number( - await IexecPocoAccessors__factory.connect( - this.proxyAddress, - ethers.provider, - ).computeDealVolume(appOrder, datasetOrder, workerpoolOrder, requestOrder), - ); + const dealId = getDealId(this.domain, requestOrder, taskIndex); + const taskId = getTaskId(dealId, taskIndex); + const volume = await IexecPocoAccessors__factory.connect( + this.proxyAddress, + ethers.provider, + ).computeDealVolume(appOrder, datasetOrder, workerpoolOrder, requestOrder); const taskPrice = - Number(appOrder.appprice) + - Number(datasetOrder.datasetprice) + - Number(workerpoolOrder.workerpoolprice); + BigInt(appOrder.appprice) + + BigInt(datasetOrder.datasetprice) + + BigInt(workerpoolOrder.workerpoolprice); const dealPrice = taskPrice * volume; const dealPayer = withSponsor ? this.accounts.sponsor : this.accounts.requester; await this.depositInIexecAccount(dealPayer, dealPrice); const schedulerStakePerDeal = await this.computeSchedulerDealStake( - Number(workerpoolOrder.workerpoolprice), + BigInt(workerpoolOrder.workerpoolprice), volume, ); await this.depositInIexecAccount(this.accounts.scheduler, schedulerStakePerDeal); - const startTime = await setNextBlockTimestamp(); + const startTime = BigInt(await setNextBlockTimestamp()); const iexecPocoAsDealPayer = IexecPoco1__factory.connect(this.proxyAddress, dealPayer); await ( withSponsor @@ -351,7 +343,7 @@ export class IexecWrapper { * @param taskIndex index of the task * @returns */ - async initializeTask(dealId: string, taskIndex: number) { + async initializeTask(dealId: string, taskIndex: bigint) { await IexecPoco2__factory.connect(this.proxyAddress, this.accounts.anyone) .initialize(dealId, taskIndex) .then((tx) => tx.wait()); @@ -370,7 +362,7 @@ export class IexecWrapper { */ async contributeToTask( dealId: string, - taskIndex: number, + taskIndex: bigint, resultDigest: string, contributor: SignerWithAddress, ) { @@ -396,7 +388,7 @@ export class IexecWrapper { */ async contributeToTeeTask( dealId: string, - taskIndex: number, + taskIndex: bigint, resultDigest: string, contributor: SignerWithAddress, ) { @@ -423,7 +415,7 @@ export class IexecWrapper { */ async _contributeToTask( dealId: string, - taskIndex: number, + taskIndex: bigint, resultDigest: string, contributor: SignerWithAddress, useEnclave: Boolean, @@ -434,7 +426,7 @@ export class IexecWrapper { ethers.provider, ) .viewDeal(dealId) - .then((deal) => Number(deal.workerStake)); + .then((deal) => deal.workerStake); const { resultHash, resultSeal } = buildResultHashAndResultSeal( taskId, resultDigest, @@ -486,33 +478,30 @@ export class IexecWrapper { for (const account of accounts) { initialFrozens.push({ address: account.address, - frozen: Number(await iexecPoco.frozenOf(account.address)), + frozen: await iexecPoco.frozenOf(account.address), }); } return initialFrozens; } async checkFrozenChanges( - accountsInitialFrozens: { address: string; frozen: number }[], - expectedFrozenChanges: number[], + accountsInitialFrozens: { address: string; frozen: bigint }[], + expectedFrozenChanges: bigint[], ) { let iexecPoco = IexecInterfaceNative__factory.connect(this.proxyAddress, ethers.provider); for (let i = 0; i < accountsInitialFrozens.length; i++) { - const actualFrozen = Number( - await iexecPoco.frozenOf(accountsInitialFrozens[i].address), - ); - + const actualFrozen = await iexecPoco.frozenOf(accountsInitialFrozens[i].address); const expectedFrozen = accountsInitialFrozens[i].frozen + expectedFrozenChanges[i]; expect(actualFrozen).to.equal(expectedFrozen, `Mismatch at index ${i}`); } } - async computeWorkersRewardForCurrentTask(totalPoolReward: number, dealId: string) { + async computeWorkersRewardForCurrentTask(totalPoolReward: bigint, dealId: string) { const deal = await IexecInterfaceNative__factory.connect( this.proxyAddress, ethers.provider, ).viewDeal(dealId); - return (totalPoolReward * (100 - Number(deal.schedulerRewardRatio))) / 100; + return (totalPoolReward * (100n - deal.schedulerRewardRatio)) / 100n; } } diff --git a/utils/createOrders.ts b/utils/createOrders.ts index a165cc097..7356e1aca 100644 --- a/utils/createOrders.ts +++ b/utils/createOrders.ts @@ -15,9 +15,9 @@ export interface OrdersAssets { } export interface OrdersPrices { - app?: number; - dataset?: number; - workerpool?: number; + app?: bigint; + dataset?: bigint; + workerpool?: bigint; } export interface MatchOrdersArgs { @@ -26,7 +26,7 @@ export interface MatchOrdersArgs { beneficiary?: string; tag?: string; prices?: OrdersPrices; - volume?: number; + volume?: bigint; callback?: string; trust?: number; category?: number; diff --git a/utils/poco-tools.ts b/utils/poco-tools.ts index 497319057..e24c1fbc7 100644 --- a/utils/poco-tools.ts +++ b/utils/poco-tools.ts @@ -83,7 +83,7 @@ export async function getIexecAccounts(): Promise { export function getDealId( domain: TypedDataDomain, requestOrder: IexecLibOrders_v5.RequestOrderStruct, - firstTaskIndex: number = 0, + firstTaskIndex: bigint = 0n, ): string { return ethers.solidityPackedKeccak256( ['bytes32', 'uint256'], @@ -91,7 +91,7 @@ export function getDealId( ); } -export function getTaskId(dealId: string, taskIndex: number): string { +export function getTaskId(dealId: string, taskIndex: bigint): string { return ethers.solidityPackedKeccak256(['bytes32', 'uint256'], [dealId, taskIndex]); } diff --git a/utils/tools.ts b/utils/tools.ts index d0555c1b1..937ccced6 100644 --- a/utils/tools.ts +++ b/utils/tools.ts @@ -1,19 +1,21 @@ // SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 -import type { BigNumber } from 'ethers'; +import { Signature } from 'ethers'; import { ethers } from 'hardhat'; export function compactSignature(signature: string): string { - const split = ethers.utils.splitSignature(signature); - let vs = ethers.utils.arrayify(split.s); - if (split.v == 1 || split.v == 28) { - vs[0] |= 0x80; - } - return ethers.utils.hexlify(ethers.utils.concat([split.r, vs])); + return Signature.from(signature).compactSerialized; } -export function BN2Address(bignumber: BigNumber) { - const lowercaseAddress = ethers.utils.hexZeroPad(bignumber.toHexString(), 20); - return ethers.utils.getAddress(lowercaseAddress); +export function bigintToAddress(bigint: bigint) { + return ethers.getAddress(ethers.toBeHex(bigint)); +} + +export function minBigInt(a: bigint, b: bigint) { + return a < b ? a : b; +} + +export function maxBigInt(a: bigint, b: bigint) { + return a > b ? a : b; }