From a487bdf87b09d3016c9251f4b403cf886380790a Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Tue, 8 Oct 2024 12:41:16 +0200 Subject: [PATCH 01/17] migrate escrow token test file --- ...scrowToken.js => IexecEscrowToken.js.skip} | 0 .../IexecEscrow/IexecEscrowToken.test.ts | 347 ++++++++++++++++++ 2 files changed, 347 insertions(+) rename test/byContract/IexecEscrow/{IexecEscrowToken.js => IexecEscrowToken.js.skip} (100%) create mode 100644 test/byContract/IexecEscrow/IexecEscrowToken.test.ts diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.js b/test/byContract/IexecEscrow/IexecEscrowToken.js.skip similarity index 100% rename from test/byContract/IexecEscrow/IexecEscrowToken.js rename to test/byContract/IexecEscrow/IexecEscrowToken.js.skip diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts new file mode 100644 index 000000000..a0d1a86eb --- /dev/null +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -0,0 +1,347 @@ +// SPDX-FileCopyrightText: 2020-2024 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +import { AddressZero } from '@ethersproject/constants'; +import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { BigNumber } from 'ethers'; +import { ethers, expect } from 'hardhat'; +import { loadHardhatFixtureDeployment } from '../../../scripts/hardhat-fixture-deployer'; +import { + IexecInterfaceToken, + IexecInterfaceToken__factory, + RLC, + RLC__factory, +} from '../../../typechain'; +import { getIexecAccounts } from '../../../utils/poco-tools'; + +const depositAmount = AmountWithDecimals(BigNumber.from(100)); +const depositArgs = [depositAmount] as [BigNumber]; +const withdrawAmount = BigNumber.from(100); + +describe('IexecEscrowTokenDelegate', () => { + let proxyAddress: string; + let [iexecPoco, , iexecPocoAsAccountA, iexecPocoAsAdmin]: IexecInterfaceToken[] = []; + let [iexecAdmin, accountA, accountB, anyone]: SignerWithAddress[] = []; + let [rlcInstance, rlcInstanceAsAccountA]: RLC[] = []; + + beforeEach('Deploy', async () => { + proxyAddress = await loadHardhatFixtureDeployment(); + await loadFixture(initFixture); + }); + + async function initFixture() { + const accounts = await getIexecAccounts(); + ({ iexecAdmin, anyone: accountA, requester: accountB, anyone } = accounts); + + iexecPoco = IexecInterfaceToken__factory.connect(proxyAddress, anyone); + iexecPocoAsAccountA = iexecPoco.connect(accountA); + iexecPocoAsAdmin = iexecPoco.connect(iexecAdmin); + rlcInstance = await RLC__factory.connect(await iexecPoco.token(), anyone); + rlcInstanceAsAccountA = rlcInstance.connect(accountA); + await rlcInstance + .connect(iexecAdmin) + .transfer(accountA.address, AmountWithDecimals(BigNumber.from(10_000))) + .then((tx) => tx.wait()); + } + + describe('Receive and Fallback', () => { + it('Should revert on receive', async () => { + await expect( + accountA.sendTransaction({ + to: iexecPoco.address, + value: depositAmount, + }), + ).to.be.revertedWith('fallback-disabled'); + }); + it('Should revert on fallback', async () => { + const randomData = ethers.utils.hexlify( + ethers.utils.toUtf8Bytes((Math.random() * 0xfffff).toString(16)), + ); + await expect( + accountA.sendTransaction({ + to: iexecPoco.address, + value: depositAmount, + data: randomData, + }), + ).to.be.revertedWith('fallback-disabled'); + }); + }); + + describe('Deposit', () => { + it('Should deposit tokens', async () => { + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositAmount) + .then((tx) => tx.wait()); + + expect(await iexecPocoAsAccountA.callStatic.deposit(...depositArgs)).to.be.true; + await expect(iexecPocoAsAccountA.deposit(...depositArgs)) + .to.changeTokenBalances( + rlcInstance, + [accountA, iexecPoco], + [-depositAmount, depositAmount], + ) + .to.emit(iexecPoco, 'Transfer') + .withArgs(AddressZero, accountA.address, depositAmount); + }); + it('Should deposit 0 token', async () => { + expect(await iexecPocoAsAccountA.callStatic.deposit(0)).to.be.true; + await expect(iexecPocoAsAccountA.deposit(0)) + .to.changeTokenBalances(rlcInstance, [accountA, iexecPoco], [-0, 0]) + .to.emit(iexecPoco, 'Transfer') + .withArgs(AddressZero, accountA.address, 0); + }); + // it('Should not deposit tokens when caller is address 0', async () => { + // const AddressZeroSigner = await ethers.getSigner(AddressZero); + // await rlcInstance.connect(iexecAdmin).transfer(AddressZeroSigner.address,AmountWithDecimals(BigNumber.from(100))).then((tx) => tx.wait()); + // const rlcInstanceAsAddress0 = rlcInstance.connect(AddressZeroSigner); + // // await rlcInstanceAsAddress0.approve(iexecPoco.address, depositAmount).then((tx) => tx.wait()); + // const iexecPocoAsAddress0 = iexecPoco.connect(AddressZeroSigner); + + // await expect(iexecPocoAsAddress0.deposit(...depositArgs)) + // .to.be.revertedWith('ERC20: mint to the zero address'); + + // }); + }); + + describe('Deposit for', () => { + it('Should deposit tokens for another account', async () => { + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositAmount) + .then((tx) => tx.wait()); + expect( + await iexecPocoAsAccountA.callStatic.depositFor(...depositArgs, accountB.address), + ).to.be.true; + await expect(iexecPocoAsAccountA.depositFor(...depositArgs, accountB.address)) + .to.changeTokenBalances( + rlcInstance, + [accountA, iexecPoco], + [-depositAmount, depositAmount], + ) + .to.emit(iexecPoco, 'Transfer') + .withArgs(AddressZero, accountB.address, depositAmount); + }); + it('Should not deposit tokens for zero address', async () => { + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositAmount) + .then((tx) => tx.wait()); + await expect( + iexecPocoAsAccountA.depositFor(depositAmount, AddressZero), + ).to.be.revertedWith('ERC20: mint to the zero address'); + }); + }); + + describe('Deposit for array', () => { + it('Should deposit tokens for multiple accounts', async () => { + const depositAmounts = [depositAmount, depositAmount.mul(2)]; + const accounts = [iexecAdmin.address, accountB.address]; + + const depositTotalAmount = getTotalAmount(depositAmounts); + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositTotalAmount) + .then((tx) => tx.wait()); + + expect(await iexecPocoAsAccountA.callStatic.depositForArray(depositAmounts, accounts)) + .to.be.true; + await expect(iexecPocoAsAccountA.depositForArray(depositAmounts, accounts)) + .to.changeTokenBalances( + rlcInstance, + [accountA, iexecPoco], + [-depositTotalAmount, depositTotalAmount], + ) + .to.emit(iexecPoco, 'Transfer') + .withArgs(AddressZero, iexecAdmin.address, depositAmount) + .to.emit(iexecPoco, 'Transfer') + .withArgs(AddressZero, accountB.address, depositAmount.mul(2)); + }); + it('Should not depositForArray with mismatched array lengths', async () => { + const depositAmounts = [depositAmount.mul(2), depositAmount, depositAmount.div(2)]; + const depositTotalAmount = getTotalAmount(depositAmounts); + + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositTotalAmount) + .then((tx) => tx.wait()); + const targets = [iexecAdmin.address, accountB.address]; + await expect( + iexecPocoAsAccountA.depositForArray(depositAmounts, targets), + ).to.be.revertedWith('invalid-array-length'); + }); + it('Should not depositForArray with address zero in target', async () => { + const depositAmounts = [depositAmount, depositAmount.mul(2)]; + + const depositTotalAmount = getTotalAmount(depositAmounts); + + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositTotalAmount) + .then((tx) => tx.wait()); + const targets = [AddressZero, accountB.address]; + await expect( + iexecPocoAsAccountA.depositForArray(depositAmounts, targets), + ).to.be.revertedWith('ERC20: mint to the zero address'); + }); + }); + + describe('Withdraw', () => { + it('Should withdraw tokens', async () => { + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositAmount) + .then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(depositAmount).then((tx) => tx.wait()); + + expect(await iexecPocoAsAccountA.callStatic.withdraw(withdrawAmount)).to.be.true; + await expect(iexecPocoAsAccountA.withdraw(withdrawAmount)) + .to.changeTokenBalances( + rlcInstance, + [iexecPoco, accountA], + [-withdrawAmount, withdrawAmount], + ) + .to.emit(iexecPoco, 'Transfer') + .withArgs(accountA.address, AddressZero, withdrawAmount); + }); + it('Should withdraw zero token', async () => { + expect(await iexecPocoAsAccountA.callStatic.withdraw(0)).to.be.true; + await expect(iexecPocoAsAccountA.withdraw(0)) + .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-0, 0]) + .to.emit(iexecPoco, 'Transfer') + .withArgs(accountA.address, AddressZero, 0); + }); + it('Should not withdraw native tokens with empty balance', async () => { + await expect( + iexecPocoAsAccountA.withdraw(withdrawAmount), + ).to.be.revertedWithoutReason(); + }); + it('Should not withdraw tokens with insufficient balance', async () => { + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositAmount) + .then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(depositAmount).then((tx) => tx.wait()); + + await expect( + iexecPocoAsAccountA.withdraw(depositAmount.mul(2)), + ).to.be.revertedWithoutReason(); + }); + }); + + describe('Withdraw to', () => { + it('Should withdraw another address', async () => { + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositAmount) + .then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(depositAmount).then((tx) => tx.wait()); + + expect( + await iexecPocoAsAccountA.callStatic.withdrawTo(withdrawAmount, accountB.address), + ).to.be.true; + await expect(iexecPocoAsAccountA.withdrawTo(withdrawAmount, accountB.address)) + .to.changeTokenBalances( + rlcInstance, + [iexecPoco, accountB], + [-withdrawAmount, withdrawAmount], + ) + .to.emit(iexecPoco, 'Transfer') + .withArgs(accountA.address, AddressZero, withdrawAmount); + }); + it('Should withdraw To with zero token', async () => { + expect(await iexecPocoAsAccountA.callStatic.withdrawTo(0, accountB.address)).to.be.true; + await expect(iexecPocoAsAccountA.withdrawTo(0, accountB.address)) + .to.changeTokenBalances(rlcInstance, [iexecPoco, accountB], [-0, 0]) + .to.emit(iexecPoco, 'Transfer') + .withArgs(accountA.address, AddressZero, 0); + }); + it('Should not withdraw To tokens with empty balance', async () => { + await expect( + iexecPocoAsAccountA.withdrawTo(withdrawAmount, accountB.address), + ).to.be.revertedWithoutReason(); + }); + it('Should not withdraw To tokens with insufficient balance', async () => { + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositAmount) + .then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(depositAmount).then((tx) => tx.wait()); + + await expect( + iexecPocoAsAccountA.withdrawTo(depositAmount.mul(2), accountB.address), + ).to.be.revertedWithoutReason(); + }); + }); + + describe('Recover', () => { + it('Should recover from balance deviation', async () => { + await rlcInstance.connect(iexecAdmin).transfer(proxyAddress, depositAmount); // Simulate deviation + + const initTotalSupply = await iexecPoco.totalSupply(); + const expectedDelta = depositAmount; + + await expect(iexecPocoAsAdmin.recover()) + .to.emit(iexecPoco, 'Transfer') + .withArgs(AddressZero, iexecAdmin.address, expectedDelta); + + expect(await iexecPoco.totalSupply()).to.equal(initTotalSupply.add(expectedDelta)); + }); + it('Should recover 0 token when balance matches total supply', async () => { + const initialSupply = await iexecPoco.totalSupply(); + + await expect(iexecPocoAsAdmin.recover()) + .to.emit(iexecPoco, 'Transfer') + .withArgs(AddressZero, iexecAdmin.address, 0); + expect(await iexecPoco.totalSupply()).to.equal(initialSupply); + }); + it('Should not allow non-owner to recover', async () => { + await expect(iexecPocoAsAccountA.recover()).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); + }); + }); + + describe('receiveApproval', () => { + it('Should receiveApproval', async () => { + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositAmount) + .then((tx) => tx.wait()); + expect( + await iexecPocoAsAccountA.callStatic.receiveApproval( + accountA.address, + depositAmount, + rlcInstance.address, + '0x', + ), + ).to.be.true; + await expect( + iexecPocoAsAccountA.receiveApproval( + accountA.address, + depositAmount, + rlcInstance.address, + '0x', + ), + ) + .to.changeTokenBalances( + rlcInstance, + [accountA, iexecPoco], + [-depositAmount, depositAmount], + ) + .to.emit(iexecPoco, 'Transfer') + .withArgs(AddressZero, accountA.address, depositAmount); + }); + + it('Should not receiveApproval when the wrong token is used', async () => { + await rlcInstanceAsAccountA + .approve(iexecPoco.address, depositAmount) + .then((tx) => tx.wait()); + await expect( + iexecPocoAsAccountA.receiveApproval( + accountA.address, + depositAmount, + ethers.Wallet.createRandom().address, + '0x', + ), + ).to.be.revertedWith('wrong-token'); + }); + }); +}); + +function AmountWithDecimals(depositAmount: BigNumber) { + return ethers.utils.parseUnits(depositAmount.toString(), 9); +} +function getTotalAmount(amounts: BigNumber[]) { + return amounts.reduce((a, b) => a.add(b), BigNumber.from(0)); +} From dbcef733e0c7968cfbb9f563da676d66d53dc3ad Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Tue, 8 Oct 2024 15:58:26 +0200 Subject: [PATCH 02/17] continue migration --- .../IexecEscrow/IexecEscrowToken.test.ts | 306 ++++++++++++------ 1 file changed, 208 insertions(+), 98 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index a0d1a86eb..a3bbf9fcf 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2020-2024 IEXEC BLOCKCHAIN TECH +// SPDX-FileCopyrightText: 2024 IEXEC BLOCKCHAIN TECH // SPDX-License-Identifier: Apache-2.0 import { AddressZero } from '@ethersproject/constants'; @@ -15,9 +15,15 @@ import { } from '../../../typechain'; import { getIexecAccounts } from '../../../utils/poco-tools'; -const depositAmount = AmountWithDecimals(BigNumber.from(100)); -const depositArgs = [depositAmount] as [BigNumber]; -const withdrawAmount = BigNumber.from(100); +const standardAmount = AmountWithDecimals(BigNumber.from(100)); +const depositParams = { + amount: standardAmount, +}; +const depositArgs = Object.values(depositParams) as [BigNumber]; +const withdrawParams = { + amount: standardAmount, +}; +const withdrawArgs = Object.values(withdrawParams) as [BigNumber]; describe('IexecEscrowTokenDelegate', () => { let proxyAddress: string; @@ -50,7 +56,7 @@ describe('IexecEscrowTokenDelegate', () => { await expect( accountA.sendTransaction({ to: iexecPoco.address, - value: depositAmount, + value: standardAmount, }), ).to.be.revertedWith('fallback-disabled'); }); @@ -61,7 +67,7 @@ describe('IexecEscrowTokenDelegate', () => { await expect( accountA.sendTransaction({ to: iexecPoco.address, - value: depositAmount, + value: standardAmount, data: randomData, }), ).to.be.revertedWith('fallback-disabled'); @@ -71,7 +77,7 @@ describe('IexecEscrowTokenDelegate', () => { describe('Deposit', () => { it('Should deposit tokens', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositAmount) + .approve(iexecPoco.address, depositParams.amount) .then((tx) => tx.wait()); expect(await iexecPocoAsAccountA.callStatic.deposit(...depositArgs)).to.be.true; @@ -79,10 +85,10 @@ describe('IexecEscrowTokenDelegate', () => { .to.changeTokenBalances( rlcInstance, [accountA, iexecPoco], - [-depositAmount, depositAmount], + [-depositParams.amount, depositParams.amount], ) .to.emit(iexecPoco, 'Transfer') - .withArgs(AddressZero, accountA.address, depositAmount); + .withArgs(AddressZero, accountA.address, depositParams.amount); }); it('Should deposit 0 token', async () => { expect(await iexecPocoAsAccountA.callStatic.deposit(0)).to.be.true; @@ -91,92 +97,141 @@ describe('IexecEscrowTokenDelegate', () => { .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, accountA.address, 0); }); - // it('Should not deposit tokens when caller is address 0', async () => { - // const AddressZeroSigner = await ethers.getSigner(AddressZero); - // await rlcInstance.connect(iexecAdmin).transfer(AddressZeroSigner.address,AmountWithDecimals(BigNumber.from(100))).then((tx) => tx.wait()); - // const rlcInstanceAsAddress0 = rlcInstance.connect(AddressZeroSigner); - // // await rlcInstanceAsAddress0.approve(iexecPoco.address, depositAmount).then((tx) => tx.wait()); - // const iexecPocoAsAddress0 = iexecPoco.connect(AddressZeroSigner); + it('Should not deposit tokens when caller is address 0', async () => { + const AddressZeroSigner = await ethers.getImpersonatedSigner(AddressZero); + await rlcInstance + .connect(iexecAdmin) + .transfer(AddressZeroSigner.address, standardAmount) + .then((tx) => tx.wait()); + // send some gas token + iexecAdmin + .sendTransaction({ + to: AddressZeroSigner.address, + value: AmountWithDecimals(BigNumber.from(100_000)), + }) + .then((tx) => tx.wait()); - // await expect(iexecPocoAsAddress0.deposit(...depositArgs)) - // .to.be.revertedWith('ERC20: mint to the zero address'); + const rlcInstanceAsAddress0 = rlcInstance.connect(AddressZeroSigner); + await rlcInstanceAsAddress0 + .approve(iexecPoco.address, depositParams.amount) + .then((tx) => tx.wait()); - // }); + const iexecPocoAsAddress0 = iexecPoco.connect(AddressZeroSigner); + await expect(iexecPocoAsAddress0.deposit(...depositArgs)).to.be.revertedWith( + 'ERC20: mint to the zero address', + ); + }); }); describe('Deposit for', () => { it('Should deposit tokens for another account', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositAmount) + .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - expect( - await iexecPocoAsAccountA.callStatic.depositFor(...depositArgs, accountB.address), - ).to.be.true; - await expect(iexecPocoAsAccountA.depositFor(...depositArgs, accountB.address)) + + const depositForParams = { + amount: standardAmount, + target: accountB.address, + }; + const depositForArgs = Object.values(depositForParams) as [BigNumber, string]; + + expect(await iexecPocoAsAccountA.callStatic.depositFor(...depositForArgs)).to.be.true; + await expect(iexecPocoAsAccountA.depositFor(...depositForArgs)) .to.changeTokenBalances( rlcInstance, [accountA, iexecPoco], - [-depositAmount, depositAmount], + [-depositForParams.amount, depositForParams.amount], ) .to.emit(iexecPoco, 'Transfer') - .withArgs(AddressZero, accountB.address, depositAmount); + .withArgs(AddressZero, depositForParams.target, depositForParams.amount); }); it('Should not deposit tokens for zero address', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositAmount) + .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - await expect( - iexecPocoAsAccountA.depositFor(depositAmount, AddressZero), - ).to.be.revertedWith('ERC20: mint to the zero address'); + + const depositForParams = { + amount: standardAmount, + target: AddressZero, + }; + const depositForArgs = Object.values(depositForParams) as [BigNumber, string]; + await expect(iexecPocoAsAccountA.depositFor(...depositForArgs)).to.be.revertedWith( + 'ERC20: mint to the zero address', + ); }); }); describe('Deposit for array', () => { it('Should deposit tokens for multiple accounts', async () => { - const depositAmounts = [depositAmount, depositAmount.mul(2)]; - const accounts = [iexecAdmin.address, accountB.address]; + const depositForArrayParams = { + amounts: [standardAmount, standardAmount.mul(2)], + targets: [iexecAdmin.address, accountB.address], + }; + const depositForArrayArgs = Object.values(depositForArrayParams) as [ + BigNumber[], + string[], + ]; + const depositTotalAmount = getTotalAmount(depositForArrayParams.amounts); - const depositTotalAmount = getTotalAmount(depositAmounts); await rlcInstanceAsAccountA .approve(iexecPoco.address, depositTotalAmount) .then((tx) => tx.wait()); - - expect(await iexecPocoAsAccountA.callStatic.depositForArray(depositAmounts, accounts)) - .to.be.true; - await expect(iexecPocoAsAccountA.depositForArray(depositAmounts, accounts)) + expect(await iexecPocoAsAccountA.callStatic.depositForArray(...depositForArrayArgs)).to + .be.true; + await expect(iexecPocoAsAccountA.depositForArray(...depositForArrayArgs)) .to.changeTokenBalances( rlcInstance, [accountA, iexecPoco], [-depositTotalAmount, depositTotalAmount], ) .to.emit(iexecPoco, 'Transfer') - .withArgs(AddressZero, iexecAdmin.address, depositAmount) + .withArgs( + AddressZero, + depositForArrayParams.targets[0], + depositForArrayParams.amounts[0], + ) .to.emit(iexecPoco, 'Transfer') - .withArgs(AddressZero, accountB.address, depositAmount.mul(2)); + .withArgs( + AddressZero, + depositForArrayParams.targets[1], + depositForArrayParams.amounts[1], + ); }); it('Should not depositForArray with mismatched array lengths', async () => { - const depositAmounts = [depositAmount.mul(2), depositAmount, depositAmount.div(2)]; - const depositTotalAmount = getTotalAmount(depositAmounts); + const depositForArrayParams = { + amounts: [standardAmount.mul(2), standardAmount, standardAmount.div(2)], + targets: [iexecAdmin.address, accountB.address], + }; + const depositForArrayArgs = Object.values(depositForArrayParams) as [ + BigNumber[], + string[], + ]; + const depositTotalAmount = getTotalAmount(depositForArrayParams.amounts); await rlcInstanceAsAccountA .approve(iexecPoco.address, depositTotalAmount) .then((tx) => tx.wait()); const targets = [iexecAdmin.address, accountB.address]; await expect( - iexecPocoAsAccountA.depositForArray(depositAmounts, targets), + iexecPocoAsAccountA.depositForArray(...depositForArrayArgs), ).to.be.revertedWith('invalid-array-length'); }); it('Should not depositForArray with address zero in target', async () => { - const depositAmounts = [depositAmount, depositAmount.mul(2)]; - - const depositTotalAmount = getTotalAmount(depositAmounts); + const depositForArrayParams = { + amounts: [standardAmount, standardAmount.mul(2)], + targets: [AddressZero, accountB.address], + }; + const depositForArrayArgs = Object.values(depositForArrayParams) as [ + BigNumber[], + string[], + ]; + const depositTotalAmount = getTotalAmount(depositForArrayParams.amounts); await rlcInstanceAsAccountA .approve(iexecPoco.address, depositTotalAmount) .then((tx) => tx.wait()); - const targets = [AddressZero, accountB.address]; await expect( - iexecPocoAsAccountA.depositForArray(depositAmounts, targets), + iexecPocoAsAccountA.depositForArray(...depositForArrayArgs), ).to.be.revertedWith('ERC20: mint to the zero address'); }); }); @@ -184,19 +239,19 @@ describe('IexecEscrowTokenDelegate', () => { describe('Withdraw', () => { it('Should withdraw tokens', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositAmount) + .approve(iexecPoco.address, depositParams.amount) .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(depositAmount).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(...depositArgs).then((tx) => tx.wait()); - expect(await iexecPocoAsAccountA.callStatic.withdraw(withdrawAmount)).to.be.true; - await expect(iexecPocoAsAccountA.withdraw(withdrawAmount)) + expect(await iexecPocoAsAccountA.callStatic.withdraw(...withdrawArgs)).to.be.true; + await expect(iexecPocoAsAccountA.withdraw(...withdrawArgs)) .to.changeTokenBalances( rlcInstance, [iexecPoco, accountA], - [-withdrawAmount, withdrawAmount], + [-withdrawParams.amount, withdrawParams.amount], ) .to.emit(iexecPoco, 'Transfer') - .withArgs(accountA.address, AddressZero, withdrawAmount); + .withArgs(accountA.address, AddressZero, withdrawParams.amount); }); it('Should withdraw zero token', async () => { expect(await iexecPocoAsAccountA.callStatic.withdraw(0)).to.be.true; @@ -207,17 +262,17 @@ describe('IexecEscrowTokenDelegate', () => { }); it('Should not withdraw native tokens with empty balance', async () => { await expect( - iexecPocoAsAccountA.withdraw(withdrawAmount), + iexecPocoAsAccountA.withdraw(...withdrawArgs), ).to.be.revertedWithoutReason(); }); it('Should not withdraw tokens with insufficient balance', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositAmount) + .approve(iexecPoco.address, depositParams.amount) .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(depositAmount).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(...depositArgs).then((tx) => tx.wait()); await expect( - iexecPocoAsAccountA.withdraw(depositAmount.mul(2)), + iexecPocoAsAccountA.withdraw(depositParams.amount.mul(2)), ).to.be.revertedWithoutReason(); }); }); @@ -225,52 +280,78 @@ describe('IexecEscrowTokenDelegate', () => { describe('Withdraw to', () => { it('Should withdraw another address', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositAmount) + .approve(iexecPoco.address, depositParams.amount) .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(depositAmount).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(...depositArgs).then((tx) => tx.wait()); + + const withdrawToParams = { + amount: withdrawParams.amount, + target: accountB.address, + }; + const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; - expect( - await iexecPocoAsAccountA.callStatic.withdrawTo(withdrawAmount, accountB.address), - ).to.be.true; - await expect(iexecPocoAsAccountA.withdrawTo(withdrawAmount, accountB.address)) + expect(await iexecPocoAsAccountA.callStatic.withdrawTo(...withdrawToArgs)).to.be.true; + await expect(iexecPocoAsAccountA.withdrawTo(...withdrawToArgs)) .to.changeTokenBalances( rlcInstance, [iexecPoco, accountB], - [-withdrawAmount, withdrawAmount], + [-withdrawToParams.amount, withdrawToParams.amount], ) .to.emit(iexecPoco, 'Transfer') - .withArgs(accountA.address, AddressZero, withdrawAmount); + .withArgs(accountA.address, AddressZero, withdrawToParams.amount); }); it('Should withdraw To with zero token', async () => { - expect(await iexecPocoAsAccountA.callStatic.withdrawTo(0, accountB.address)).to.be.true; - await expect(iexecPocoAsAccountA.withdrawTo(0, accountB.address)) - .to.changeTokenBalances(rlcInstance, [iexecPoco, accountB], [-0, 0]) + const withdrawToParams = { + amount: 0, + target: accountB.address, + }; + const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; + + expect(await iexecPocoAsAccountA.callStatic.withdrawTo(...withdrawToArgs)).to.be.true; + await expect(iexecPocoAsAccountA.withdrawTo(...withdrawToArgs)) + .to.changeTokenBalances( + rlcInstance, + [iexecPoco, accountB], + [-withdrawToParams.amount, withdrawToParams.amount], + ) .to.emit(iexecPoco, 'Transfer') .withArgs(accountA.address, AddressZero, 0); }); it('Should not withdraw To tokens with empty balance', async () => { + const withdrawToParams = { + amount: withdrawParams.amount, + target: accountB.address, + }; + const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; + await expect( - iexecPocoAsAccountA.withdrawTo(withdrawAmount, accountB.address), + iexecPocoAsAccountA.withdrawTo(...withdrawToArgs), ).to.be.revertedWithoutReason(); }); it('Should not withdraw To tokens with insufficient balance', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositAmount) + .approve(iexecPoco.address, depositParams.amount) .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(depositAmount).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(...depositArgs).then((tx) => tx.wait()); + + const withdrawToParams = { + amount: depositParams.amount.mul(2), + target: accountB.address, + }; + const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; await expect( - iexecPocoAsAccountA.withdrawTo(depositAmount.mul(2), accountB.address), + iexecPocoAsAccountA.withdrawTo(...withdrawToArgs), ).to.be.revertedWithoutReason(); }); }); describe('Recover', () => { it('Should recover from balance deviation', async () => { - await rlcInstance.connect(iexecAdmin).transfer(proxyAddress, depositAmount); // Simulate deviation + await rlcInstance.connect(iexecAdmin).transfer(proxyAddress, standardAmount); // Simulate deviation const initTotalSupply = await iexecPoco.totalSupply(); - const expectedDelta = depositAmount; + const expectedDelta = standardAmount; await expect(iexecPocoAsAdmin.recover()) .to.emit(iexecPoco, 'Transfer') @@ -296,41 +377,70 @@ describe('IexecEscrowTokenDelegate', () => { describe('receiveApproval', () => { it('Should receiveApproval', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositAmount) + .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - expect( - await iexecPocoAsAccountA.callStatic.receiveApproval( - accountA.address, - depositAmount, - rlcInstance.address, - '0x', - ), - ).to.be.true; - await expect( - iexecPocoAsAccountA.receiveApproval( - accountA.address, - depositAmount, - rlcInstance.address, - '0x', - ), - ) + + const receiveApprovalParams = { + sender: accountA.address, + amount: standardAmount, + token: rlcInstance.address, + extraData: '0x', + }; + const receiveApprovalArgs = Object.values(receiveApprovalParams) as [ + string, + BigNumber, + string, + string, + ]; + expect(await iexecPocoAsAccountA.callStatic.receiveApproval(...receiveApprovalArgs)).to + .be.true; + await expect(iexecPocoAsAccountA.receiveApproval(...receiveApprovalArgs)) .to.changeTokenBalances( rlcInstance, [accountA, iexecPoco], - [-depositAmount, depositAmount], + [-receiveApprovalParams.amount, receiveApprovalParams.amount], ) .to.emit(iexecPoco, 'Transfer') - .withArgs(AddressZero, accountA.address, depositAmount); + .withArgs(AddressZero, receiveApprovalParams.sender, receiveApprovalParams.amount); }); + it('Should receiveApproval for another sender', async () => { + await rlcInstance + .connect(iexecAdmin) + .transfer(accountB.address, standardAmount) + .then((tx) => tx.wait()); + await rlcInstance + .connect(accountB) + .approve(iexecPoco.address, standardAmount) + .then((tx) => tx.wait()); + const receiveApprovalParams = { + sender: accountB.address, + amount: standardAmount, + token: rlcInstance.address, + extraData: '0x', + }; + const receiveApprovalArgs = Object.values(receiveApprovalParams) as [ + string, + BigNumber, + string, + string, + ]; + expect(await iexecPocoAsAccountA.callStatic.receiveApproval(...receiveApprovalArgs)).to + .be.true; + await expect(iexecPocoAsAccountA.receiveApproval(...receiveApprovalArgs)) + .to.changeTokenBalances( + rlcInstance, + [accountB, iexecPoco], + [-receiveApprovalParams.amount, receiveApprovalParams.amount], + ) + .to.emit(iexecPoco, 'Transfer') + .withArgs(AddressZero, receiveApprovalParams.sender, receiveApprovalParams.amount); + }); it('Should not receiveApproval when the wrong token is used', async () => { - await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositAmount) - .then((tx) => tx.wait()); await expect( iexecPocoAsAccountA.receiveApproval( accountA.address, - depositAmount, + standardAmount, ethers.Wallet.createRandom().address, '0x', ), @@ -339,8 +449,8 @@ describe('IexecEscrowTokenDelegate', () => { }); }); -function AmountWithDecimals(depositAmount: BigNumber) { - return ethers.utils.parseUnits(depositAmount.toString(), 9); +function AmountWithDecimals(amount: BigNumber) { + return ethers.utils.parseUnits(amount.toString(), 9); } function getTotalAmount(amounts: BigNumber[]) { return amounts.reduce((a, b) => a.add(b), BigNumber.from(0)); From 265a539ba5a32b2ff8ff44990acfd5e9cb01c6aa Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Tue, 8 Oct 2024 16:04:21 +0200 Subject: [PATCH 03/17] update change log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d54ccf9f..30613cc73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## vNEXT - Migrate unit test files to Typescript & Hardhat: + - IexecEscrowToken (#141) - IexecRelay (#140) - IexecPoco1 (#136, #137) - IexecPoco2 From 34c666a408d1b630f82a229b8ff23f8e52fc91ec Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 09:54:53 +0200 Subject: [PATCH 04/17] update check changes on sRLC and RLC transfer events --- .../IexecEscrow/IexecEscrowToken.test.ts | 48 +++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index a3bbf9fcf..832e6df13 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -87,6 +87,9 @@ describe('IexecEscrowTokenDelegate', () => { [accountA, iexecPoco], [-depositParams.amount, depositParams.amount], ) + .to.emit(rlcInstance, 'Transfer') + .withArgs(accountA.address, iexecPoco, depositParams.amount) + .to.changeTokenBalances(iexecPoco, [accountA], [depositParams.amount]) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, accountA.address, depositParams.amount); }); @@ -94,6 +97,9 @@ describe('IexecEscrowTokenDelegate', () => { expect(await iexecPocoAsAccountA.callStatic.deposit(0)).to.be.true; await expect(iexecPocoAsAccountA.deposit(0)) .to.changeTokenBalances(rlcInstance, [accountA, iexecPoco], [-0, 0]) + .to.emit(rlcInstance, 'Transfer') + .withArgs(accountA.address, iexecPoco, 0) + .to.changeTokenBalances(iexecPoco, [accountA], [0]) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, accountA.address, 0); }); @@ -142,6 +148,13 @@ describe('IexecEscrowTokenDelegate', () => { [accountA, iexecPoco], [-depositForParams.amount, depositForParams.amount], ) + .to.emit(rlcInstance, 'Transfer') + .withArgs(accountA.address, iexecPoco, depositForParams.amount) + .to.changeTokenBalances( + iexecPoco, + [depositForParams.target], + [depositParams.amount], + ) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, depositForParams.target, depositForParams.amount); }); @@ -184,6 +197,13 @@ describe('IexecEscrowTokenDelegate', () => { [accountA, iexecPoco], [-depositTotalAmount, depositTotalAmount], ) + .to.emit(rlcInstance, 'Transfer') + .withArgs(accountA.address, iexecPoco, depositTotalAmount) + .to.changeTokenBalances( + iexecPoco, + [...depositForArrayParams.targets], + [...depositForArrayParams.amounts], + ) .to.emit(iexecPoco, 'Transfer') .withArgs( AddressZero, @@ -250,6 +270,9 @@ describe('IexecEscrowTokenDelegate', () => { [iexecPoco, accountA], [-withdrawParams.amount, withdrawParams.amount], ) + .to.emit(rlcInstance, 'Transfer') + .withArgs(iexecPoco, accountA.address, withdrawParams.amount) + .to.changeTokenBalances(iexecPoco, [accountA], [-withdrawParams.amount]) .to.emit(iexecPoco, 'Transfer') .withArgs(accountA.address, AddressZero, withdrawParams.amount); }); @@ -257,6 +280,9 @@ describe('IexecEscrowTokenDelegate', () => { expect(await iexecPocoAsAccountA.callStatic.withdraw(0)).to.be.true; await expect(iexecPocoAsAccountA.withdraw(0)) .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-0, 0]) + .to.emit(rlcInstance, 'Transfer') + .withArgs(iexecPoco, accountA.address, 0) + .to.changeTokenBalances(iexecPoco, [accountA], [-0]) .to.emit(iexecPoco, 'Transfer') .withArgs(accountA.address, AddressZero, 0); }); @@ -297,6 +323,9 @@ describe('IexecEscrowTokenDelegate', () => { [iexecPoco, accountB], [-withdrawToParams.amount, withdrawToParams.amount], ) + .to.emit(rlcInstance, 'Transfer') + .withArgs(iexecPoco, withdrawToParams.target, withdrawToParams.amount) + .to.changeTokenBalances(iexecPoco, [accountA], [-withdrawParams.amount]) .to.emit(iexecPoco, 'Transfer') .withArgs(accountA.address, AddressZero, withdrawToParams.amount); }); @@ -309,11 +338,10 @@ describe('IexecEscrowTokenDelegate', () => { expect(await iexecPocoAsAccountA.callStatic.withdrawTo(...withdrawToArgs)).to.be.true; await expect(iexecPocoAsAccountA.withdrawTo(...withdrawToArgs)) - .to.changeTokenBalances( - rlcInstance, - [iexecPoco, accountB], - [-withdrawToParams.amount, withdrawToParams.amount], - ) + .to.changeTokenBalances(rlcInstance, [iexecPoco, accountB], [-0, 0]) + .to.emit(rlcInstance, 'Transfer') + .withArgs(iexecPoco, withdrawToParams.target, 0) + .to.changeTokenBalances(iexecPoco, [accountA], [-0]) .to.emit(iexecPoco, 'Transfer') .withArgs(accountA.address, AddressZero, 0); }); @@ -400,6 +428,9 @@ describe('IexecEscrowTokenDelegate', () => { [accountA, iexecPoco], [-receiveApprovalParams.amount, receiveApprovalParams.amount], ) + .to.emit(rlcInstance, 'Transfer') + .withArgs(accountA.address, iexecPoco, receiveApprovalParams.amount) + .to.changeTokenBalances(iexecPoco, [accountA], [receiveApprovalParams.amount]) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, receiveApprovalParams.sender, receiveApprovalParams.amount); }); @@ -433,6 +464,13 @@ describe('IexecEscrowTokenDelegate', () => { [accountB, iexecPoco], [-receiveApprovalParams.amount, receiveApprovalParams.amount], ) + .to.emit(rlcInstance, 'Transfer') + .withArgs(receiveApprovalParams.sender, iexecPoco, receiveApprovalParams.amount) + .to.changeTokenBalances( + iexecPoco, + [receiveApprovalParams.sender], + [receiveApprovalParams.amount], + ) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, receiveApprovalParams.sender, receiveApprovalParams.amount); }); From b6f315aa7360bcc8354b03ee8307d52f71832bb2 Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 09:55:32 +0200 Subject: [PATCH 05/17] clean suggestions --- test/byContract/IexecEscrow/IexecEscrowToken.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index 832e6df13..37e8177c8 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -25,7 +25,7 @@ const withdrawParams = { }; const withdrawArgs = Object.values(withdrawParams) as [BigNumber]; -describe('IexecEscrowTokenDelegate', () => { +describe('IexecEscrowToken', () => { let proxyAddress: string; let [iexecPoco, , iexecPocoAsAccountA, iexecPocoAsAdmin]: IexecInterfaceToken[] = []; let [iexecAdmin, accountA, accountB, anyone]: SignerWithAddress[] = []; @@ -43,7 +43,7 @@ describe('IexecEscrowTokenDelegate', () => { iexecPoco = IexecInterfaceToken__factory.connect(proxyAddress, anyone); iexecPocoAsAccountA = iexecPoco.connect(accountA); iexecPocoAsAdmin = iexecPoco.connect(iexecAdmin); - rlcInstance = await RLC__factory.connect(await iexecPoco.token(), anyone); + rlcInstance = RLC__factory.connect(await iexecPoco.token(), anyone); rlcInstanceAsAccountA = rlcInstance.connect(accountA); await rlcInstance .connect(iexecAdmin) From 08393448e90e9079d85ff3d04ea36375a7cc0bf8 Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 09:59:04 +0200 Subject: [PATCH 06/17] clean 2 --- test/byContract/IexecEscrow/IexecEscrowToken.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index 37e8177c8..b62bebde6 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -47,7 +47,7 @@ describe('IexecEscrowToken', () => { rlcInstanceAsAccountA = rlcInstance.connect(accountA); await rlcInstance .connect(iexecAdmin) - .transfer(accountA.address, AmountWithDecimals(BigNumber.from(10_000))) + .transfer(accountA.address, standardAmount.mul(10)) .then((tx) => tx.wait()); } @@ -231,7 +231,6 @@ describe('IexecEscrowToken', () => { await rlcInstanceAsAccountA .approve(iexecPoco.address, depositTotalAmount) .then((tx) => tx.wait()); - const targets = [iexecAdmin.address, accountB.address]; await expect( iexecPocoAsAccountA.depositForArray(...depositForArrayArgs), ).to.be.revertedWith('invalid-array-length'); From 5a1ec788c96f674292845e76d0c97953abda6da8 Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 11:03:11 +0200 Subject: [PATCH 07/17] remove *params and use standardAmount --- .../IexecEscrow/IexecEscrowToken.test.ts | 83 ++++++++----------- 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index b62bebde6..ba55daa33 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -16,14 +16,6 @@ import { import { getIexecAccounts } from '../../../utils/poco-tools'; const standardAmount = AmountWithDecimals(BigNumber.from(100)); -const depositParams = { - amount: standardAmount, -}; -const depositArgs = Object.values(depositParams) as [BigNumber]; -const withdrawParams = { - amount: standardAmount, -}; -const withdrawArgs = Object.values(withdrawParams) as [BigNumber]; describe('IexecEscrowToken', () => { let proxyAddress: string; @@ -47,7 +39,7 @@ describe('IexecEscrowToken', () => { rlcInstanceAsAccountA = rlcInstance.connect(accountA); await rlcInstance .connect(iexecAdmin) - .transfer(accountA.address, standardAmount.mul(10)) + .transfer(accountA.address, standardAmount.mul(10)) //enough to cover tests. .then((tx) => tx.wait()); } @@ -77,21 +69,21 @@ describe('IexecEscrowToken', () => { describe('Deposit', () => { it('Should deposit tokens', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositParams.amount) + .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - expect(await iexecPocoAsAccountA.callStatic.deposit(...depositArgs)).to.be.true; - await expect(iexecPocoAsAccountA.deposit(...depositArgs)) + expect(await iexecPocoAsAccountA.callStatic.deposit(standardAmount)).to.be.true; + await expect(iexecPocoAsAccountA.deposit(standardAmount)) .to.changeTokenBalances( rlcInstance, [accountA, iexecPoco], - [-depositParams.amount, depositParams.amount], + [-standardAmount, standardAmount], ) .to.emit(rlcInstance, 'Transfer') - .withArgs(accountA.address, iexecPoco, depositParams.amount) - .to.changeTokenBalances(iexecPoco, [accountA], [depositParams.amount]) + .withArgs(accountA.address, iexecPoco, standardAmount) + .to.changeTokenBalances(iexecPoco, [accountA], [standardAmount]) .to.emit(iexecPoco, 'Transfer') - .withArgs(AddressZero, accountA.address, depositParams.amount); + .withArgs(AddressZero, accountA.address, standardAmount); }); it('Should deposit 0 token', async () => { expect(await iexecPocoAsAccountA.callStatic.deposit(0)).to.be.true; @@ -117,15 +109,14 @@ describe('IexecEscrowToken', () => { }) .then((tx) => tx.wait()); - const rlcInstanceAsAddress0 = rlcInstance.connect(AddressZeroSigner); - await rlcInstanceAsAddress0 - .approve(iexecPoco.address, depositParams.amount) + await rlcInstance + .connect(AddressZeroSigner) + .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - const iexecPocoAsAddress0 = iexecPoco.connect(AddressZeroSigner); - await expect(iexecPocoAsAddress0.deposit(...depositArgs)).to.be.revertedWith( - 'ERC20: mint to the zero address', - ); + await expect( + iexecPoco.connect(AddressZeroSigner).deposit(standardAmount), + ).to.be.revertedWith('ERC20: mint to the zero address'); }); }); @@ -150,11 +141,7 @@ describe('IexecEscrowToken', () => { ) .to.emit(rlcInstance, 'Transfer') .withArgs(accountA.address, iexecPoco, depositForParams.amount) - .to.changeTokenBalances( - iexecPoco, - [depositForParams.target], - [depositParams.amount], - ) + .to.changeTokenBalances(iexecPoco, [depositForParams.target], [standardAmount]) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, depositForParams.target, depositForParams.amount); }); @@ -258,22 +245,22 @@ describe('IexecEscrowToken', () => { describe('Withdraw', () => { it('Should withdraw tokens', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositParams.amount) + .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(...depositArgs).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(standardAmount).then((tx) => tx.wait()); - expect(await iexecPocoAsAccountA.callStatic.withdraw(...withdrawArgs)).to.be.true; - await expect(iexecPocoAsAccountA.withdraw(...withdrawArgs)) + expect(await iexecPocoAsAccountA.callStatic.withdraw(standardAmount)).to.be.true; + await expect(iexecPocoAsAccountA.withdraw(standardAmount)) .to.changeTokenBalances( rlcInstance, [iexecPoco, accountA], - [-withdrawParams.amount, withdrawParams.amount], + [-standardAmount, standardAmount], ) .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, accountA.address, withdrawParams.amount) - .to.changeTokenBalances(iexecPoco, [accountA], [-withdrawParams.amount]) + .withArgs(iexecPoco, accountA.address, standardAmount) + .to.changeTokenBalances(iexecPoco, [accountA], [-standardAmount]) .to.emit(iexecPoco, 'Transfer') - .withArgs(accountA.address, AddressZero, withdrawParams.amount); + .withArgs(accountA.address, AddressZero, standardAmount); }); it('Should withdraw zero token', async () => { expect(await iexecPocoAsAccountA.callStatic.withdraw(0)).to.be.true; @@ -287,17 +274,17 @@ describe('IexecEscrowToken', () => { }); it('Should not withdraw native tokens with empty balance', async () => { await expect( - iexecPocoAsAccountA.withdraw(...withdrawArgs), + iexecPocoAsAccountA.withdraw(standardAmount), ).to.be.revertedWithoutReason(); }); it('Should not withdraw tokens with insufficient balance', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositParams.amount) + .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(...depositArgs).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(standardAmount).then((tx) => tx.wait()); await expect( - iexecPocoAsAccountA.withdraw(depositParams.amount.mul(2)), + iexecPocoAsAccountA.withdraw(standardAmount.mul(2)), ).to.be.revertedWithoutReason(); }); }); @@ -305,12 +292,12 @@ describe('IexecEscrowToken', () => { describe('Withdraw to', () => { it('Should withdraw another address', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositParams.amount) + .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(...depositArgs).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(standardAmount).then((tx) => tx.wait()); const withdrawToParams = { - amount: withdrawParams.amount, + amount: standardAmount, target: accountB.address, }; const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; @@ -324,7 +311,7 @@ describe('IexecEscrowToken', () => { ) .to.emit(rlcInstance, 'Transfer') .withArgs(iexecPoco, withdrawToParams.target, withdrawToParams.amount) - .to.changeTokenBalances(iexecPoco, [accountA], [-withdrawParams.amount]) + .to.changeTokenBalances(iexecPoco, [accountA], [-standardAmount]) .to.emit(iexecPoco, 'Transfer') .withArgs(accountA.address, AddressZero, withdrawToParams.amount); }); @@ -346,7 +333,7 @@ describe('IexecEscrowToken', () => { }); it('Should not withdraw To tokens with empty balance', async () => { const withdrawToParams = { - amount: withdrawParams.amount, + amount: standardAmount, target: accountB.address, }; const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; @@ -357,12 +344,12 @@ describe('IexecEscrowToken', () => { }); it('Should not withdraw To tokens with insufficient balance', async () => { await rlcInstanceAsAccountA - .approve(iexecPoco.address, depositParams.amount) + .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(...depositArgs).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(standardAmount).then((tx) => tx.wait()); const withdrawToParams = { - amount: depositParams.amount.mul(2), + amount: standardAmount.mul(2), target: accountB.address, }; const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; From 0674928954cd51281a6611ed34a04749a7998bc9 Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 11:48:26 +0200 Subject: [PATCH 08/17] rename addr zero signer --- test/byContract/IexecEscrow/IexecEscrowToken.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index ba55daa33..e2bb26da7 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -96,26 +96,26 @@ describe('IexecEscrowToken', () => { .withArgs(AddressZero, accountA.address, 0); }); it('Should not deposit tokens when caller is address 0', async () => { - const AddressZeroSigner = await ethers.getImpersonatedSigner(AddressZero); + const addressZeroSigner = await ethers.getImpersonatedSigner(AddressZero); await rlcInstance .connect(iexecAdmin) - .transfer(AddressZeroSigner.address, standardAmount) + .transfer(addressZeroSigner.address, standardAmount) .then((tx) => tx.wait()); // send some gas token iexecAdmin .sendTransaction({ - to: AddressZeroSigner.address, + to: addressZeroSigner.address, value: AmountWithDecimals(BigNumber.from(100_000)), }) .then((tx) => tx.wait()); await rlcInstance - .connect(AddressZeroSigner) + .connect(addressZeroSigner) .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); await expect( - iexecPoco.connect(AddressZeroSigner).deposit(standardAmount), + iexecPoco.connect(addressZeroSigner).deposit(standardAmount), ).to.be.revertedWith('ERC20: mint to the zero address'); }); }); From a331a0d25aa3ca3adf68803e4e49c39598630619 Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 12:03:13 +0200 Subject: [PATCH 09/17] remove params and args variables when reverted when possible --- .../IexecEscrow/IexecEscrowToken.test.ts | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index e2bb26da7..cc83232ae 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -141,7 +141,11 @@ describe('IexecEscrowToken', () => { ) .to.emit(rlcInstance, 'Transfer') .withArgs(accountA.address, iexecPoco, depositForParams.amount) - .to.changeTokenBalances(iexecPoco, [depositForParams.target], [standardAmount]) + .to.changeTokenBalances( + iexecPoco, + [depositForParams.target], + [depositForParams.amount], + ) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, depositForParams.target, depositForParams.amount); }); @@ -149,15 +153,9 @@ describe('IexecEscrowToken', () => { await rlcInstanceAsAccountA .approve(iexecPoco.address, standardAmount) .then((tx) => tx.wait()); - - const depositForParams = { - amount: standardAmount, - target: AddressZero, - }; - const depositForArgs = Object.values(depositForParams) as [BigNumber, string]; - await expect(iexecPocoAsAccountA.depositFor(...depositForArgs)).to.be.revertedWith( - 'ERC20: mint to the zero address', - ); + await expect( + iexecPocoAsAccountA.depositFor(standardAmount, AddressZero), + ).to.be.revertedWith('ERC20: mint to the zero address'); }); }); @@ -332,14 +330,8 @@ describe('IexecEscrowToken', () => { .withArgs(accountA.address, AddressZero, 0); }); it('Should not withdraw To tokens with empty balance', async () => { - const withdrawToParams = { - amount: standardAmount, - target: accountB.address, - }; - const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; - await expect( - iexecPocoAsAccountA.withdrawTo(...withdrawToArgs), + iexecPocoAsAccountA.withdrawTo(standardAmount, accountB.address), ).to.be.revertedWithoutReason(); }); it('Should not withdraw To tokens with insufficient balance', async () => { @@ -348,14 +340,8 @@ describe('IexecEscrowToken', () => { .then((tx) => tx.wait()); await iexecPocoAsAccountA.deposit(standardAmount).then((tx) => tx.wait()); - const withdrawToParams = { - amount: standardAmount.mul(2), - target: accountB.address, - }; - const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; - await expect( - iexecPocoAsAccountA.withdrawTo(...withdrawToArgs), + iexecPocoAsAccountA.withdrawTo(standardAmount.mul(2), accountB.address), ).to.be.revertedWithoutReason(); }); }); From 478f09f557b3d7215ce2ad22dcf69d86da02cf6f Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 12:10:13 +0200 Subject: [PATCH 10/17] introduce account C and clean account B --- .../IexecEscrow/IexecEscrowToken.test.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index cc83232ae..206645138 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -20,7 +20,7 @@ const standardAmount = AmountWithDecimals(BigNumber.from(100)); describe('IexecEscrowToken', () => { let proxyAddress: string; let [iexecPoco, , iexecPocoAsAccountA, iexecPocoAsAdmin]: IexecInterfaceToken[] = []; - let [iexecAdmin, accountA, accountB, anyone]: SignerWithAddress[] = []; + let [iexecAdmin, accountA, accountB, accountC, anyone]: SignerWithAddress[] = []; let [rlcInstance, rlcInstanceAsAccountA]: RLC[] = []; beforeEach('Deploy', async () => { @@ -30,7 +30,13 @@ describe('IexecEscrowToken', () => { async function initFixture() { const accounts = await getIexecAccounts(); - ({ iexecAdmin, anyone: accountA, requester: accountB, anyone } = accounts); + ({ + iexecAdmin, + anyone: accountA, + requester: accountB, + sponsor: accountC, + anyone, + } = accounts); iexecPoco = IexecInterfaceToken__factory.connect(proxyAddress, anyone); iexecPocoAsAccountA = iexecPoco.connect(accountA); @@ -163,7 +169,7 @@ describe('IexecEscrowToken', () => { it('Should deposit tokens for multiple accounts', async () => { const depositForArrayParams = { amounts: [standardAmount, standardAmount.mul(2)], - targets: [iexecAdmin.address, accountB.address], + targets: [accountB.address, accountC.address], }; const depositForArrayArgs = Object.values(depositForArrayParams) as [ BigNumber[], @@ -205,7 +211,7 @@ describe('IexecEscrowToken', () => { it('Should not depositForArray with mismatched array lengths', async () => { const depositForArrayParams = { amounts: [standardAmount.mul(2), standardAmount, standardAmount.div(2)], - targets: [iexecAdmin.address, accountB.address], + targets: [accountB.address, accountC.address], }; const depositForArrayArgs = Object.values(depositForArrayParams) as [ BigNumber[], @@ -304,7 +310,7 @@ describe('IexecEscrowToken', () => { await expect(iexecPocoAsAccountA.withdrawTo(...withdrawToArgs)) .to.changeTokenBalances( rlcInstance, - [iexecPoco, accountB], + [iexecPoco, withdrawToParams.target], [-withdrawToParams.amount, withdrawToParams.amount], ) .to.emit(rlcInstance, 'Transfer') @@ -433,7 +439,7 @@ describe('IexecEscrowToken', () => { await expect(iexecPocoAsAccountA.receiveApproval(...receiveApprovalArgs)) .to.changeTokenBalances( rlcInstance, - [accountB, iexecPoco], + [receiveApprovalParams.sender, iexecPoco], [-receiveApprovalParams.amount, receiveApprovalParams.amount], ) .to.emit(rlcInstance, 'Transfer') From 9528dd4715415dbe283c681c960de4182dea40c4 Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 15:35:15 +0200 Subject: [PATCH 11/17] rename to amount and use parseUnits instead of fct --- .../IexecEscrow/IexecEscrowToken.test.ts | 139 +++++++----------- 1 file changed, 54 insertions(+), 85 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index 206645138..eba381c32 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -15,7 +15,7 @@ import { } from '../../../typechain'; import { getIexecAccounts } from '../../../utils/poco-tools'; -const standardAmount = AmountWithDecimals(BigNumber.from(100)); +const amount = ethers.utils.parseUnits(BigNumber.from(100).toString(), 9); describe('IexecEscrowToken', () => { let proxyAddress: string; @@ -45,7 +45,7 @@ describe('IexecEscrowToken', () => { rlcInstanceAsAccountA = rlcInstance.connect(accountA); await rlcInstance .connect(iexecAdmin) - .transfer(accountA.address, standardAmount.mul(10)) //enough to cover tests. + .transfer(accountA.address, amount.mul(10)) //enough to cover tests. .then((tx) => tx.wait()); } @@ -54,7 +54,7 @@ describe('IexecEscrowToken', () => { await expect( accountA.sendTransaction({ to: iexecPoco.address, - value: standardAmount, + value: amount, }), ).to.be.revertedWith('fallback-disabled'); }); @@ -65,7 +65,7 @@ describe('IexecEscrowToken', () => { await expect( accountA.sendTransaction({ to: iexecPoco.address, - value: standardAmount, + value: amount, data: randomData, }), ).to.be.revertedWith('fallback-disabled'); @@ -74,22 +74,16 @@ describe('IexecEscrowToken', () => { describe('Deposit', () => { it('Should deposit tokens', async () => { - await rlcInstanceAsAccountA - .approve(iexecPoco.address, standardAmount) - .then((tx) => tx.wait()); + await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); - expect(await iexecPocoAsAccountA.callStatic.deposit(standardAmount)).to.be.true; - await expect(iexecPocoAsAccountA.deposit(standardAmount)) - .to.changeTokenBalances( - rlcInstance, - [accountA, iexecPoco], - [-standardAmount, standardAmount], - ) + expect(await iexecPocoAsAccountA.callStatic.deposit(amount)).to.be.true; + await expect(iexecPocoAsAccountA.deposit(amount)) + .to.changeTokenBalances(rlcInstance, [accountA, iexecPoco], [-amount, amount]) .to.emit(rlcInstance, 'Transfer') - .withArgs(accountA.address, iexecPoco, standardAmount) - .to.changeTokenBalances(iexecPoco, [accountA], [standardAmount]) + .withArgs(accountA.address, iexecPoco, amount) + .to.changeTokenBalances(iexecPoco, [accountA], [amount]) .to.emit(iexecPoco, 'Transfer') - .withArgs(AddressZero, accountA.address, standardAmount); + .withArgs(AddressZero, accountA.address, amount); }); it('Should deposit 0 token', async () => { expect(await iexecPocoAsAccountA.callStatic.deposit(0)).to.be.true; @@ -105,35 +99,33 @@ describe('IexecEscrowToken', () => { const addressZeroSigner = await ethers.getImpersonatedSigner(AddressZero); await rlcInstance .connect(iexecAdmin) - .transfer(addressZeroSigner.address, standardAmount) + .transfer(addressZeroSigner.address, amount) .then((tx) => tx.wait()); // send some gas token iexecAdmin .sendTransaction({ to: addressZeroSigner.address, - value: AmountWithDecimals(BigNumber.from(100_000)), + value: ethers.utils.parseUnits(BigNumber.from(100_000).toString(), 9), }) .then((tx) => tx.wait()); await rlcInstance .connect(addressZeroSigner) - .approve(iexecPoco.address, standardAmount) + .approve(iexecPoco.address, amount) .then((tx) => tx.wait()); - await expect( - iexecPoco.connect(addressZeroSigner).deposit(standardAmount), - ).to.be.revertedWith('ERC20: mint to the zero address'); + await expect(iexecPoco.connect(addressZeroSigner).deposit(amount)).to.be.revertedWith( + 'ERC20: mint to the zero address', + ); }); }); describe('Deposit for', () => { it('Should deposit tokens for another account', async () => { - await rlcInstanceAsAccountA - .approve(iexecPoco.address, standardAmount) - .then((tx) => tx.wait()); + await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); const depositForParams = { - amount: standardAmount, + amount: amount, target: accountB.address, }; const depositForArgs = Object.values(depositForParams) as [BigNumber, string]; @@ -156,19 +148,17 @@ describe('IexecEscrowToken', () => { .withArgs(AddressZero, depositForParams.target, depositForParams.amount); }); it('Should not deposit tokens for zero address', async () => { - await rlcInstanceAsAccountA - .approve(iexecPoco.address, standardAmount) - .then((tx) => tx.wait()); - await expect( - iexecPocoAsAccountA.depositFor(standardAmount, AddressZero), - ).to.be.revertedWith('ERC20: mint to the zero address'); + await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); + await expect(iexecPocoAsAccountA.depositFor(amount, AddressZero)).to.be.revertedWith( + 'ERC20: mint to the zero address', + ); }); }); describe('Deposit for array', () => { it('Should deposit tokens for multiple accounts', async () => { const depositForArrayParams = { - amounts: [standardAmount, standardAmount.mul(2)], + amounts: [amount, amount.mul(2)], targets: [accountB.address, accountC.address], }; const depositForArrayArgs = Object.values(depositForArrayParams) as [ @@ -210,7 +200,7 @@ describe('IexecEscrowToken', () => { }); it('Should not depositForArray with mismatched array lengths', async () => { const depositForArrayParams = { - amounts: [standardAmount.mul(2), standardAmount, standardAmount.div(2)], + amounts: [amount.mul(2), amount, amount.div(2)], targets: [accountB.address, accountC.address], }; const depositForArrayArgs = Object.values(depositForArrayParams) as [ @@ -228,7 +218,7 @@ describe('IexecEscrowToken', () => { }); it('Should not depositForArray with address zero in target', async () => { const depositForArrayParams = { - amounts: [standardAmount, standardAmount.mul(2)], + amounts: [amount, amount.mul(2)], targets: [AddressZero, accountB.address], }; const depositForArrayArgs = Object.values(depositForArrayParams) as [ @@ -248,23 +238,17 @@ describe('IexecEscrowToken', () => { describe('Withdraw', () => { it('Should withdraw tokens', async () => { - await rlcInstanceAsAccountA - .approve(iexecPoco.address, standardAmount) - .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(standardAmount).then((tx) => tx.wait()); + await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(amount).then((tx) => tx.wait()); - expect(await iexecPocoAsAccountA.callStatic.withdraw(standardAmount)).to.be.true; - await expect(iexecPocoAsAccountA.withdraw(standardAmount)) - .to.changeTokenBalances( - rlcInstance, - [iexecPoco, accountA], - [-standardAmount, standardAmount], - ) + expect(await iexecPocoAsAccountA.callStatic.withdraw(amount)).to.be.true; + await expect(iexecPocoAsAccountA.withdraw(amount)) + .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-amount, amount]) .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, accountA.address, standardAmount) - .to.changeTokenBalances(iexecPoco, [accountA], [-standardAmount]) + .withArgs(iexecPoco, accountA.address, amount) + .to.changeTokenBalances(iexecPoco, [accountA], [-amount]) .to.emit(iexecPoco, 'Transfer') - .withArgs(accountA.address, AddressZero, standardAmount); + .withArgs(accountA.address, AddressZero, amount); }); it('Should withdraw zero token', async () => { expect(await iexecPocoAsAccountA.callStatic.withdraw(0)).to.be.true; @@ -277,31 +261,23 @@ describe('IexecEscrowToken', () => { .withArgs(accountA.address, AddressZero, 0); }); it('Should not withdraw native tokens with empty balance', async () => { - await expect( - iexecPocoAsAccountA.withdraw(standardAmount), - ).to.be.revertedWithoutReason(); + await expect(iexecPocoAsAccountA.withdraw(amount)).to.be.revertedWithoutReason(); }); it('Should not withdraw tokens with insufficient balance', async () => { - await rlcInstanceAsAccountA - .approve(iexecPoco.address, standardAmount) - .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(standardAmount).then((tx) => tx.wait()); + await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(amount).then((tx) => tx.wait()); - await expect( - iexecPocoAsAccountA.withdraw(standardAmount.mul(2)), - ).to.be.revertedWithoutReason(); + await expect(iexecPocoAsAccountA.withdraw(amount.mul(2))).to.be.revertedWithoutReason(); }); }); describe('Withdraw to', () => { it('Should withdraw another address', async () => { - await rlcInstanceAsAccountA - .approve(iexecPoco.address, standardAmount) - .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(standardAmount).then((tx) => tx.wait()); + await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(amount).then((tx) => tx.wait()); const withdrawToParams = { - amount: standardAmount, + amount: amount, target: accountB.address, }; const withdrawToArgs = Object.values(withdrawToParams) as [BigNumber, string]; @@ -315,7 +291,7 @@ describe('IexecEscrowToken', () => { ) .to.emit(rlcInstance, 'Transfer') .withArgs(iexecPoco, withdrawToParams.target, withdrawToParams.amount) - .to.changeTokenBalances(iexecPoco, [accountA], [-standardAmount]) + .to.changeTokenBalances(iexecPoco, [accountA], [-amount]) .to.emit(iexecPoco, 'Transfer') .withArgs(accountA.address, AddressZero, withdrawToParams.amount); }); @@ -337,27 +313,25 @@ describe('IexecEscrowToken', () => { }); it('Should not withdraw To tokens with empty balance', async () => { await expect( - iexecPocoAsAccountA.withdrawTo(standardAmount, accountB.address), + iexecPocoAsAccountA.withdrawTo(amount, accountB.address), ).to.be.revertedWithoutReason(); }); it('Should not withdraw To tokens with insufficient balance', async () => { - await rlcInstanceAsAccountA - .approve(iexecPoco.address, standardAmount) - .then((tx) => tx.wait()); - await iexecPocoAsAccountA.deposit(standardAmount).then((tx) => tx.wait()); + await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); + await iexecPocoAsAccountA.deposit(amount).then((tx) => tx.wait()); await expect( - iexecPocoAsAccountA.withdrawTo(standardAmount.mul(2), accountB.address), + iexecPocoAsAccountA.withdrawTo(amount.mul(2), accountB.address), ).to.be.revertedWithoutReason(); }); }); describe('Recover', () => { it('Should recover from balance deviation', async () => { - await rlcInstance.connect(iexecAdmin).transfer(proxyAddress, standardAmount); // Simulate deviation + await rlcInstance.connect(iexecAdmin).transfer(proxyAddress, amount); // Simulate deviation const initTotalSupply = await iexecPoco.totalSupply(); - const expectedDelta = standardAmount; + const expectedDelta = amount; await expect(iexecPocoAsAdmin.recover()) .to.emit(iexecPoco, 'Transfer') @@ -382,13 +356,11 @@ describe('IexecEscrowToken', () => { describe('receiveApproval', () => { it('Should receiveApproval', async () => { - await rlcInstanceAsAccountA - .approve(iexecPoco.address, standardAmount) - .then((tx) => tx.wait()); + await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); const receiveApprovalParams = { sender: accountA.address, - amount: standardAmount, + amount: amount, token: rlcInstance.address, extraData: '0x', }; @@ -415,16 +387,16 @@ describe('IexecEscrowToken', () => { it('Should receiveApproval for another sender', async () => { await rlcInstance .connect(iexecAdmin) - .transfer(accountB.address, standardAmount) + .transfer(accountB.address, amount) .then((tx) => tx.wait()); await rlcInstance .connect(accountB) - .approve(iexecPoco.address, standardAmount) + .approve(iexecPoco.address, amount) .then((tx) => tx.wait()); const receiveApprovalParams = { sender: accountB.address, - amount: standardAmount, + amount: amount, token: rlcInstance.address, extraData: '0x', }; @@ -456,7 +428,7 @@ describe('IexecEscrowToken', () => { await expect( iexecPocoAsAccountA.receiveApproval( accountA.address, - standardAmount, + amount, ethers.Wallet.createRandom().address, '0x', ), @@ -465,9 +437,6 @@ describe('IexecEscrowToken', () => { }); }); -function AmountWithDecimals(amount: BigNumber) { - return ethers.utils.parseUnits(amount.toString(), 9); -} function getTotalAmount(amounts: BigNumber[]) { return amounts.reduce((a, b) => a.add(b), BigNumber.from(0)); } From 9ecbfaf689819304963aa706925be1988f08d8f6 Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 15:44:40 +0200 Subject: [PATCH 12/17] on withdraw swap burn & withdraw check --- .../IexecEscrow/IexecEscrowToken.test.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index eba381c32..42c3844ee 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -243,22 +243,22 @@ describe('IexecEscrowToken', () => { expect(await iexecPocoAsAccountA.callStatic.withdraw(amount)).to.be.true; await expect(iexecPocoAsAccountA.withdraw(amount)) - .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-amount, amount]) - .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, accountA.address, amount) .to.changeTokenBalances(iexecPoco, [accountA], [-amount]) .to.emit(iexecPoco, 'Transfer') - .withArgs(accountA.address, AddressZero, amount); + .withArgs(accountA.address, AddressZero, amount) + .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-amount, amount]) + .to.emit(rlcInstance, 'Transfer') + .withArgs(iexecPoco, accountA.address, amount); }); it('Should withdraw zero token', async () => { expect(await iexecPocoAsAccountA.callStatic.withdraw(0)).to.be.true; await expect(iexecPocoAsAccountA.withdraw(0)) - .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-0, 0]) - .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, accountA.address, 0) .to.changeTokenBalances(iexecPoco, [accountA], [-0]) .to.emit(iexecPoco, 'Transfer') - .withArgs(accountA.address, AddressZero, 0); + .withArgs(accountA.address, AddressZero, 0) + .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-0, 0]) + .to.emit(rlcInstance, 'Transfer') + .withArgs(iexecPoco, accountA.address, 0); }); it('Should not withdraw native tokens with empty balance', async () => { await expect(iexecPocoAsAccountA.withdraw(amount)).to.be.revertedWithoutReason(); @@ -284,16 +284,16 @@ describe('IexecEscrowToken', () => { expect(await iexecPocoAsAccountA.callStatic.withdrawTo(...withdrawToArgs)).to.be.true; await expect(iexecPocoAsAccountA.withdrawTo(...withdrawToArgs)) + .to.changeTokenBalances(iexecPoco, [accountA], [-amount]) + .to.emit(iexecPoco, 'Transfer') + .withArgs(accountA.address, AddressZero, withdrawToParams.amount) .to.changeTokenBalances( rlcInstance, [iexecPoco, withdrawToParams.target], [-withdrawToParams.amount, withdrawToParams.amount], ) .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, withdrawToParams.target, withdrawToParams.amount) - .to.changeTokenBalances(iexecPoco, [accountA], [-amount]) - .to.emit(iexecPoco, 'Transfer') - .withArgs(accountA.address, AddressZero, withdrawToParams.amount); + .withArgs(iexecPoco, withdrawToParams.target, withdrawToParams.amount); }); it('Should withdraw To with zero token', async () => { const withdrawToParams = { @@ -304,12 +304,12 @@ describe('IexecEscrowToken', () => { expect(await iexecPocoAsAccountA.callStatic.withdrawTo(...withdrawToArgs)).to.be.true; await expect(iexecPocoAsAccountA.withdrawTo(...withdrawToArgs)) - .to.changeTokenBalances(rlcInstance, [iexecPoco, accountB], [-0, 0]) - .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, withdrawToParams.target, 0) .to.changeTokenBalances(iexecPoco, [accountA], [-0]) .to.emit(iexecPoco, 'Transfer') - .withArgs(accountA.address, AddressZero, 0); + .withArgs(accountA.address, AddressZero, 0) + .to.changeTokenBalances(rlcInstance, [iexecPoco, accountB], [-0, 0]) + .to.emit(rlcInstance, 'Transfer') + .withArgs(iexecPoco, withdrawToParams.target, 0); }); it('Should not withdraw To tokens with empty balance', async () => { await expect( From 74517e154e629006f01b9837259dffbd05d45ebd Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 15:58:46 +0200 Subject: [PATCH 13/17] fixe iexecpoco addr --- test/byContract/IexecEscrow/IexecEscrowToken.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index 42c3844ee..4cb1f2597 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -248,7 +248,7 @@ describe('IexecEscrowToken', () => { .withArgs(accountA.address, AddressZero, amount) .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-amount, amount]) .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, accountA.address, amount); + .withArgs(iexecPoco.address, accountA.address, amount); }); it('Should withdraw zero token', async () => { expect(await iexecPocoAsAccountA.callStatic.withdraw(0)).to.be.true; @@ -258,7 +258,7 @@ describe('IexecEscrowToken', () => { .withArgs(accountA.address, AddressZero, 0) .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-0, 0]) .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, accountA.address, 0); + .withArgs(iexecPoco.address, accountA.address, 0); }); it('Should not withdraw native tokens with empty balance', async () => { await expect(iexecPocoAsAccountA.withdraw(amount)).to.be.revertedWithoutReason(); @@ -293,7 +293,7 @@ describe('IexecEscrowToken', () => { [-withdrawToParams.amount, withdrawToParams.amount], ) .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, withdrawToParams.target, withdrawToParams.amount); + .withArgs(iexecPoco.address, withdrawToParams.target, withdrawToParams.amount); }); it('Should withdraw To with zero token', async () => { const withdrawToParams = { @@ -309,7 +309,7 @@ describe('IexecEscrowToken', () => { .withArgs(accountA.address, AddressZero, 0) .to.changeTokenBalances(rlcInstance, [iexecPoco, accountB], [-0, 0]) .to.emit(rlcInstance, 'Transfer') - .withArgs(iexecPoco, withdrawToParams.target, 0); + .withArgs(iexecPoco.address, withdrawToParams.target, 0); }); it('Should not withdraw To tokens with empty balance', async () => { await expect( From 4f91a47f4087fb404718953064ef188b393de48d Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 16:06:52 +0200 Subject: [PATCH 14/17] several cleans --- .../IexecEscrow/IexecEscrowToken.test.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index 4cb1f2597..154c00636 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -198,7 +198,7 @@ describe('IexecEscrowToken', () => { depositForArrayParams.amounts[1], ); }); - it('Should not depositForArray with mismatched array lengths', async () => { + it('Should not deposit tokens for multiple accounts with mismatched array lengths', async () => { const depositForArrayParams = { amounts: [amount.mul(2), amount, amount.div(2)], targets: [accountB.address, accountC.address], @@ -216,7 +216,7 @@ describe('IexecEscrowToken', () => { iexecPocoAsAccountA.depositForArray(...depositForArrayArgs), ).to.be.revertedWith('invalid-array-length'); }); - it('Should not depositForArray with address zero in target', async () => { + it('Should not deposit tokens for multiple accounts with address zero in target', async () => { const depositForArrayParams = { amounts: [amount, amount.mul(2)], targets: [AddressZero, accountB.address], @@ -267,12 +267,12 @@ describe('IexecEscrowToken', () => { await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); await iexecPocoAsAccountA.deposit(amount).then((tx) => tx.wait()); - await expect(iexecPocoAsAccountA.withdraw(amount.mul(2))).to.be.revertedWithoutReason(); + await expect(iexecPocoAsAccountA.withdraw(amount.add(1))).to.be.revertedWithoutReason(); }); }); describe('Withdraw to', () => { - it('Should withdraw another address', async () => { + it('Should withdraw to another address', async () => { await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); await iexecPocoAsAccountA.deposit(amount).then((tx) => tx.wait()); @@ -295,7 +295,7 @@ describe('IexecEscrowToken', () => { .to.emit(rlcInstance, 'Transfer') .withArgs(iexecPoco.address, withdrawToParams.target, withdrawToParams.amount); }); - it('Should withdraw To with zero token', async () => { + it('Should withdraw to another address with zero token', async () => { const withdrawToParams = { amount: 0, target: accountB.address, @@ -311,17 +311,17 @@ describe('IexecEscrowToken', () => { .to.emit(rlcInstance, 'Transfer') .withArgs(iexecPoco.address, withdrawToParams.target, 0); }); - it('Should not withdraw To tokens with empty balance', async () => { + it('Should not withdraw to another address with empty balance', async () => { await expect( iexecPocoAsAccountA.withdrawTo(amount, accountB.address), ).to.be.revertedWithoutReason(); }); - it('Should not withdraw To tokens with insufficient balance', async () => { + it('Should not withdraw to another address with insufficient balance', async () => { await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); await iexecPocoAsAccountA.deposit(amount).then((tx) => tx.wait()); await expect( - iexecPocoAsAccountA.withdrawTo(amount.mul(2), accountB.address), + iexecPocoAsAccountA.withdrawTo(amount.add(1), accountB.address), ).to.be.revertedWithoutReason(); }); }); @@ -347,7 +347,7 @@ describe('IexecEscrowToken', () => { .withArgs(AddressZero, iexecAdmin.address, 0); expect(await iexecPoco.totalSupply()).to.equal(initialSupply); }); - it('Should not allow non-owner to recover', async () => { + it('Should not recover token when caller is not the owner', async () => { await expect(iexecPocoAsAccountA.recover()).to.be.revertedWith( 'Ownable: caller is not the owner', ); From 580677250ce6b433e82d747e7d40ea0f9b10c270 Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 16:21:42 +0200 Subject: [PATCH 15/17] add totalSupply checks on tests --- .../IexecEscrow/IexecEscrowToken.test.ts | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index 154c00636..ab0833866 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -75,6 +75,7 @@ describe('IexecEscrowToken', () => { describe('Deposit', () => { it('Should deposit tokens', async () => { await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); + const initialTotalSupply = await iexecPoco.totalSupply(); expect(await iexecPocoAsAccountA.callStatic.deposit(amount)).to.be.true; await expect(iexecPocoAsAccountA.deposit(amount)) @@ -84,6 +85,7 @@ describe('IexecEscrowToken', () => { .to.changeTokenBalances(iexecPoco, [accountA], [amount]) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, accountA.address, amount); + expect(await iexecPoco.totalSupply()).to.equal(initialTotalSupply.add(amount)); }); it('Should deposit 0 token', async () => { expect(await iexecPocoAsAccountA.callStatic.deposit(0)).to.be.true; @@ -123,6 +125,7 @@ describe('IexecEscrowToken', () => { describe('Deposit for', () => { it('Should deposit tokens for another account', async () => { await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); + const initialTotalSupply = await iexecPoco.totalSupply(); const depositForParams = { amount: amount, @@ -146,6 +149,9 @@ describe('IexecEscrowToken', () => { ) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, depositForParams.target, depositForParams.amount); + expect(await iexecPoco.totalSupply()).to.equal( + initialTotalSupply.add(depositForParams.amount), + ); }); it('Should not deposit tokens for zero address', async () => { await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); @@ -166,6 +172,7 @@ describe('IexecEscrowToken', () => { string[], ]; const depositTotalAmount = getTotalAmount(depositForArrayParams.amounts); + const initialTotalSupply = await iexecPoco.totalSupply(); await rlcInstanceAsAccountA .approve(iexecPoco.address, depositTotalAmount) @@ -197,6 +204,9 @@ describe('IexecEscrowToken', () => { depositForArrayParams.targets[1], depositForArrayParams.amounts[1], ); + expect(await iexecPoco.totalSupply()).to.equal( + initialTotalSupply.add(depositTotalAmount), + ); }); it('Should not deposit tokens for multiple accounts with mismatched array lengths', async () => { const depositForArrayParams = { @@ -240,6 +250,7 @@ describe('IexecEscrowToken', () => { it('Should withdraw tokens', async () => { await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); await iexecPocoAsAccountA.deposit(amount).then((tx) => tx.wait()); + const initialTotalSupply = await iexecPoco.totalSupply(); expect(await iexecPocoAsAccountA.callStatic.withdraw(amount)).to.be.true; await expect(iexecPocoAsAccountA.withdraw(amount)) @@ -249,6 +260,7 @@ describe('IexecEscrowToken', () => { .to.changeTokenBalances(rlcInstance, [iexecPoco, accountA], [-amount, amount]) .to.emit(rlcInstance, 'Transfer') .withArgs(iexecPoco.address, accountA.address, amount); + expect(await iexecPoco.totalSupply()).to.equal(initialTotalSupply.sub(amount)); }); it('Should withdraw zero token', async () => { expect(await iexecPocoAsAccountA.callStatic.withdraw(0)).to.be.true; @@ -275,6 +287,7 @@ describe('IexecEscrowToken', () => { it('Should withdraw to another address', async () => { await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); await iexecPocoAsAccountA.deposit(amount).then((tx) => tx.wait()); + const initialTotalSupply = await iexecPoco.totalSupply(); const withdrawToParams = { amount: amount, @@ -294,6 +307,9 @@ describe('IexecEscrowToken', () => { ) .to.emit(rlcInstance, 'Transfer') .withArgs(iexecPoco.address, withdrawToParams.target, withdrawToParams.amount); + expect(await iexecPoco.totalSupply()).to.equal( + initialTotalSupply.sub(withdrawToParams.amount), + ); }); it('Should withdraw to another address with zero token', async () => { const withdrawToParams = { @@ -357,10 +373,11 @@ describe('IexecEscrowToken', () => { describe('receiveApproval', () => { it('Should receiveApproval', async () => { await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); + const initialTotalSupply = await iexecPoco.totalSupply(); const receiveApprovalParams = { sender: accountA.address, - amount: amount, + amount, token: rlcInstance.address, extraData: '0x', }; @@ -383,6 +400,9 @@ describe('IexecEscrowToken', () => { .to.changeTokenBalances(iexecPoco, [accountA], [receiveApprovalParams.amount]) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, receiveApprovalParams.sender, receiveApprovalParams.amount); + expect(await iexecPoco.totalSupply()).to.equal( + initialTotalSupply.add(receiveApprovalParams.amount), + ); }); it('Should receiveApproval for another sender', async () => { await rlcInstance From ad319605cc7fb51e80ea94ae714e23e8ec7b64d5 Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 16:26:31 +0200 Subject: [PATCH 16/17] add changeTokenBalances checks on recover test --- test/byContract/IexecEscrow/IexecEscrowToken.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index ab0833866..e239f1bcb 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -350,15 +350,16 @@ describe('IexecEscrowToken', () => { const expectedDelta = amount; await expect(iexecPocoAsAdmin.recover()) + .to.changeTokenBalances(iexecPoco, [iexecAdmin], [expectedDelta]) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, iexecAdmin.address, expectedDelta); - expect(await iexecPoco.totalSupply()).to.equal(initTotalSupply.add(expectedDelta)); }); it('Should recover 0 token when balance matches total supply', async () => { const initialSupply = await iexecPoco.totalSupply(); await expect(iexecPocoAsAdmin.recover()) + .to.changeTokenBalances(iexecPoco, [iexecAdmin], [0]) .to.emit(iexecPoco, 'Transfer') .withArgs(AddressZero, iexecAdmin.address, 0); expect(await iexecPoco.totalSupply()).to.equal(initialSupply); From f1df2882a2fd915bebb697100e426421cc12ec5a Mon Sep 17 00:00:00 2001 From: Gabriel Fournier Date: Wed, 9 Oct 2024 17:44:37 +0200 Subject: [PATCH 17/17] remove receiveApproval section --- .../IexecEscrow/IexecEscrowToken.test.ts | 86 ------------------- 1 file changed, 86 deletions(-) diff --git a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts index e239f1bcb..be54dc31d 100644 --- a/test/byContract/IexecEscrow/IexecEscrowToken.test.ts +++ b/test/byContract/IexecEscrow/IexecEscrowToken.test.ts @@ -370,92 +370,6 @@ describe('IexecEscrowToken', () => { ); }); }); - - describe('receiveApproval', () => { - it('Should receiveApproval', async () => { - await rlcInstanceAsAccountA.approve(iexecPoco.address, amount).then((tx) => tx.wait()); - const initialTotalSupply = await iexecPoco.totalSupply(); - - const receiveApprovalParams = { - sender: accountA.address, - amount, - token: rlcInstance.address, - extraData: '0x', - }; - const receiveApprovalArgs = Object.values(receiveApprovalParams) as [ - string, - BigNumber, - string, - string, - ]; - expect(await iexecPocoAsAccountA.callStatic.receiveApproval(...receiveApprovalArgs)).to - .be.true; - await expect(iexecPocoAsAccountA.receiveApproval(...receiveApprovalArgs)) - .to.changeTokenBalances( - rlcInstance, - [accountA, iexecPoco], - [-receiveApprovalParams.amount, receiveApprovalParams.amount], - ) - .to.emit(rlcInstance, 'Transfer') - .withArgs(accountA.address, iexecPoco, receiveApprovalParams.amount) - .to.changeTokenBalances(iexecPoco, [accountA], [receiveApprovalParams.amount]) - .to.emit(iexecPoco, 'Transfer') - .withArgs(AddressZero, receiveApprovalParams.sender, receiveApprovalParams.amount); - expect(await iexecPoco.totalSupply()).to.equal( - initialTotalSupply.add(receiveApprovalParams.amount), - ); - }); - it('Should receiveApproval for another sender', async () => { - await rlcInstance - .connect(iexecAdmin) - .transfer(accountB.address, amount) - .then((tx) => tx.wait()); - await rlcInstance - .connect(accountB) - .approve(iexecPoco.address, amount) - .then((tx) => tx.wait()); - - const receiveApprovalParams = { - sender: accountB.address, - amount: amount, - token: rlcInstance.address, - extraData: '0x', - }; - const receiveApprovalArgs = Object.values(receiveApprovalParams) as [ - string, - BigNumber, - string, - string, - ]; - expect(await iexecPocoAsAccountA.callStatic.receiveApproval(...receiveApprovalArgs)).to - .be.true; - await expect(iexecPocoAsAccountA.receiveApproval(...receiveApprovalArgs)) - .to.changeTokenBalances( - rlcInstance, - [receiveApprovalParams.sender, iexecPoco], - [-receiveApprovalParams.amount, receiveApprovalParams.amount], - ) - .to.emit(rlcInstance, 'Transfer') - .withArgs(receiveApprovalParams.sender, iexecPoco, receiveApprovalParams.amount) - .to.changeTokenBalances( - iexecPoco, - [receiveApprovalParams.sender], - [receiveApprovalParams.amount], - ) - .to.emit(iexecPoco, 'Transfer') - .withArgs(AddressZero, receiveApprovalParams.sender, receiveApprovalParams.amount); - }); - it('Should not receiveApproval when the wrong token is used', async () => { - await expect( - iexecPocoAsAccountA.receiveApproval( - accountA.address, - amount, - ethers.Wallet.createRandom().address, - '0x', - ), - ).to.be.revertedWith('wrong-token'); - }); - }); }); function getTotalAmount(amounts: BigNumber[]) {