Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion test/000_fullchain-boost.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
} from '../utils/poco-tools';
import { IexecWrapper } from './utils/IexecWrapper';
import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer';
import { randomAddress } from './utils/utils';
import { expectProxyBalanceToEqualAllFrozen, randomAddress } from './utils/utils';

const taskIndex = 0n;
const volume = taskIndex + 1n;
Expand Down Expand Up @@ -109,6 +109,10 @@ describe('IexecPocoBoostFacet (IT)', function () {
await iexecWrapper.setTeeBroker('0x0000000000000000000000000000000000000000');
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({
Expand Down
6 changes: 5 additions & 1 deletion test/000_fullchain.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '../utils/poco-tools';
import { IexecWrapper } from './utils/IexecWrapper';
import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer';
import { randomAddress } from './utils/utils';
import { expectProxyBalanceToEqualAllFrozen, randomAddress } from './utils/utils';

// +---------+-------------+-------------+-------------+----------+-----+---------------------------------------------+
// | | Sponsorship | Replication | Beneficiary | Callback | BoT | Type |
Expand Down Expand Up @@ -67,6 +67,10 @@ describe('Integration tests', function () {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({
Expand Down
5 changes: 5 additions & 0 deletions test/200_fullchain-bot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { OrdersActors, OrdersAssets, OrdersPrices, buildOrders } from '../utils/
import { TaskStatusEnum, buildUtf8ResultAndDigest, getIexecAccounts } from '../utils/poco-tools';
import { IexecWrapper } from './utils/IexecWrapper';
import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer';
import { expectProxyBalanceToEqualAllFrozen } from './utils/utils';

const appPrice = 1000n;
const datasetPrice = 1_000_000n;
Expand Down Expand Up @@ -43,6 +44,10 @@ describe('Integration tests', function () {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({
Expand Down
5 changes: 5 additions & 0 deletions test/201_fullchain-multi-orders.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import { maxBigInt, minBigInt } from '../utils/tools';
import { IexecWrapper } from './utils/IexecWrapper';
import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer';
import { expectProxyBalanceToEqualAllFrozen } from './utils/utils';

const appPrice = 1000n;
const datasetPrice = 1_000_000n;
Expand All @@ -47,6 +48,10 @@ describe('Integration tests', function () {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({ requester, appProvider, datasetProvider, scheduler, anyone, worker1 } = accounts);
Expand Down
5 changes: 5 additions & 0 deletions test/300_fullchain-reopen.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ZeroAddress } from 'ethers';
import { IexecInterface, IexecInterface__factory } from '../typechain';
import { OrdersActors, OrdersAssets, OrdersPrices, buildOrders } from '../utils/createOrders';
import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer';
import { expectProxyBalanceToEqualAllFrozen } from './utils/utils';

import { TAG_STANDARD } from '../utils/constants';
import {
Expand Down Expand Up @@ -52,6 +53,10 @@ describe('Integration tests', function () {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({
Expand Down
6 changes: 5 additions & 1 deletion test/byContract/IexecERC20/IexecERC20.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { getIexecAccounts } from '../../../utils/poco-tools';
import { IexecWrapper } from '../../utils/IexecWrapper';
import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer';
import { setZeroAddressBalance } from '../../utils/utils';
import { expectProxyBalanceToEqualAllFrozen, setZeroAddressBalance } from '../../utils/utils';

const value = 100n;

Expand All @@ -33,6 +33,10 @@ describe('ERC20', async () => {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
// Setup current test accounts from some arbitrary iExec accounts
Expand Down
6 changes: 5 additions & 1 deletion test/byContract/IexecEscrow/IexecEscrow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ethers } from 'hardhat';
import { IexecInterface, IexecInterface__factory, RLC, RLC__factory } from '../../../typechain';
import { getIexecAccounts } from '../../../utils/poco-tools';
import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer';
import { setZeroAddressBalance } from '../../utils/utils';
import { expectProxyBalanceToEqualAllFrozen, setZeroAddressBalance } from '../../utils/utils';

const amount = ethers.parseUnits('100', 9);

Expand All @@ -24,6 +24,10 @@ describe('IexecEscrow', () => {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({
Expand Down
5 changes: 5 additions & 0 deletions test/byContract/IexecPoco/IexecPoco2-claim.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from '../../../utils/poco-tools';
import { IexecWrapper } from '../../utils/IexecWrapper';
import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer';
import { expectProxyBalanceToEqualAllFrozen } from '../../utils/utils';
import * as constants from './../../../utils/constants';

const categoryTime = 300n;
Expand Down Expand Up @@ -46,6 +47,10 @@ describe('IexecPoco2#claim', async () => {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({ iexecAdmin, requester, sponsor, scheduler, worker1, worker2, anyone } = accounts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
} from '../../../utils/poco-tools';
import { IexecWrapper } from '../../utils/IexecWrapper';
import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer';
import { expectProxyBalanceToEqualAllFrozen } from '../../utils/utils';

const appPrice = 1000n;
const datasetPrice = 1_000_000n;
Expand Down Expand Up @@ -60,6 +61,10 @@ describe('IexecPoco2#contributeAndFinalize', () => {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({ requester, appProvider, datasetProvider, scheduler, sms, enclave, worker, anyone } =
Expand Down
5 changes: 5 additions & 0 deletions test/byContract/IexecPoco/IexecPoco2-finalize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
import { getPocoStorageSlotLocation } from '../../../utils/proxy-tools';
import { IexecWrapper } from '../../utils/IexecWrapper';
import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer';
import { expectProxyBalanceToEqualAllFrozen } from '../../utils/utils';

const { results, resultDigest } = buildUtf8ResultAndDigest('result');
const hexResults = ethers.hexlify(results);
Expand Down Expand Up @@ -63,6 +64,10 @@ describe('IexecPoco2#finalize', async () => {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({
Expand Down
6 changes: 5 additions & 1 deletion test/byContract/IexecPocoBoost/IexecPocoBoost.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ import {
} from '../../../utils/poco-tools';
import { IexecWrapper } from '../../utils/IexecWrapper';
import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer';
import { randomAddress } from '../../utils/utils';
import { expectProxyBalanceToEqualAllFrozen, randomAddress } from '../../utils/utils';

const taskIndex = 0n;
const volume = taskIndex + 1n;
Expand Down Expand Up @@ -108,6 +108,10 @@ describe('IexecPocoBoost', function () {
await loadFixture(initFixture);
});

afterEach('Check escrow invariant', async () => {
await expectProxyBalanceToEqualAllFrozen(proxyAddress);
});

async function initFixture() {
const accounts = await getIexecAccounts();
({
Expand Down
31 changes: 30 additions & 1 deletion test/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { expect } from 'chai';
import { ZeroAddress } from 'ethers';
import { ethers } from 'hardhat';
import { IexecLibOrders_v5 } from '../../typechain';
import { IexecInterface__factory, IexecLibOrders_v5 } from '../../typechain';

export async function hashDomain(domain: IexecLibOrders_v5.EIP712DomainStructOutput) {
return ethers.TypedDataEncoder.hashDomain({
Expand Down Expand Up @@ -30,3 +31,31 @@ export async function setZeroAddressBalance() {
export function randomAddress() {
return ethers.Wallet.createRandom().address;
}

/**
* Assert the escrow invariant: the sRLC held by the proxy is exactly the sum of
* every account's frozen sRLC.
*
* `EscrowLib.seize` and `EscrowLib.rewardAndLock` are the only escrow operations
* that write `m_frozens` without an sRLC transfer, so they preserve this
* invariant only when they are paired on the same value. Per-account balance and
* frozen deltas cannot detect such a mismatch: a seize without its
* `rewardAndLock` leaves the proxy holding sRLC no account can claim, and the
* opposite leaves frozen values that a later unlock cannot transfer.
*
* The invariant assumes no account sRLC-transfers to the proxy outside of the
* escrow (`transfer(proxyAddress, ...)` or `depositFor(proxyAddress, ...)`),
* which no production code path does.
*/
export async function expectProxyBalanceToEqualAllFrozen(proxyAddress: string) {
const iexecPoco = IexecInterface__factory.connect(proxyAddress, ethers.provider);
const accounts = [
proxyAddress, // The proxy itself never freezes, but a non null value would break the sum.
await iexecPoco.kitty_address(),
...(await ethers.getSigners()).map((signer) => signer.address),
];
const totalFrozen = await Promise.all(
accounts.map((account) => iexecPoco.frozenOf(account)),
).then((frozens) => frozens.reduce((total, frozen) => total + frozen, 0n));
expect(await iexecPoco.balanceOf(proxyAddress)).to.equal(totalFrozen);
}
Loading