From 37078ca8e3ac587d88b83be2c97921154e404363 Mon Sep 17 00:00:00 2001 From: Ryan Sauge <71391932+rya-sge@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:49:54 +0100 Subject: [PATCH 1/2] Add TransferEngineModule, remove snapshotModule --- .../interfaces/engine/ITransferEngine.sol | 14 ++ contracts/libraries/Errors.sol | 2 + contracts/mocks/TransferEngineMock.sol | 167 ++++++++++++++++++ contracts/modules/CMTAT_BASE.sol | 16 +- .../internal/ERC20SnapshotModuleInternal.sol | 1 + .../internal/base/SnapshotModuleBase.sol | 3 +- .../extensions/TransferEngineModule.sol | 71 ++++++++ ...RC20SnapshotModuleCommonGetNextSnapshot.js | 38 ++-- .../ERC20SnapshotModuleCommonRescheduling.js | 80 ++++----- .../ERC20SnapshotModuleCommonScheduling.js | 76 ++++---- .../ERC20SnapshotModuleCommonUnschedule.js | 112 ++++++------ .../ERC20SnapshotModuleUtils.js | 12 +- .../ERC20SnapshotModuleMultiplePlannedTest.js | 16 +- ...C20SnapshotModuleOnePlannedSnapshotTest.js | 8 +- .../proxy/modules/ERC20SnapshotModule.test.js | 3 + .../modules/ERC20SnapshotModule.test.js | 3 + 16 files changed, 445 insertions(+), 177 deletions(-) create mode 100644 contracts/interfaces/engine/ITransferEngine.sol create mode 100644 contracts/mocks/TransferEngineMock.sol create mode 100644 contracts/modules/wrapper/extensions/TransferEngineModule.sol diff --git a/contracts/interfaces/engine/ITransferEngine.sol b/contracts/interfaces/engine/ITransferEngine.sol new file mode 100644 index 00000000..b78b17c6 --- /dev/null +++ b/contracts/interfaces/engine/ITransferEngine.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +/* +* @dev minimum interface to define a RuleEngine +*/ +interface ITransferEngine { + /** + * @dev Returns true if the operation is a success, and false otherwise. + */ + function operateOnTransfer(address from, address to, uint256 balanceFrom, uint256 balanceTo, uint256 totalSupply) external; + +} \ No newline at end of file diff --git a/contracts/libraries/Errors.sol b/contracts/libraries/Errors.sol index d5beb510..e9f72804 100644 --- a/contracts/libraries/Errors.sol +++ b/contracts/libraries/Errors.sol @@ -61,6 +61,8 @@ library Errors { error CMTAT_AuthorizationModule_InvalidAuthorization(); error CMTAT_AuthorizationModule_AuthorizationEngineAlreadySet(); + error CMTAT_TransferEngineModule_TransferEngineAlreadySet(); + // DocumentModule error CMTAT_DocumentModule_SameValue(); diff --git a/contracts/mocks/TransferEngineMock.sol b/contracts/mocks/TransferEngineMock.sol new file mode 100644 index 00000000..b987cb2d --- /dev/null +++ b/contracts/mocks/TransferEngineMock.sol @@ -0,0 +1,167 @@ +//SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; +import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; +import "../modules/internal/base/SnapshotModuleBase.sol"; +import "../interfaces/ICMTATSnapshot.sol"; +import "../interfaces/engine/ITransferEngine.sol"; +/* +* @title a RuleEngine mock for testing, not suitable for production +*/ +contract TransferEngineMock is SnapshotModuleBase, AccessControlUpgradeable, ITransferEngine { + ERC20Upgradeable erc20; + constructor(ERC20Upgradeable erc20_, address admin) { + erc20 = erc20_; + _grantRole(DEFAULT_ADMIN_ROLE, admin); + } + /* ============ State Variables ============ */ + bytes32 public constant SNAPSHOOTER_ROLE = keccak256("SNAPSHOOTER_ROLE"); + + /** + * @dev Returns `true` if `account` has been granted `role`. + */ + function hasRole( + bytes32 role, + address account + ) public view virtual override(AccessControlUpgradeable) returns (bool) { + // The Default Admin has all roles + if (AccessControlUpgradeable.hasRole(DEFAULT_ADMIN_ROLE, account)) { + return true; + } + return AccessControlUpgradeable.hasRole(role, account); + } + /** + * @dev Update balance and/or total supply snapshots before the values are modified. This is implemented + * in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. + */ + function operateOnTransfer(address from, address to, uint256 balanceFrom, uint256 balanceTo, uint256 totalSupply) public override { + _setCurrentSnapshot(); + if (from != address(0)) { + // for both burn and transfer + _updateAccountSnapshot(from, balanceFrom); + if (to != address(0)) { + // transfer + _updateAccountSnapshot(to, balanceTo); + } else { + // burn + _updateTotalSupplySnapshot(totalSupply); + } + } else { + // mint + _updateAccountSnapshot(to, balanceTo); + _updateTotalSupplySnapshot(totalSupply); + } + } + + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /** + * @notice Return snapshotBalanceOf and snapshotTotalSupply to avoid multiple calls + * @return ownerBalance , totalSupply - see snapshotBalanceOf and snapshotTotalSupply + */ + function snapshotInfo(uint256 time, address owner) public view returns (uint256 ownerBalance, uint256 totalSupply) { + ownerBalance = snapshotBalanceOf(time, owner); + totalSupply = snapshotTotalSupply(time); + } + + /** + * @notice Return snapshotBalanceOf for each address in the array and the total supply + * @return ownerBalances array with the balance of each address, the total supply + */ + function snapshotInfoBatch(uint256 time, address[] calldata addresses) public view returns (uint256[] memory ownerBalances, uint256 totalSupply) { + ownerBalances = new uint256[](addresses.length); + for(uint256 i = 0; i < addresses.length; ++i){ + ownerBalances[i] = snapshotBalanceOf(time, addresses[i]); + } + totalSupply = snapshotTotalSupply(time); + } + + /** + * @notice Return snapshotBalanceOf for each address in the array and the total supply + * @return ownerBalances array with the balance of each address, the total supply + */ + function snapshotInfoBatch(uint256[] calldata times, address[] calldata addresses) public view returns (uint256[][] memory ownerBalances, uint256[] memory totalSupply) { + ownerBalances = new uint256[][](times.length); + totalSupply = new uint256[](times.length); + for(uint256 iT = 0; iT < times.length; ++iT){ + (ownerBalances[iT], totalSupply[iT]) = snapshotInfoBatch(times[iT],addresses); + } + } + + /** + * @notice Return the number of tokens owned by the given owner at the time when the snapshot with the given time was created. + * @return value stored in the snapshot, or the actual balance if no snapshot + */ + function snapshotBalanceOf( + uint256 time, + address owner + ) public view returns (uint256) { + return _snapshotBalanceOf(time, owner, erc20.balanceOf(owner)); + } + + /** + * @dev See {OpenZeppelin - ERC20Snapshot} + * Retrieves the total supply at the specified time. + * @return value stored in the snapshot, or the actual totalSupply if no snapshot + */ + function snapshotTotalSupply(uint256 time) public view returns (uint256) { + return _snapshotTotalSupply(time, erc20.totalSupply()); + } + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /** + * @notice + * Schedule a snapshot at the given time specified as a number of seconds since epoch. + * The time cannot be before the time of the latest scheduled, but not yet created snapshot. + */ + function scheduleSnapshot(uint256 time) public onlyRole(SNAPSHOOTER_ROLE) { + _scheduleSnapshot(time); + } + + /** + * @notice + * Schedule a snapshot at the given time specified as a number of seconds since epoch. + * The time cannot be before the time of the latest scheduled, but not yet created snapshot. + */ + function scheduleSnapshotNotOptimized( + uint256 time + ) public onlyRole(SNAPSHOOTER_ROLE) { + _scheduleSnapshotNotOptimized(time); + } + + /** + * @notice + * Reschedule the scheduled snapshot, but not yet created snapshot with the given oldTime to be created at the given newTime specified as a number of seconds since epoch. + * The newTime cannot be before the time of the previous scheduled, but not yet created snapshot, or after the time fo the next scheduled snapshot. + */ + function rescheduleSnapshot( + uint256 oldTime, + uint256 newTime + ) public onlyRole(SNAPSHOOTER_ROLE) { + _rescheduleSnapshot(oldTime, newTime); + } + + /** + * @notice + * Cancel creation of the scheduled snapshot, but not yet created snapshot with the given time. + * There should not be any other snapshots scheduled after this one. + */ + function unscheduleLastSnapshot( + uint256 time + ) public onlyRole(SNAPSHOOTER_ROLE) { + _unscheduleLastSnapshot(time); + } + + /** + * @notice + * Cancel creation of the scheduled snapshot, but not yet created snapshot with the given time. + */ + function unscheduleSnapshotNotOptimized( + uint256 time + ) public onlyRole(SNAPSHOOTER_ROLE) { + _unscheduleSnapshotNotOptimized(time); + } +} diff --git a/contracts/modules/CMTAT_BASE.sol b/contracts/modules/CMTAT_BASE.sol index dfe445cf..63b91c27 100644 --- a/contracts/modules/CMTAT_BASE.sol +++ b/contracts/modules/CMTAT_BASE.sol @@ -22,13 +22,16 @@ import "./wrapper/controllers/ValidationModule.sol"; import "./wrapper/extensions/MetaTxModule.sol"; import "./wrapper/extensions/DebtModule.sol"; import "./wrapper/extensions/DocumentModule.sol"; +import "./wrapper/extensions/TransferEngineModule.sol"; import "./security/AuthorizationModule.sol"; import "../interfaces/ICMTATConstructor.sol"; +import "../interfaces/engine/ITransferEngine.sol"; import "../libraries/Errors.sol"; abstract contract CMTAT_BASE is Initializable, ContextUpgradeable, + TransferEngineModule, // Core BaseModule, PauseModule, @@ -39,7 +42,7 @@ abstract contract CMTAT_BASE is ERC20BaseModule, // Extension MetaTxModule, - ERC20SnapshotModule, + //ERC20SnapshotModule, DebtModule, DocumentModule { @@ -96,8 +99,8 @@ abstract contract CMTAT_BASE is SnapshotModule: Add these two calls in case you add the SnapshotModule */ - __SnapshotModuleBase_init_unchained(); - __ERC20Snapshot_init_unchained(); + //__SnapshotModuleBase_init_unchained(); + //__ERC20Snapshot_init_unchained(); __Validation_init_unchained(engines_ .ruleEngine); @@ -117,7 +120,7 @@ abstract contract CMTAT_BASE is SnapshotModule: Add this call in case you add the SnapshotModule */ - __ERC20SnasphotModule_init_unchained(); + //__ERC20SnasphotModule_init_unchained(); __DocumentModule_init_unchained(engines_ .documentEngine); __DebtModule_init_unchained(engines_ .debtEngine); @@ -199,7 +202,10 @@ abstract contract CMTAT_BASE is Add this in case you add the SnapshotModule We call the SnapshotModule only if the transfer is valid */ - ERC20SnapshotModuleInternal._snapshotUpdate(from, to); + //ERC20SnapshotModuleInternal._snapshotUpdate(from, to); + if(address(transferEngine()) != address(0)){ + transferEngine().operateOnTransfer(from, to, balanceOf(from), balanceOf(to), totalSupply()); + } ERC20Upgradeable._update(from, to, amount); } /*////////////////////////////////////////////////////////////// diff --git a/contracts/modules/internal/ERC20SnapshotModuleInternal.sol b/contracts/modules/internal/ERC20SnapshotModuleInternal.sol index e7db352e..1da61700 100644 --- a/contracts/modules/internal/ERC20SnapshotModuleInternal.sol +++ b/contracts/modules/internal/ERC20SnapshotModuleInternal.sol @@ -17,6 +17,7 @@ import "../../interfaces/ICMTATSnapshot.sol"; abstract contract ERC20SnapshotModuleInternal is ICMTATSnapshot, SnapshotModuleBase, ERC20Upgradeable { using Arrays for uint256[]; + /* ============ Initializer Function ============ */ function __ERC20Snapshot_init_unchained() internal onlyInitializing { // Nothing to do diff --git a/contracts/modules/internal/base/SnapshotModuleBase.sol b/contracts/modules/internal/base/SnapshotModuleBase.sol index 09b6b70e..96da36b5 100644 --- a/contracts/modules/internal/base/SnapshotModuleBase.sol +++ b/contracts/modules/internal/base/SnapshotModuleBase.sol @@ -398,7 +398,8 @@ abstract contract SnapshotModuleBase is Initializable { } /* ============ Require balance and total supply ============ */ - /** + + /** * @dev See {OpenZeppelin - ERC20Snapshot} */ function _updateAccountSnapshot(address account, uint256 accountBalance) internal { diff --git a/contracts/modules/wrapper/extensions/TransferEngineModule.sol b/contracts/modules/wrapper/extensions/TransferEngineModule.sol new file mode 100644 index 00000000..753bd2d8 --- /dev/null +++ b/contracts/modules/wrapper/extensions/TransferEngineModule.sol @@ -0,0 +1,71 @@ +//SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import "../../security/AuthorizationModule.sol"; +import "../../../libraries/Errors.sol"; +import "../../../interfaces/engine/ITransferEngine.sol"; + +abstract contract TransferEngineModule is AuthorizationModule { + /* ============ Events ============ */ + /** + * @dev Emitted when a rule engine is set. + */ + event TransferEngine(ITransferEngine indexed newTransferEngine); + /* ============ ERC-7201 ============ */ + // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.TransferModule")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant TransferEngineModuleStorageLocation = 0x59b7f077fa4ad020f9053fd2197fef0113b19f0b11dcfe516e88cbc0e9226d00; + /* ==== ERC-7201 State Variables === */ + struct TransferEngineModuleStorage { + ITransferEngine _transferEngine; + } + /* ============ Initializer Function ============ */ + /** + * @dev + * + * - The grant to the admin role is done by AccessControlDefaultAdminRules + * - The control of the zero address is done by AccessControlDefaultAdminRules + * + */ + function __TransferModule_init_unchained(ITransferEngine TransferEngine_) + internal onlyInitializing { + if (address(TransferEngine_) != address (0)) { + TransferEngineModuleStorage storage $ = _getTransferEngineModuleStorage(); + $._transferEngine = TransferEngine_; + emit TransferEngine(TransferEngine_); + } + } + + + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + function transferEngine() public view virtual returns (ITransferEngine) { + TransferEngineModuleStorage storage $ = _getTransferEngineModuleStorage(); + return $._transferEngine; + } + + /* + * @notice set an TransferEngine if not already set + * @dev once an TransferEngine is set, it is not possible to unset it + */ + function setTransferEngine( + ITransferEngine transferEngine_ + ) external onlyRole(DEFAULT_ADMIN_ROLE) { + TransferEngineModuleStorage storage $ = _getTransferEngineModuleStorage(); + $._transferEngine = transferEngine_; + emit TransferEngine(transferEngine_); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL/PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + /* ============ ERC-7201 ============ */ + function _getTransferEngineModuleStorage() private pure returns (TransferEngineModuleStorage storage $) { + assembly { + $.slot := TransferEngineModuleStorageLocation + } + } +} diff --git a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonGetNextSnapshot.js b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonGetNextSnapshot.js index 09d063de..165b27e2 100644 --- a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonGetNextSnapshot.js +++ b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonGetNextSnapshot.js @@ -16,13 +16,13 @@ function ERC20SnapshotModuleCommonGetNextSnapshot () { this.snapshotTime3 = this.currentTime + time.duration.seconds(20) this.snapshotTime4 = this.currentTime + time.duration.seconds(25) this.snapshotTime5 = this.currentTime + time.duration.seconds(30) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime1) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime2) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime3) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime4) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime5) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime1) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime2) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime3) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime4) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime5) // Act - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() // Assert expect(snapshots.length).to.equal(5) checkArraySnapshot(snapshots, [ @@ -33,7 +33,7 @@ function ERC20SnapshotModuleCommonGetNextSnapshot () { this.snapshotTime5 ]) // Act - const AllSnapshots = await this.cmtat.getAllSnapshots() + const AllSnapshots = await this.transferEngineMock.getAllSnapshots() // Assert checkArraySnapshot(AllSnapshots, [ this.snapshotTime1, @@ -47,32 +47,32 @@ function ERC20SnapshotModuleCommonGetNextSnapshot () { // it('testCanReturnEmptyArrayIfAllSnapshotsAreInThePast', async function () { // Arrange - this.snapshotTime1 = this.currentTime + time.duration.seconds(2) - this.snapshotTime2 = this.currentTime + time.duration.seconds(3) - this.snapshotTime3 = this.currentTime + time.duration.seconds(4) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime1) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime2) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime3) + this.snapshotTime1 = this.currentTime + time.duration.seconds(3) + this.snapshotTime2 = this.currentTime + time.duration.seconds(4) + this.snapshotTime3 = this.currentTime + time.duration.seconds(5) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime1) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime2) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime3) // We jump into the future await time.increase(4) // Act - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() // Assert expect(snapshots.length).to.equal(0) }) it('testCanReturnOnlyFutureSnapshotsIfSomeSnapshotsAreInThePast', async function () { // Arrange - this.snapshotTime1 = this.currentTime + time.duration.seconds(2) + this.snapshotTime1 = this.currentTime + time.duration.seconds(3) this.snapshotTime2 = this.currentTime + time.duration.seconds(20) this.snapshotTime3 = this.currentTime + time.duration.seconds(300) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime1) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime1) // We jump into the future await time.increase(3) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime2) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime3) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime2) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime3) // Act - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() // Assert expect(snapshots.length).to.equal(2) checkArraySnapshot(snapshots, [this.snapshotTime2, this.snapshotTime3]) diff --git a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonRescheduling.js b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonRescheduling.js index 87b13c09..1cb26968 100644 --- a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonRescheduling.js +++ b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonRescheduling.js @@ -11,17 +11,17 @@ function ERC20SnapshotModuleCommonRescheduling () { this.currentTime = await time.latest() this.snapshotTime = this.currentTime + time.duration.seconds(60) this.newSnapshotTime = this.currentTime + time.duration.seconds(200) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime) }) it('can reschedule a snapshot with the snapshoter role and emits a SnapshotSchedule event', async function () { - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .rescheduleSnapshot(this.snapshotTime, this.newSnapshotTime) await expect(this.logs) - .to.emit(this.cmtat, 'SnapshotSchedule') + .to.emit(this.transferEngineMock, 'SnapshotSchedule') .withArgs(this.snapshotTime, this.newSnapshotTime) - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(1) expect(snapshots[0]).to.equal(this.newSnapshotTime) }) @@ -33,18 +33,18 @@ function ERC20SnapshotModuleCommonRescheduling () { this.snapshotTime + time.duration.seconds(40) const FIRST_SNAPSHOT = this.snapshotTime + time.duration.seconds(60) const SECOND_SNAPSHOT = this.snapshotTime + time.duration.seconds(90) - await this.cmtat + await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(SNAPSHOT_MIDDLE_OLD_TIME) - await this.cmtat.connect(this.admin).scheduleSnapshot(FIRST_SNAPSHOT) - await this.cmtat.connect(this.admin).scheduleSnapshot(SECOND_SNAPSHOT) - this.logs = await this.cmtat + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(FIRST_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(SECOND_SNAPSHOT) + this.logs = await this.transferEngineMock .connect(this.admin) .rescheduleSnapshot(SNAPSHOT_MIDDLE_OLD_TIME, SNAPSHOT_MIDDLE_NEW_TIME) await expect(this.logs) - .to.emit(this.cmtat, 'SnapshotSchedule') + .to.emit(this.transferEngineMock, 'SnapshotSchedule') .withArgs(SNAPSHOT_MIDDLE_OLD_TIME, SNAPSHOT_MIDDLE_NEW_TIME) - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(4) checkArraySnapshot(snapshots, [ this.snapshotTime, @@ -61,14 +61,14 @@ function ERC20SnapshotModuleCommonRescheduling () { this.snapshotTime + time.duration.seconds(61) const FIRST_SNAPSHOT = this.snapshotTime + time.duration.seconds(60) const SECOND_SNAPSHOT = this.snapshotTime + time.duration.seconds(90) - await this.cmtat + await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(SNAPSHOT_MIDDLE_OLD_TIME) - await this.cmtat.connect(this.admin).scheduleSnapshot(FIRST_SNAPSHOT) - await this.cmtat.connect(this.admin).scheduleSnapshot(SECOND_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(FIRST_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(SECOND_SNAPSHOT) // Act await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .rescheduleSnapshot( SNAPSHOT_MIDDLE_OLD_TIME, @@ -76,12 +76,12 @@ function ERC20SnapshotModuleCommonRescheduling () { ) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotTimestampAfterNextSnapshot' ) .withArgs(SNAPSHOT_MIDDLE_NEW_TIME, FIRST_SNAPSHOT) // Assert - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(4) checkArraySnapshot(snapshots, [ this.snapshotTime, @@ -99,14 +99,14 @@ function ERC20SnapshotModuleCommonRescheduling () { const FIRST_SNAPSHOT = this.snapshotTime + time.duration.seconds(60) const SECOND_SNAPSHOT = this.snapshotTime + time.duration.seconds(90) - await this.cmtat + await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(SNAPSHOT_MIDDLE_OLD_TIME) - await this.cmtat.connect(this.admin).scheduleSnapshot(FIRST_SNAPSHOT) - await this.cmtat.connect(this.admin).scheduleSnapshot(SECOND_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(FIRST_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(SECOND_SNAPSHOT) // Act await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .rescheduleSnapshot( SNAPSHOT_MIDDLE_OLD_TIME, @@ -114,13 +114,13 @@ function ERC20SnapshotModuleCommonRescheduling () { ) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotTimestampBeforePreviousSnapshot' ) .withArgs(SNAPSHOT_MIDDLE_NEW_TIME, this.snapshotTime) // Assert - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(4) checkArraySnapshot(snapshots, [ this.snapshotTime, @@ -133,12 +133,12 @@ function ERC20SnapshotModuleCommonRescheduling () { it('reverts when calling from non-owner', async function () { // Act await expect( - this.cmtat + this.transferEngineMock .connect(this.address1) .rescheduleSnapshot(this.snapshotTime, this.newSnapshotTime) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'AccessControlUnauthorizedAccount' ) .withArgs(this.address1.address, SNAPSHOOTER_ROLE) @@ -147,12 +147,12 @@ function ERC20SnapshotModuleCommonRescheduling () { it('reverts when trying to reschedule a snapshot in the past', async function () { const NEW_TIME = this.snapshotTime - time.duration.seconds(60) await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .rescheduleSnapshot(this.snapshotTime, NEW_TIME) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotScheduledInThePast' ) .withArgs(NEW_TIME, (await time.latest()) + time.duration.seconds(1)) @@ -160,13 +160,13 @@ function ERC20SnapshotModuleCommonRescheduling () { it('reverts when trying to reschedule a snapshot to a snapshot time already existing', async function () { const NEW_TIME = this.snapshotTime + time.duration.seconds(60) - await this.cmtat.connect(this.admin).scheduleSnapshot(NEW_TIME) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(NEW_TIME) await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .rescheduleSnapshot(this.snapshotTime, NEW_TIME) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotAlreadyExists' ) }) @@ -175,7 +175,7 @@ function ERC20SnapshotModuleCommonRescheduling () { /* Arrange: we schedule the snapshot at a new time */ - await this.cmtat + await this.transferEngineMock .connect(this.admin) .rescheduleSnapshot(this.snapshotTime, this.newSnapshotTime) @@ -184,15 +184,15 @@ function ERC20SnapshotModuleCommonRescheduling () { We try to reschedule the previous snapshot */ await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .rescheduleSnapshot(this.snapshotTime, this.newSnapshotTime) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotNotFound' ) // Assert - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(1) expect(snapshots[0]).to.equal(this.newSnapshotTime) }) @@ -200,25 +200,25 @@ function ERC20SnapshotModuleCommonRescheduling () { it('reverts when snapshot is not found', async function () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(90) await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .rescheduleSnapshot(SNAPSHOT_TIME, this.newSnapshotTime) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotNotFound' ) }) it('reverts if no snapshot exits', async function () { - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .unscheduleLastSnapshot(this.snapshotTime) await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .rescheduleSnapshot(this.snapshotTime, this.newSnapshotTime) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_NoSnapshotScheduled' ) }) @@ -226,11 +226,11 @@ function ERC20SnapshotModuleCommonRescheduling () { it('reverts when snapshot has been processed', async function () { const SNAPSHOT_TIME = this.currentTime - time.duration.seconds(60) await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .rescheduleSnapshot(SNAPSHOT_TIME, this.newSnapshotTime) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotAlreadyDone' ) }) diff --git a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonScheduling.js b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonScheduling.js index 50ffd7b3..8a5d2ced 100644 --- a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonScheduling.js +++ b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonScheduling.js @@ -13,27 +13,27 @@ function ERC20SnapshotModuleCommonScheduling () { it('can schedule a snapshot with the snapshoter role', async function () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(60) // Act - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(SNAPSHOT_TIME) // Assert - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(1) expect(snapshots[0]).to.equal(SNAPSHOT_TIME) // emits a SnapshotSchedule event await expect(this.logs) - .to.emit(this.cmtat, 'SnapshotSchedule') + .to.emit(this.transferEngineMock, 'SnapshotSchedule') .withArgs('0', SNAPSHOT_TIME) }) it('reverts when calling from non-admin', async function () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(60) await expect( - this.cmtat.connect(this.address1).scheduleSnapshot(SNAPSHOT_TIME) + this.transferEngineMock.connect(this.address1).scheduleSnapshot(SNAPSHOT_TIME) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'AccessControlUnauthorizedAccount' ) .withArgs(this.address1.address, SNAPSHOOTER_ROLE) @@ -42,16 +42,16 @@ function ERC20SnapshotModuleCommonScheduling () { it('reverts when trying to schedule a snapshot before the last snapshot', async function () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(120) // Act - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(SNAPSHOT_TIME) const SNAPSHOT_TIME_INVALID = SNAPSHOT_TIME - time.duration.seconds(60) await expect( - this.cmtat.connect(this.admin).scheduleSnapshot(SNAPSHOT_TIME_INVALID) + this.transferEngineMock.connect(this.admin).scheduleSnapshot(SNAPSHOT_TIME_INVALID) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotTimestampBeforeLastSnapshot' ) .withArgs(SNAPSHOT_TIME_INVALID, SNAPSHOT_TIME) @@ -60,10 +60,10 @@ function ERC20SnapshotModuleCommonScheduling () { it('reverts when trying to schedule a snapshot in the past', async function () { const SNAPSHOT_TIME = this.currentTime - time.duration.seconds(60) await expect( - this.cmtat.connect(this.admin).scheduleSnapshot(SNAPSHOT_TIME) + this.transferEngineMock.connect(this.admin).scheduleSnapshot(SNAPSHOT_TIME) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotScheduledInThePast' ) .withArgs( @@ -75,16 +75,16 @@ function ERC20SnapshotModuleCommonScheduling () { it('reverts when trying to schedule a snapshot with the same time twice', async function () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(60) // Arrange - await this.cmtat.connect(this.admin).scheduleSnapshot(SNAPSHOT_TIME) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(SNAPSHOT_TIME) // Act await expect( - this.cmtat.connect(this.admin).scheduleSnapshot(SNAPSHOT_TIME) + this.transferEngineMock.connect(this.admin).scheduleSnapshot(SNAPSHOT_TIME) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotAlreadyExists' ) // Assert - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(1) expect(snapshots[0]).to.equal(SNAPSHOT_TIME) }) @@ -99,20 +99,20 @@ function ERC20SnapshotModuleCommonScheduling () { const SECOND_SNAPSHOT = this.currentTime + time.duration.seconds(200) const THIRD_SNAPSHOT = this.currentTime + time.duration.seconds(15) // Arrange - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(FIRST_SNAPSHOT) - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(SECOND_SNAPSHOT) // Act // We schedule the snapshot at the first place this.snapshotTime = this.currentTime + time.duration.seconds(10) - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshotNotOptimized(THIRD_SNAPSHOT) // Assert - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(3) expect(snapshots[0]).to.equal(THIRD_SNAPSHOT) }) @@ -126,19 +126,19 @@ function ERC20SnapshotModuleCommonScheduling () { const FIVE_SNAPSHOT = this.currentTime + time.duration.seconds(30) // Third position const RANDOM_SNAPSHOT = this.currentTime + time.duration.seconds(17) - await this.cmtat.connect(this.admin).scheduleSnapshot(FIRST_SNAPSHOT) - await this.cmtat.connect(this.admin).scheduleSnapshot(SECOND_SNAPSHOT) - await this.cmtat.connect(this.admin).scheduleSnapshot(THIRD_SNAPSHOT) - await this.cmtat.connect(this.admin).scheduleSnapshot(FOUR_SNAPSHOT) - await this.cmtat.connect(this.admin).scheduleSnapshot(FIVE_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(FIRST_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(SECOND_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(THIRD_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(FOUR_SNAPSHOT) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(FIVE_SNAPSHOT) // Act - await this.cmtat + await this.transferEngineMock .connect(this.admin) .scheduleSnapshotNotOptimized(RANDOM_SNAPSHOT) // Assert - let snapshots = await this.cmtat.getNextSnapshots() + let snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(6) - snapshots = await this.cmtat.getNextSnapshots() + snapshots = await this.transferEngineMock.getNextSnapshots() checkArraySnapshot(snapshots, [ FIRST_SNAPSHOT, SECOND_SNAPSHOT, @@ -151,27 +151,27 @@ function ERC20SnapshotModuleCommonScheduling () { it('schedule a snapshot, which will be in the last position', async function () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(60) - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshotNotOptimized(SNAPSHOT_TIME) - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(1) // emits a SnapshotSchedule event await expect(this.logs) - .to.emit(this.cmtat, 'SnapshotSchedule') + .to.emit(this.transferEngineMock, 'SnapshotSchedule') .withArgs('0', SNAPSHOT_TIME) }) it('reverts when calling from non-admin', async function () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(60) await expect( - this.cmtat + this.transferEngineMock .connect(this.address1) .scheduleSnapshotNotOptimized(SNAPSHOT_TIME) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'AccessControlUnauthorizedAccount' ) .withArgs(this.address1.address, SNAPSHOOTER_ROLE) @@ -180,12 +180,12 @@ function ERC20SnapshotModuleCommonScheduling () { it('reverts when trying to schedule a snapshot in the past', async function () { const SNAPSHOT_TIME = this.currentTime - time.duration.seconds(60) await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .scheduleSnapshotNotOptimized(SNAPSHOT_TIME) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotScheduledInThePast' ) .withArgs( @@ -198,23 +198,23 @@ function ERC20SnapshotModuleCommonScheduling () { const FIRST_SNAPSHOT = this.currentTime + time.duration.seconds(10) const SECOND_SNAPSHOT = this.currentTime + time.duration.seconds(100) // Arrange - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(FIRST_SNAPSHOT) - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(SECOND_SNAPSHOT) // Act await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .scheduleSnapshotNotOptimized(FIRST_SNAPSHOT) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotAlreadyExists' ) // Assert - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(2) checkArraySnapshot(snapshots, [FIRST_SNAPSHOT, SECOND_SNAPSHOT]) }) diff --git a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonUnschedule.js b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonUnschedule.js index 4f47f2f9..e1e1a023 100644 --- a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonUnschedule.js +++ b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleCommonUnschedule.js @@ -19,30 +19,30 @@ function ERC20SnapshotModuleCommonUnschedule () { it('can remove a snapshot as admin', async function () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(60) - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(SNAPSHOT_TIME) - let snapshots = await this.cmtat.getNextSnapshots() + let snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(1) expect(snapshots[0]).to.equal(SNAPSHOT_TIME) - await this.cmtat + await this.transferEngineMock .connect(this.admin) .unscheduleSnapshotNotOptimized(SNAPSHOT_TIME) - snapshots = await this.cmtat.getNextSnapshots() + snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(0) }) it('can remove a random snapshot with the snapshoter role', async function () { - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime1) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime2) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime3) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime4) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime5) - let snapshots = await this.cmtat.getNextSnapshots() + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime1) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime2) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime3) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime4) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime5) + let snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(5) - await this.cmtat + await this.transferEngineMock .connect(this.admin) .unscheduleSnapshotNotOptimized(this.snapshotTime3) - snapshots = await this.cmtat.getNextSnapshots() + snapshots = await this.transferEngineMock.getNextSnapshots() checkArraySnapshot(snapshots, [ this.snapshotTime1, this.snapshotTime2, @@ -53,41 +53,41 @@ function ERC20SnapshotModuleCommonUnschedule () { }) it('Revert if no snapshot', async function () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(60) - let snapshots = await this.cmtat.getNextSnapshots() + let snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(0) await expect( - this.cmtat + this.transferEngineMock .connect(this.admin) .unscheduleSnapshotNotOptimized(SNAPSHOT_TIME) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotNotFound' ) - snapshots = await this.cmtat.getNextSnapshots() + snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(0) }) it('testCannotUnscheduleASnapshotInThePast', async function () { const SNAPSHOT_TIME = this.currentTime - time.duration.seconds(60) await expect( - this.cmtat.connect(this.admin).unscheduleLastSnapshot(SNAPSHOT_TIME) + this.transferEngineMock.connect(this.admin).unscheduleLastSnapshot(SNAPSHOT_TIME) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotAlreadyDone' ) }) it('can unschedule a snaphot in a random place', async function () { const RANDOM_SNAPSHOT = this.currentTime + time.duration.seconds(17) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime1) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime2) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime3) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime4) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime5) - await this.cmtat + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime1) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime2) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime3) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime4) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime5) + await this.transferEngineMock .connect(this.admin) .scheduleSnapshotNotOptimized(RANDOM_SNAPSHOT) - let snapshots = await this.cmtat.getNextSnapshots() + let snapshots = await this.transferEngineMock.getNextSnapshots() checkArraySnapshot(snapshots, [ this.snapshotTime1, this.snapshotTime2, @@ -97,12 +97,12 @@ function ERC20SnapshotModuleCommonUnschedule () { this.snapshotTime5 ]) expect(snapshots.length).to.equal(6) - await this.cmtat + await this.transferEngineMock .connect(this.admin) .unscheduleSnapshotNotOptimized(RANDOM_SNAPSHOT) - snapshots = await this.cmtat.getNextSnapshots() + snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(5) - snapshots = await this.cmtat.getNextSnapshots() + snapshots = await this.transferEngineMock.getNextSnapshots() checkArraySnapshot(snapshots, [ this.snapshotTime1, this.snapshotTime2, @@ -113,20 +113,20 @@ function ERC20SnapshotModuleCommonUnschedule () { }) it('can schedule a snaphot after an unschedule', async function () { - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime1) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime2) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime3) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime4) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime5) - let snapshots = await this.cmtat.getNextSnapshots() + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime1) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime2) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime3) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime4) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime5) + let snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(5) - await this.cmtat + await this.transferEngineMock .connect(this.admin) .unscheduleSnapshotNotOptimized(this.snapshotTime2) - snapshots = await this.cmtat.getNextSnapshots() + snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(4) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime6) - snapshots = await this.cmtat.getNextSnapshots() + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime6) + snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(5) checkArraySnapshot(snapshots, [ this.snapshotTime1, @@ -140,25 +140,25 @@ function ERC20SnapshotModuleCommonUnschedule () { it('reverts when calling from non-admin', async function () { // Arrange const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(60) - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .scheduleSnapshot(SNAPSHOT_TIME) - let snapshots = await this.cmtat.getNextSnapshots() + let snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(1) expect(snapshots[0]).to.equal(SNAPSHOT_TIME) // Act await expect( - this.cmtat + this.transferEngineMock .connect(this.address1) .unscheduleSnapshotNotOptimized(SNAPSHOT_TIME) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'AccessControlUnauthorizedAccount' ) .withArgs(this.address1.address, SNAPSHOOTER_ROLE) // Assert - snapshots = await this.cmtat.getNextSnapshots() + snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(1) }) }) @@ -167,28 +167,28 @@ function ERC20SnapshotModuleCommonUnschedule () { beforeEach(async function () { this.currentTime = await time.latest() this.snapshotTime = this.currentTime + time.duration.seconds(60) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime) }) it('can unschedule a snapshot with the snapshoter role and emits a SnapshotUnschedule event', async function () { - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .unscheduleLastSnapshot(this.snapshotTime) await expect(this.logs) - .to.emit(this.cmtat, 'SnapshotUnschedule') + .to.emit(this.transferEngineMock, 'SnapshotUnschedule') .withArgs(this.snapshotTime) - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(0) }) it('reverts when calling from non-admin', async function () { await expect( - this.cmtat + this.transferEngineMock .connect(this.address1) .unscheduleLastSnapshot(this.snapshotTime) ) .to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'AccessControlUnauthorizedAccount' ) .withArgs(this.address1.address, SNAPSHOOTER_ROLE) @@ -198,14 +198,14 @@ function ERC20SnapshotModuleCommonUnschedule () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(90) // Arrange // Delete the only snapshot - this.logs = await this.cmtat + this.logs = await this.transferEngineMock .connect(this.admin) .unscheduleLastSnapshot(this.snapshotTime) // Act await expect( - this.cmtat.connect(this.admin).unscheduleLastSnapshot(SNAPSHOT_TIME) + this.transferEngineMock.connect(this.admin).unscheduleLastSnapshot(SNAPSHOT_TIME) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_NoSnapshotScheduled' ) }) @@ -214,9 +214,9 @@ function ERC20SnapshotModuleCommonUnschedule () { const SNAPSHOT_TIME = this.currentTime + time.duration.seconds(90) // Act await expect( - this.cmtat.connect(this.admin).unscheduleLastSnapshot(SNAPSHOT_TIME) + this.transferEngineMock.connect(this.admin).unscheduleLastSnapshot(SNAPSHOT_TIME) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotNotFound' ) }) @@ -224,9 +224,9 @@ function ERC20SnapshotModuleCommonUnschedule () { it('reverts when snapshot has been processed', async function () { const SNAPSHOT_TIME = this.currentTime - time.duration.seconds(60) await expect( - this.cmtat.connect(this.admin).unscheduleLastSnapshot(SNAPSHOT_TIME) + this.transferEngineMock.connect(this.admin).unscheduleLastSnapshot(SNAPSHOT_TIME) ).to.be.revertedWithCustomError( - this.cmtat, + this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotAlreadyDone' ) }) diff --git a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleUtils/ERC20SnapshotModuleUtils.js b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleUtils/ERC20SnapshotModuleUtils.js index 54ad7e42..6bb9a0b1 100644 --- a/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleUtils/ERC20SnapshotModuleUtils.js +++ b/test/common/ERC20SnapshotModuleCommon/ERC20SnapshotModuleUtils/ERC20SnapshotModuleUtils.js @@ -10,25 +10,25 @@ const timeout = function (ms) { async function checkSnapshot (time, totalSupply, addressese, balances) { const addresses = [this.address1, this.address2, this.address3] // Values before the snapshot - expect(await this.cmtat.snapshotTotalSupply(time)).to.equal(totalSupply) + expect(await this.transferEngineMock.snapshotTotalSupply(time)).to.equal(totalSupply) // const result = await this.cmtat.snapshotInfoBatch(time, addresses) - const result = await this.cmtat['snapshotInfoBatch(uint256,address[])']( + const result = await this.transferEngineMock['snapshotInfoBatch(uint256,address[])']( time, addresses ) /* methods */ const times = [time] - const result2 = await this.cmtat['snapshotInfoBatch(uint256[],address[])']( + const result2 = await this.transferEngineMock['snapshotInfoBatch(uint256[],address[])']( times, addresses ) for (let i = 0; i < balances.length; ++i) { - expect(await this.cmtat.snapshotBalanceOf(time, addresses[i])).to.equal( + expect(await this.transferEngineMock.snapshotBalanceOf(time, addresses[i])).to.equal( balances[i] ) - await this.cmtat.snapshotInfo(time, addresses[i]) + await this.transferEngineMock.snapshotInfo(time, addresses[i]) const { 0: ownerBalance, 1: totalSupplyGet } = - await this.cmtat.snapshotInfo(time, addresses[i]) + await this.transferEngineMock.snapshotInfo(time, addresses[i]) // const [ownerBalance, totalSupplyGet] expect(ownerBalance).to.equal(balances[i]) expect(result[0][i]).to.equal(balances[i]) diff --git a/test/common/ERC20SnapshotModuleCommon/global/ERC20SnapshotModuleMultiplePlannedTest.js b/test/common/ERC20SnapshotModuleCommon/global/ERC20SnapshotModuleMultiplePlannedTest.js index 2989346f..07b497e8 100644 --- a/test/common/ERC20SnapshotModuleCommon/global/ERC20SnapshotModuleMultiplePlannedTest.js +++ b/test/common/ERC20SnapshotModuleCommon/global/ERC20SnapshotModuleMultiplePlannedTest.js @@ -36,9 +36,9 @@ function ERC20SnapshotModuleMultiplePlannedTest () { this.snapshotTime3 = this.currentTime + time.duration.seconds(THIRD_SNAPSHOT_INTERVAL) this.beforeSnapshotTime = this.currentTime - time.duration.seconds(60) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime1) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime2) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime3) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime1) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime2) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime3) // We jump into the future await time.increase(FIRST_SNAPSHOT_INTERVAL + 1) }) @@ -157,7 +157,7 @@ function ERC20SnapshotModuleMultiplePlannedTest () { ADDRESS3_INITIAL_MINT ] ) - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(1) }) @@ -228,7 +228,7 @@ function ERC20SnapshotModuleMultiplePlannedTest () { ADDRESS3_INITIAL_MINT ] ) - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(0) }) @@ -306,7 +306,7 @@ function ERC20SnapshotModuleMultiplePlannedTest () { ADDRESS3_INITIAL_MINT ] ) - expect((await this.cmtat.getNextSnapshots()).length).to.equal(2) + expect((await this.transferEngineMock.getNextSnapshots()).length).to.equal(2) // We jump into the future await time.increase(SECOND_SNAPSHOT_INTERVAL - FIRST_SNAPSHOT_INTERVAL) @@ -362,7 +362,7 @@ function ERC20SnapshotModuleMultiplePlannedTest () { ADDRESS3_INITIAL_MINT ] ) - expect((await this.cmtat.getNextSnapshots()).length).to.equal(1) + expect((await this.transferEngineMock.getNextSnapshots()).length).to.equal(1) // We jump into the future await time.increase(THIRD_SNAPSHOT_INTERVAL - FIRST_SNAPSHOT_INTERVAL) @@ -431,7 +431,7 @@ function ERC20SnapshotModuleMultiplePlannedTest () { ADDRESS3_INITIAL_MINT ] ) - expect((await this.cmtat.getNextSnapshots()).length).to.equal(0) + expect((await this.transferEngineMock.getNextSnapshots()).length).to.equal(0) }) }) } diff --git a/test/common/ERC20SnapshotModuleCommon/global/ERC20SnapshotModuleOnePlannedSnapshotTest.js b/test/common/ERC20SnapshotModuleCommon/global/ERC20SnapshotModuleOnePlannedSnapshotTest.js index a450f066..790e245d 100644 --- a/test/common/ERC20SnapshotModuleCommon/global/ERC20SnapshotModuleOnePlannedSnapshotTest.js +++ b/test/common/ERC20SnapshotModuleCommon/global/ERC20SnapshotModuleOnePlannedSnapshotTest.js @@ -25,7 +25,7 @@ function ERC20SnapshotModuleOnePlannedSnapshotTest () { this.currentTime = await time.latest() this.snapshotTime = this.currentTime + time.duration.seconds(3) this.beforeSnapshotTime = this.currentTime - time.duration.seconds(60) - await this.cmtat.connect(this.admin).scheduleSnapshot(this.snapshotTime) + await this.transferEngineMock.connect(this.admin).scheduleSnapshot(this.snapshotTime) // We jump into the future await time.increase(time.duration.seconds(10)) }) @@ -74,7 +74,7 @@ function ERC20SnapshotModuleOnePlannedSnapshotTest () { ADDRESSES, [address1NewTokensBalance, ADDRESS2_INITIAL_MINT, ADDRESS3_INITIAL_MINT] ) - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(0) }) @@ -122,7 +122,7 @@ function ERC20SnapshotModuleOnePlannedSnapshotTest () { ADDRESSES, [address1NewTokensBalance, ADDRESS2_INITIAL_MINT, ADDRESS3_INITIAL_MINT] ) - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(0) }) @@ -175,7 +175,7 @@ function ERC20SnapshotModuleOnePlannedSnapshotTest () { ADDRESS3_INITIAL_MINT ] ) - const snapshots = await this.cmtat.getNextSnapshots() + const snapshots = await this.transferEngineMock.getNextSnapshots() expect(snapshots.length).to.equal(0) }) }) diff --git a/test/proxy/modules/ERC20SnapshotModule.test.js b/test/proxy/modules/ERC20SnapshotModule.test.js index a1c0399f..c7b072a2 100644 --- a/test/proxy/modules/ERC20SnapshotModule.test.js +++ b/test/proxy/modules/ERC20SnapshotModule.test.js @@ -19,6 +19,9 @@ describe('Proxy - ERC20SnapshotModule', function () { this.admin.address, this.deployerAddress.address ) + this.transferEngineMock = await ethers.deployContract('TransferEngineMock', [ + this.cmtat.target, this.admin]) + this.cmtat.connect(this.admin).setTransferEngine(this.transferEngineMock) }) ERC20SnapshotModuleMultiplePlannedTest() ERC20SnapshotModuleOnePlannedSnapshotTest() diff --git a/test/standard/modules/ERC20SnapshotModule.test.js b/test/standard/modules/ERC20SnapshotModule.test.js index 111c8f01..09ba4e7c 100644 --- a/test/standard/modules/ERC20SnapshotModule.test.js +++ b/test/standard/modules/ERC20SnapshotModule.test.js @@ -19,6 +19,9 @@ describe('Standard - ERC20SnapshotModule', function () { this.admin.address, this.deployerAddress.address ) + this.transferEngineMock = await ethers.deployContract('TransferEngineMock', [ + this.cmtat.target, this.admin]) + this.cmtat.connect(this.admin).setTransferEngine(this.transferEngineMock) }) ERC20SnapshotModuleMultiplePlannedTest() ERC20SnapshotModuleOnePlannedSnapshotTest() From 115ac4d2da92221f16e46e539ee522bb32f17d63 Mon Sep 17 00:00:00 2001 From: Ryan Sauge <71391932+rya-sge@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:39:14 +0100 Subject: [PATCH 2/2] Use a struct to represent a document --- .../interfaces/engine/draft-IERC1643.sol | 10 +- contracts/mocks/DocumentEngineMock.sol | 100 ++++++++---------- .../wrapper/extensions/DocumentModule.sol | 8 +- .../DocumentModule/DocumentModuleCommon.js | 44 ++++---- .../DocumentModuleSetDocumentEngineCommon.js | 8 +- 5 files changed, 82 insertions(+), 88 deletions(-) diff --git a/contracts/interfaces/engine/draft-IERC1643.sol b/contracts/interfaces/engine/draft-IERC1643.sol index c902df6d..826537be 100644 --- a/contracts/interfaces/engine/draft-IERC1643.sol +++ b/contracts/interfaces/engine/draft-IERC1643.sol @@ -5,7 +5,13 @@ pragma solidity ^0.8.20; /// @title IERC1643 Document Management /// (part of the ERC1400 Security Token Standards) interface IERC1643 { + struct Document { + string uri; + bytes32 documentHash; + uint256 lastModified; + } + // Document Management - function getDocument(bytes32 _name) external view returns (string memory , bytes32, uint256); - function getAllDocuments() external view returns (bytes32[] memory); + function getDocument(string memory name) external view returns (Document memory doc); + function getAllDocuments() external view returns (string[] memory); } \ No newline at end of file diff --git a/contracts/mocks/DocumentEngineMock.sol b/contracts/mocks/DocumentEngineMock.sol index 297ce5b8..4f0f1939 100644 --- a/contracts/mocks/DocumentEngineMock.sol +++ b/contracts/mocks/DocumentEngineMock.sol @@ -3,94 +3,82 @@ pragma solidity ^0.8.20; import "../interfaces/engine/draft-IERC1643.sol"; interface IERC1643Whole is IERC1643{ - + /// uri The URI of the document + /// @return documentHash The hash of the document contents + /// @return lastModified The timestamp of the last modification + struct DocumentInfo { + string name; + string uri; + bytes32 documentHash; + } // Document Management - function setDocument(bytes32 _name, string memory _uri, bytes32 _documentHash) external; - function removeDocument(bytes32 _name) external; + function setDocument(DocumentInfo calldata doc) external; + function removeDocument(string memory name) external; // Document Events - event DocumentRemoved(bytes32 indexed _name, string _uri, bytes32 _documentHash); - event DocumentUpdated(bytes32 indexed _name, string _uri, bytes32 _documentHash); + event DocumentRemoved(string indexed name, Document doc); + event DocumentUpdated(string indexed name, Document doc); } /* * @title a DocumentEngine mock for testing, not suitable for production */ contract DocumentEngineMock is IERC1643Whole { - struct Document { - string uri; - bytes32 documentHash; - uint256 lastModified; - } - - mapping(bytes32 => Document) private documents; - bytes32[] private documentNames; + /*struct DocumentStorage { + uint256 key; + Document doc; + }*/ + mapping(string => Document) private documents; + mapping(string => uint256) private documentKey; + string[] private documentNames; /// @dev Error thrown when a document does not exist error DocumentDoesNotExist(); /// @notice Retrieves the document details by name - /// @param name_ The name of the document - /// @return uri The URI of the document - /// @return documentHash The hash of the document contents - /// @return lastModified The timestamp of the last modification - function getDocument(bytes32 name_) + /// @param name The name of the document + function getDocument(string memory name) external view override - returns (string memory uri, bytes32 documentHash, uint256 lastModified) + returns (Document memory doc) { - if (bytes(documents[name_].uri).length == 0) { - return("", 0x0, 0); - } - - Document storage doc = documents[name_]; - return (doc.uri, doc.documentHash, doc.lastModified); + return documents[name]; } /// @notice Sets or updates a document - /// @param name_ The name of the document - /// @param uri_ The URI of the document - /// @param documentHash_ The hash of the document contents - function setDocument(bytes32 name_, string memory uri_, bytes32 documentHash_) external override { - Document storage doc = documents[name_]; - bool isUpdate = bytes(doc.uri).length != 0; - - doc.uri = uri_; - doc.documentHash = documentHash_; + /// @param doc_ the document + function setDocument(DocumentInfo calldata doc_) external override { + Document storage doc = documents[doc_.name]; + doc.uri = doc_.uri; + doc.documentHash = doc_.documentHash; doc.lastModified = block.timestamp; - - if (!isUpdate) { - documentNames.push(name_); + if (documentKey[doc_.name] == 0) { + // To avoid key == 0 + uint256 key = documentNames.length + 1; + documentKey[doc_.name] = key; + documentNames.push(doc_.name); } - - emit DocumentUpdated(name_, uri_, documentHash_); + emit DocumentUpdated(doc_.name, doc); } /// @notice Removes a document - /// @param name_ The name of the document - function removeDocument(bytes32 name_) external override { - if (bytes(documents[name_].uri).length == 0) { + /// @param name The name of the document + function removeDocument(string calldata name) external override { + if (documentKey[name] == 0) { revert DocumentDoesNotExist(); } - - Document memory doc = documents[name_]; - delete documents[name_]; - - for (uint256 i = 0; i < documentNames.length; i++) { - if (documentNames[i] == name_) { - documentNames[i] = documentNames[documentNames.length - 1]; - documentNames.pop(); - break; - } - } - - emit DocumentRemoved(name_, doc.uri, doc.documentHash); + Document memory doc = documents[name]; + documentNames[documentKey[name] - 1] = documentNames[documentNames.length - 1]; + documentNames.pop(); + delete documents[name]; + documentKey[name] = 0; + emit DocumentRemoved(name, doc); } /// @notice Retrieves all document names /// @return An array of document names - function getAllDocuments() external view override returns (bytes32[] memory) { + function getAllDocuments() external view override returns (string[] memory) { return documentNames; } } \ No newline at end of file diff --git a/contracts/modules/wrapper/extensions/DocumentModule.sol b/contracts/modules/wrapper/extensions/DocumentModule.sol index e763a12d..d69e865e 100644 --- a/contracts/modules/wrapper/extensions/DocumentModule.sol +++ b/contracts/modules/wrapper/extensions/DocumentModule.sol @@ -71,16 +71,16 @@ abstract contract DocumentModule is AuthorizationModule, IERC1643 { } - function getDocument(bytes32 _name) public view returns (string memory, bytes32, uint256){ + function getDocument(string memory name) public view returns (Document memory document){ DocumentModuleStorage storage $ = _getDocumentModuleStorage(); if(address($._documentEngine) != address(0)){ - return $._documentEngine.getDocument( _name); + return $._documentEngine.getDocument(name); } else{ - return ("",0x0, 0); + return Document("", 0x0, 0); } } - function getAllDocuments() public view returns (bytes32[] memory documents){ + function getAllDocuments() public view returns (string[] memory documents){ DocumentModuleStorage storage $ = _getDocumentModuleStorage(); if(address($._documentEngine) != address(0)){ documents = $._documentEngine.getAllDocuments(); diff --git a/test/common/DocumentModule/DocumentModuleCommon.js b/test/common/DocumentModule/DocumentModuleCommon.js index ea26021e..c0bf5d9e 100644 --- a/test/common/DocumentModule/DocumentModuleCommon.js +++ b/test/common/DocumentModule/DocumentModuleCommon.js @@ -24,13 +24,13 @@ function DocumentModuleCommon () { const uri = 'https://github.com/CMTA/CMTAT' const documentHash = ethers.encodeBytes32String('hash1') - await this.documentEngineMock.setDocument(name, uri, documentHash) + await this.documentEngineMock.setDocument(({name, uri, documentHash})) - const [storedUri, storedHash, lastModified] = + const doc = await this.cmtat.getDocument(name) - expect(storedUri).to.equal(uri) - expect(storedHash).to.equal(documentHash) - expect(lastModified).to.be.gt(0) + expect(doc.uri).to.equal(uri) + expect(doc.documentHash).to.equal(documentHash) + expect(doc.lastModified).to.be.gt(0) }) it('testCanUpdateADocument', async function () { @@ -41,23 +41,23 @@ function DocumentModuleCommon () { const uri2 = 'https://github.com/CMTA/CMTAT/V2' const documentHash2 = ethers.encodeBytes32String('hash2') - await this.documentEngineMock.setDocument(name, uri1, documentHash1) - await this.documentEngineMock.setDocument(name, uri2, documentHash2) + await this.documentEngineMock.setDocument([name, uri1, documentHash1]) + await this.documentEngineMock.setDocument([name, uri2, documentHash2]) - const [storedUri, storedHash, lastModified] = + const doc = await this.cmtat.getDocument(name) - expect(storedUri).to.equal(uri2) - expect(storedHash).to.equal(documentHash2) - expect(lastModified).to.be.gt(0) + expect(doc.uri).to.equal(uri2) + expect(doc.documentHash).to.equal(documentHash2) + expect(doc.lastModified).to.be.gt(0) }) it('testCanGetNullValueIfNoDocument', async function () { const name = ethers.encodeBytes32String('doc1') - const [storedUri, storedHash, lastModified] = + const doc = await this.cmtat.getDocument(name) - expect(storedUri).to.equal('') - expect(storedHash).to.equal(ethers.encodeBytes32String('')) - expect(lastModified).to.equal(0) + expect(doc.uri).to.equal('') + expect(doc.documentHash).to.equal(ethers.encodeBytes32String('')) + expect(doc.lastModified).to.equal(0) }) it('testCanRemoveADocument', async function () { @@ -65,14 +65,14 @@ function DocumentModuleCommon () { const uri = 'https://github.com/CMTA/CMTAT' const documentHash = ethers.encodeBytes32String('hash1') - await this.documentEngineMock.setDocument(name, uri, documentHash) + await this.documentEngineMock.setDocument([name, uri, documentHash]) await this.documentEngineMock.removeDocument(name) - const [storedUri, storedHash, lastModified] = + const doc = await this.cmtat.getDocument(name) - expect(storedUri).to.equal('') - expect(storedHash).to.equal(ethers.encodeBytes32String('')) - expect(lastModified).to.equal(0) + expect(doc.uri).to.equal('') + expect(doc.documentHash).to.equal(ethers.encodeBytes32String('')) + expect(doc.lastModified).to.equal(0) }) it('testCanReturnAllDocumentNames', async function () { @@ -84,8 +84,8 @@ function DocumentModuleCommon () { const uri2 = 'https://github.com/CMTA/CMTAT/V2' const documentHash2 = ethers.encodeBytes32String('hash2') - await this.documentEngineMock.setDocument(name1, uri1, documentHash1) - await this.documentEngineMock.setDocument(name2, uri2, documentHash2) + await this.documentEngineMock.setDocument([name1, uri1, documentHash1]) + await this.documentEngineMock.setDocument([name2, uri2, documentHash2]) const documentNames = await this.cmtat.getAllDocuments() expect(documentNames.length).to.equal(2) diff --git a/test/common/DocumentModule/DocumentModuleSetDocumentEngineCommon.js b/test/common/DocumentModule/DocumentModuleSetDocumentEngineCommon.js index 4877fba6..19e24045 100644 --- a/test/common/DocumentModule/DocumentModuleSetDocumentEngineCommon.js +++ b/test/common/DocumentModule/DocumentModuleSetDocumentEngineCommon.js @@ -44,12 +44,12 @@ function DocumentModuleSetDocumentEngineCommon () { it('testGetEmptyDocumentsIfNoDocumentEngine', async function () { const name = ethers.encodeBytes32String('doc1') // act - const [storedUri, storedHash, lastModified] = + const doc = await this.cmtat.getDocument(name) // Assert - expect(storedUri).to.equal('') - expect(storedHash).to.equal(ethers.encodeBytes32String('')) - expect(lastModified).to.equal(0) + expect(doc.uri).to.equal('') + expect(doc.documentHash).to.equal(ethers.encodeBytes32String('')) + expect(doc.lastModified).to.equal(0) // Act const documentNames = await this.cmtat.getAllDocuments()