From e379bf86bd0fd6af18044b559a6c48eb1e617958 Mon Sep 17 00:00:00 2001 From: ihoroleksiienko <144142848+ihoroleksiienko@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:51:38 +0200 Subject: [PATCH] feat: create `IVersion` interface (#19) * feat: add contract version * test: add tests for contract version * fix: change comments, types * fix: typo * feat: change version function to $, add abstract instead interface * test: change version test * fix: update version * test: update version test * test: remove unnecessary import * fix: rename version class, function * test: update version test * fix: add version interface * feat: remove `__VERSION` functions * feat: change version to `4.0.0` * chore: disable `stylistic/linebreak-style` checks * feat: move `IVersion` interface to the separate file --------- Co-authored-by: Igor Senych --- .eslintrc.json | 2 +- contracts/Cashier.sol | 4 +++- contracts/CashierShard.sol | 3 ++- contracts/Versionable.sol | 21 +++++++++++++++++++++ contracts/interfaces/ICashier.sol | 4 +++- contracts/interfaces/ICashierShard.sol | 5 ++++- contracts/interfaces/IVersion.sol | 24 ++++++++++++++++++++++++ test/CashierSharded.test.ts | 24 ++++++++++++++++++++++++ 8 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 contracts/Versionable.sol create mode 100644 contracts/interfaces/IVersion.sol diff --git a/.eslintrc.json b/.eslintrc.json index c43af43..3a80ec9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,7 +26,7 @@ "@stylistic/function-paren-newline": ["warn", "multiline-arguments"], "@stylistic/indent": ["warn", 2], "@stylistic/indent-binary-ops": ["warn", 2], - "@stylistic/linebreak-style": ["warn", "unix"], + "@stylistic/linebreak-style": "off", "@stylistic/lines-around-comment": ["warn", {"beforeBlockComment": false}], "@stylistic/max-len": ["warn", {"code": 120, "tabWidth": 2}], "@stylistic/member-delimiter-style": [ diff --git a/contracts/Cashier.sol b/contracts/Cashier.sol index 2565183..dd9017f 100644 --- a/contracts/Cashier.sol +++ b/contracts/Cashier.sol @@ -21,6 +21,7 @@ import { ICashierHookable } from "./interfaces/ICashierHookable.sol"; import { IERC20Mintable } from "./interfaces/IERC20Mintable.sol"; import { CashierStorage } from "./CashierStorage.sol"; +import { Versionable } from "./Versionable.sol"; /** * @title Cashier contract @@ -34,7 +35,8 @@ contract Cashier is RescuableUpgradeable, UUPSUpgradeable, ICashier, - ICashierHookable + ICashierHookable, + Versionable { using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.Bytes32Set; diff --git a/contracts/CashierShard.sol b/contracts/CashierShard.sol index fc40416..0c56307 100644 --- a/contracts/CashierShard.sol +++ b/contracts/CashierShard.sol @@ -9,13 +9,14 @@ import { ICashierShard } from "./interfaces/ICashierShard.sol"; import { ICashierShardPrimary } from "./interfaces/ICashierShard.sol"; import { ICashierShardConfiguration } from "./interfaces/ICashierShard.sol"; import { CashierShardStorage } from "./CashierShardStorage.sol"; +import { Versionable } from "./Versionable.sol"; /** * @title CashierShard contract * @author CloudWalk Inc. (See https://www.cloudwalk.io) * @dev The contract responsible for storing sharded cash-in and cash-out operations. */ -contract CashierShard is CashierShardStorage, OwnableUpgradeable, UUPSUpgradeable, ICashierShard { +contract CashierShard is CashierShardStorage, OwnableUpgradeable, UUPSUpgradeable, ICashierShard, Versionable { // ------------------ Initializers ---------------------------- // /** diff --git a/contracts/Versionable.sol b/contracts/Versionable.sol new file mode 100644 index 0000000..07b8eba --- /dev/null +++ b/contracts/Versionable.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./interfaces/IVersion.sol"; + +/** + * @title Versionable contract + * @author CloudWalk Inc. (See https://cloudwalk.io) + * @dev Defines the contract version. + */ +abstract contract Versionable is IVersion { + // ------------------ Pure functions -------------------------- // + + /** + * @inheritdoc IVersion + */ + function $__VERSION() external pure returns (Version memory) { + return Version(4, 0, 0); + } +} diff --git a/contracts/interfaces/ICashier.sol b/contracts/interfaces/ICashier.sol index b0b2165..3456b93 100644 --- a/contracts/interfaces/ICashier.sol +++ b/contracts/interfaces/ICashier.sol @@ -492,4 +492,6 @@ interface ICashier is ICashierErrors, // Tools: this comment prevents Prettier from formatting into a single line. ICashierPrimary, ICashierConfiguration -{} +{ + +} diff --git a/contracts/interfaces/ICashierShard.sol b/contracts/interfaces/ICashierShard.sol index 8cd8b21..a548a9b 100644 --- a/contracts/interfaces/ICashierShard.sol +++ b/contracts/interfaces/ICashierShard.sol @@ -22,6 +22,7 @@ interface ICashierShardErrors { /// @dev Thrown if the caller is not an admin. error CashierShard_Unauthorized(); } + /** * @title ICashierShardPrimary interface * @author CloudWalk Inc. (See https://www.cloudwalk.io) @@ -219,4 +220,6 @@ interface ICashierShard is ICashierShardErrors, // Tools: this comment prevents Prettier from formatting into a single line. ICashierShardPrimary, ICashierShardConfiguration -{} +{ + +} diff --git a/contracts/interfaces/IVersion.sol b/contracts/interfaces/IVersion.sol new file mode 100644 index 0000000..1e71e8c --- /dev/null +++ b/contracts/interfaces/IVersion.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @title IVersion interface + * @author CloudWalk Inc. (See https://cloudwalk.io) + * @dev Defines the function to get the contract version. + */ +interface IVersion { + /** + * @dev The struct for the contract version. + */ + struct Version { + uint8 major; // -- The major version of contract + uint8 minor; // -- The minor version of contract + uint8 patch; // -- The patch version of contract + } + + /** + * @dev Returns the version of the contract. + */ + function $__VERSION() external pure returns (Version memory); +} diff --git a/test/CashierSharded.test.ts b/test/CashierSharded.test.ts index 2efae41..028fdad 100644 --- a/test/CashierSharded.test.ts +++ b/test/CashierSharded.test.ts @@ -71,6 +71,14 @@ interface HookConfig { [key: string]: number | string; // Indexing signature to ensure that fields are iterated over in a key-value style } +interface Version { + major: number; + minor: number; + patch: number; + + [key: string]: number; // Indexing signature to ensure that fields are iterated over in a key-value style +} + function checkCashOutEquality( actualOnChainCashOut: Record, expectedCashOut: TestCashOut, @@ -200,6 +208,12 @@ describe("Contracts 'Cashier' and `CashierShard`", async () => { (1 << HookIndex.CashOutReversalBefore) + (1 << HookIndex.CashOutReversalAfter); + const EXPECTED_VERSION: Version = { + major: 4, + minor: 0, + patch: 0 + }; + // Errors of the lib contracts const REVERT_ERROR_IF_CONTRACT_INITIALIZATION_IS_INVALID = "InvalidInitialization"; const REVERT_ERROR_IF_CONTRACT_IS_PAUSED = "EnforcedPause"; @@ -2520,6 +2534,16 @@ describe("Contracts 'Cashier' and `CashierShard`", async () => { }); }); + describe("Function '$__VERSION()'", async () => { + it("Returns expected values", async () => { + const { cashierRoot, cashierShards } = await setUpFixture(deployAndConfigureContracts); + const cashierRootVersion = await cashierRoot.$__VERSION(); + const cashierShardVersion = await cashierShards[0].$__VERSION(); + checkEquality(cashierRootVersion, EXPECTED_VERSION); + checkEquality(cashierShardVersion, EXPECTED_VERSION); + }); + }); + describe("Scenarios with configured hooks", async () => { async function checkHookEvents(fixture: Fixture, props: { tx: TransactionResponse;