From c8157d2c48d868ac5871137b81ed51a525540445 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:01:20 +0530 Subject: [PATCH] feat: add TimeManagerV5 and TimeManagerV8 --- contracts/TimeManagerV5.sol | 58 ++++++++++++++++++++++++++++++++ contracts/TimeManagerV8.sol | 60 ++++++++++++++++++++++++++++++++++ hardhat.config.ts | 16 +++++++++ tests/hardhat/TimeManagerV5.ts | 34 +++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 contracts/TimeManagerV5.sol create mode 100644 contracts/TimeManagerV8.sol create mode 100644 tests/hardhat/TimeManagerV5.ts diff --git a/contracts/TimeManagerV5.sol b/contracts/TimeManagerV5.sol new file mode 100644 index 0000000..8605e84 --- /dev/null +++ b/contracts/TimeManagerV5.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.5.16; + +contract TimeManagerV5 { + /// @dev The approximate number of seconds per year + uint256 constant SECONDS_PER_YEAR = 31_536_000; + + /// @notice Number of blocks per year or seconds per year + uint256 public blocksOrSecondsPerYear; + + /// @dev Sets true when block timestamp is used + bool public isTimeBased; + + /** + * @dev Retrieves the current slot + * @return Current slot + */ + function() view returns (uint256) private _getCurrentSlot; + + /** + * @param timeBased_ A boolean indicating whether the contract is based on time or block. + * If timeBased is true than blocksPerYear_ param is ignored as blocksOrSecondsPerYear is set to SECONDS_PER_YEAR + * @param blocksPerYear_ The number of blocks per year + */ + constructor(bool timeBased_, uint256 blocksPerYear_) public { + if (!timeBased_ && blocksPerYear_ == 0) { + revert("Invalid Blocks Per year"); + } + isTimeBased = timeBased_; + blocksOrSecondsPerYear = timeBased_ ? SECONDS_PER_YEAR : blocksPerYear_; + _getCurrentSlot = timeBased_ ? _getBlockTimestamp : _getBlockNumber; + } + + /** + * @dev Function to simply retrieve block number or block timestamp + * This exists mainly for inheriting test contracts to stub this result. + * @return Current block number or block timestamp + */ + function getBlockNumberOrTimestamp() public view returns (uint256) { + return _getCurrentSlot(); + } + + /** + * @notice Returns the current timestamp in seconds + * @return The current timestamp + */ + function _getBlockTimestamp() private view returns (uint256) { + return block.timestamp; + } + + /** + * @notice Returns the current block number + * @return The current block number + */ + function _getBlockNumber() private view returns (uint256) { + return block.number; + } +} diff --git a/contracts/TimeManagerV8.sol b/contracts/TimeManagerV8.sol new file mode 100644 index 0000000..80194f8 --- /dev/null +++ b/contracts/TimeManagerV8.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.13; + +import { SECONDS_PER_YEAR } from "./constants.sol"; + +abstract contract TimeManagerV8 { + /// @custom:oz-upgrades-unsafe-allow state-variable-immutable + uint256 public immutable blocksOrSecondsPerYear; + + /// @custom:oz-upgrades-unsafe-allow state-variable-immutable + bool public immutable isTimeBased; + + /// @custom:oz-upgrades-unsafe-allow state-variable-immutable + function() view returns (uint256) private immutable _getCurrentSlot; + + /// @notice Thrown on invaid arguments + error InvalidBlocksPerYear(); + + /** + * @param timeBased_ A boolean indicating whether the contract is based on time or block. + * If timeBased is true than blocksPerYear_ param is ignored as blocksOrSecondsPerYear is set to SECONDS_PER_YEAR + * @param blocksPerYear_ The number of blocks per year + * @custom:error InvalidBlocksPerYear is thrown if blocksPerYear entered is zero + * @custom:oz-upgrades-unsafe-allow constructor + */ + constructor(bool timeBased_, uint256 blocksPerYear_) { + if (!timeBased_ && blocksPerYear_ == 0) { + revert InvalidBlocksPerYear(); + } + + isTimeBased = timeBased_; + blocksOrSecondsPerYear = timeBased_ ? SECONDS_PER_YEAR : blocksPerYear_; + _getCurrentSlot = timeBased_ ? _getBlockTimestamp : _getBlockNumber; + } + + /** + * @dev Function to simply retrieve block number or block timestamp + * This exists mainly for inheriting test contracts to stub this result. + * @return Current block number or block timestamp + */ + function getBlockNumberOrTimestamp() public view virtual returns (uint256) { + return _getCurrentSlot(); + } + + /** + * @notice Returns the current timestamp in seconds + * @return The current timestamp + */ + function _getBlockTimestamp() private view returns (uint256) { + return block.timestamp; + } + + /** + * @notice Returns the current block number + * @return The current block number + */ + function _getBlockNumber() private view returns (uint256) { + return block.number; + } +} diff --git a/hardhat.config.ts b/hardhat.config.ts index f80b120..29b5abd 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -47,6 +47,22 @@ const config: HardhatUserConfig = { }, }, }, + { + version: "0.5.16", + settings: { + optimizer: { + enabled: true, + details: { + yul: !process.env.CI, + }, + }, + outputSelection: { + "*": { + "*": ["storageLayout"], + }, + }, + }, + }, ], }, networks: { diff --git a/tests/hardhat/TimeManagerV5.ts b/tests/hardhat/TimeManagerV5.ts new file mode 100644 index 0000000..2d0069b --- /dev/null +++ b/tests/hardhat/TimeManagerV5.ts @@ -0,0 +1,34 @@ +import chai from "chai"; +import { ethers } from "hardhat"; + +const { expect } = chai; + +describe("TimeManagerV5: tests", async () => { + let timeManager: ethers.Contracts; + describe("For block number", async () => { + const blocksPerYear = 10512000; + beforeEach(async () => { + const timeManagerV5 = await ethers.getContractFactory("TimeManagerV5"); + timeManager = await timeManagerV5.deploy(false, blocksPerYear); + }); + + it("Retrieves block timestamp", async () => { + const currentBlockNumber = (await ethers.provider.getBlock("latest")).number; + expect(await timeManager.getBlockNumberOrTimestamp()).to.be.equal(currentBlockNumber); + expect(await timeManager.blocksOrSecondsPerYear()).to.be.equal(blocksPerYear); + }); + }); + describe("For block timestamp", async () => { + beforeEach(async () => { + const timeManagerV5 = await ethers.getContractFactory("TimeManagerV5"); + timeManager = await timeManagerV5.deploy(true, 0); + }); + + it("Retrieves block timestamp", async () => { + const secondsPerYear = 31536000; + const currentBlocktimestamp = (await ethers.provider.getBlock("latest")).timestamp; + expect(await timeManager.getBlockNumberOrTimestamp()).to.be.equal(currentBlocktimestamp); + expect(await timeManager.blocksOrSecondsPerYear()).to.be.equal(secondsPerYear); + }); + }); +});