diff --git a/.github/workflows/tests-integration.yml b/.github/workflows/tests-integration.yml index b4af0478d..22327e2e6 100644 --- a/.github/workflows/tests-integration.yml +++ b/.github/workflows/tests-integration.yml @@ -10,7 +10,7 @@ jobs: services: hardhat-node: - image: feofanov/hardhat-node:2.22.8 + image: feofanov/hardhat-node:2.22.9 ports: - 8545:8545 env: diff --git a/.prettierignore b/.prettierignore index 07b0b1a99..35b275a85 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,9 @@ foundry +contracts/**/*.sol .gitignore .prettierignore +eslint.config.mjs + package-lock.json diff --git a/.prettierrc b/.prettierrc index 8618a9629..724d44d6f 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,5 +3,16 @@ "singleQuote": false, "printWidth": 120, "tabWidth": 2, - "quoteProps": "consistent" + "quoteProps": "consistent", + "plugins": ["prettier-plugin-solidity"], + "overrides": [ + { + "files": "*.sol", + "options": { + "parser": "solidity-parse", + "tabWidth": 4, + "useTabs": false + } + } + ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c02fce8c8..f6acdac9d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -128,19 +128,29 @@ This repository features a Hardhat-Foundry dual setup: - Hardhat gives much more flexibility when writing complex tests; - The Foundry's fuzzing capabilities enable better coverage of edge cases. -#### Tracing +#### Hardhat + +Hardhat tests are all located in `/tests` at the root of the project. +Each subdirectory name corresponds to the version of the contract being tested, mirroring the `/contracts` directory +structure. Integration, regression, and other non-unit tests are placed into corresponding subdirectories, +e.g. `/tests/integration/`, ` /tests/regression`, etc. + +##### Tracing -`hardhat-tracer` is used to trace contract calls and state changes during tests. +During Hardhat tests, the `hardhat-tracer` is used to trace contract calls and state changes. Full-scale transaction tracing is disabled by default because it can significantly slow down the tests. +> [!NOTE] +> Tracing is ONLY supported in Hardhat unit tests and integration tests using Hardhat mainnet fork (see below). + To enable tracing, you need to wrap the code you want to trace with the `Tracer.enable()` and `Tracer.disable()` -functions: +functions and run the tests with the appropriate command postfix, e.g. `yarn test:trace`. ```typescript -import { Tracer } from 'test/suite'; +import { Tracer } from "test/suite"; -describe('MyContract', () => { - it('should do something', async () => { +describe("MyContract", () => { + it("should do something", async () => { Tracer.enable(); // code to trace Tracer.disable(); @@ -148,79 +158,63 @@ describe('MyContract', () => { }); ``` -Then run the tests with the following commands: +##### Unit tests -```bash -yarn test:trace # Run all tests with trace logging (calls only) -yarn test:fulltrace # Run all tests with full trace logging (calls and storage ops) -yarn test:integration:trace # Run all integration tests with trace logging -yarn test:integration:fulltrace # Run all integration tests with full trace logging -``` +Unit tests are located in `/tests` at the root of the project. +These tests are designed to verify the behavior of individual contracts and functions. +Naming conventions follow utilizes the `*.test.ts` postfix, e.g. `myContract.test.ts`. -> [!NOTE] -> Tracing is not supported in Foundry tests and integration tests other than Hardhat mainnet fork tests. +If you require mocks or wrappers for external contracts, please place them in the appropriate subdirectories, such as +`/tests/0.4.24/contracts` and adhere to the naming conventions: -#### Hardhat +- Use the `Mock` postfix for self-established contracts that simulate the behavior of the target contract. For example, + `MyContract_Mock.sol` or `MyContract_MockForAnotherContract.sol`. +- Use the `Harness` postfix for a wrapper that exposes private functions of a contract and may include test-specific + actions. For example, `MyContract_Wrapper.sol` or `MyContract_WrapperForAnotherContract.sol`. -Hardhat tests are all located in `/tests` at the root of the project. -Each subdirectory name corresponds to the version of the contract being tested, mirroring the `/contracts` directory -structure. Integration, regression, and other non-unit tests are placed into corresponding subdirectories, -e.g. `/tests/integration/`, ` /tests/regression`, etc. +You can run unit tests in multiple ways: ```bash yarn test # Run all tests in parallel yarn test:sequential # Run all tests sequentially -yarn test:trace # Run all tests with trace logging (see Tracing section) +yarn test:trace # Run all tests with trace logging (calls only) +yarn test:fulltrace # Run all tests with full trace logging (calls and storage ops) yarn test:watch # Run all tests in watch mode ``` -#### Foundry - -Foundry's Solidity tests are used only for fuzzing library contracts or functions performing complex calculations -or byte juggling. Solidity tests are located under ` / tests` and in the appropriate subdirectories. Naming conventions -follow the Foundry's [documentation](https://book.getfoundry.sh/tutorials/best-practices#general-test-guidance): - -- for tests, postfix `.t.sol` is used (e.g., `MyContract.t.sol`) -- for scripts, postfix `.s.sol` is used (e.g., `MyScript.s.sol`) -- for helpers, postfix `.h.sol` is used (e.g., `MyHelper.h.sol`). - -Following the convention of distinguishing Hardhat test files from Foundry-related files is essential to ensure the -proper execution of Hardhat tests. - -```bash -yarn test:foundry # Run all Foundry tests -``` - -#### Integration tests +##### Integration tests Integration tests are located in `/tests/integration` at the root of the project. These tests are used to verify the interaction between different contracts and their behavior in a real-world scenario. +Naming conventions follow the `*.int.ts` postfix, e.g. `myScenario.int.ts`. You can run integration tests in multiple ways, but for all of them, you need to have a `.env` file in the root of the project (you can use `.env.example` as a template). -##### Hardhat Mainnet Fork +###### Hardhat Mainnet Fork This is the most common way to run integration tests. It uses the Hardhat mainnet fork to simulate the mainnet environment. Requires `HARDHAT_FORKING_URL` and `HARDHAT_FORKING_BLOCK_NUMBER` (optional) to be set in the `.env` file -along with `MAINNET_*` env variables (see `.env.example`). +along with some `MAINNET_*` env variables (see `.env.example`). ```bash -yarn test:integration # Run all integration tests -yarn test:integration:trace # Run all integration tests with trace logging (see Tracing section) +yarn test:integration # Run all integration tests +yarn test:integration:trace # Run all integration tests with trace logging (calls only) +yarn test:integration:fulltrace # Run all integration tests with full trace logging (calls and storage ops) ``` -##### Local setup +###### Local setup This method is used to run integration tests against a local scratch deployment ( see [scratch-deploy.md](./docs/scratch-deploy.md)). -Requires `LOCAL_*` env variables to be set and a local deployment to be running on port `8555`. +Requires a local deployment to be running on port `8555` and `deployed-local.json` with the deployed addresses +(automatically generated during the scratch deployment). ```bash yarn test:integration:local ``` -##### Any fork setup +###### Any fork setup This method is used to run integration tests against any fork. Requires `MAINNET_*` env variables to be set in the `.env` file and a fork to be running on port `8545`. @@ -229,6 +223,23 @@ This method is used to run integration tests against any fork. Requires `MAINNET yarn test:integration:fork ``` +#### Foundry tests + +Foundry's Solidity tests are used only for fuzzing library contracts or functions performing complex calculations +or byte juggling. Solidity tests are located under ` / tests` and in the appropriate subdirectories. Naming conventions +follow the Foundry's [documentation](https://book.getfoundry.sh/tutorials/best-practices#general-test-guidance): + +- for tests, postfix `.t.sol` is used (e.g., `MyContract.t.sol`) +- for scripts, postfix `.s.sol` is used (e.g., `MyScript.s.sol`) +- for helpers, postfix `.h.sol` is used (e.g., `MyHelper.h.sol`). + +Following the convention of distinguishing Hardhat test files from Foundry-related files is essential to ensure the +proper execution of Hardhat tests. + +```bash +yarn test:foundry # Run all Foundry tests +``` + #### Coverage The project uses the `hardhat-coverage` plugin to generate coverage reports. diff --git a/contracts/0.8.9/LidoLocator.sol b/contracts/0.8.9/LidoLocator.sol index 07392a280..31d577a9f 100644 --- a/contracts/0.8.9/LidoLocator.sol +++ b/contracts/0.8.9/LidoLocator.sol @@ -1,9 +1,10 @@ // SPDX-FileCopyrightText: 2023 Lido // SPDX-License-Identifier: GPL-3.0 -/* See contracts/COMPILERS.md */ pragma solidity 0.8.9; +// solhint-disable immutable-vars-naming + import {ILidoLocator} from "../common/interfaces/ILidoLocator.sol"; /** @@ -28,6 +29,7 @@ contract LidoLocator is ILidoLocator { address withdrawalQueue; address withdrawalVault; address oracleDaemonConfig; + address wstEth; } error ZeroAddress(); @@ -46,6 +48,7 @@ contract LidoLocator is ILidoLocator { address public immutable withdrawalQueue; address public immutable withdrawalVault; address public immutable oracleDaemonConfig; + address public immutable wstEth; /** * @notice declare service locations @@ -67,9 +70,10 @@ contract LidoLocator is ILidoLocator { withdrawalQueue = _assertNonZero(_config.withdrawalQueue); withdrawalVault = _assertNonZero(_config.withdrawalVault); oracleDaemonConfig = _assertNonZero(_config.oracleDaemonConfig); + wstEth = _assertNonZero(_config.wstEth); } - function coreComponents() external view returns( + function coreComponents() external view returns ( address, address, address, @@ -87,7 +91,7 @@ contract LidoLocator is ILidoLocator { ); } - function oracleReportComponentsForLido() external view returns( + function oracleReportComponentsForLido() external view returns ( address, address, address, diff --git a/contracts/common/interfaces/ILidoLocator.sol b/contracts/common/interfaces/ILidoLocator.sol index a2bdc764d..de4e524a6 100644 --- a/contracts/common/interfaces/ILidoLocator.sol +++ b/contracts/common/interfaces/ILidoLocator.sol @@ -1,26 +1,30 @@ // SPDX-FileCopyrightText: 2023 Lido // SPDX-License-Identifier: GPL-3.0 -// See contracts/COMPILERS.md // solhint-disable-next-line pragma solidity >=0.4.24 <0.9.0; interface ILidoLocator { - function accountingOracle() external view returns(address); - function depositSecurityModule() external view returns(address); - function elRewardsVault() external view returns(address); - function legacyOracle() external view returns(address); - function lido() external view returns(address); - function oracleReportSanityChecker() external view returns(address); - function burner() external view returns(address); - function stakingRouter() external view returns(address); - function treasury() external view returns(address); - function validatorsExitBusOracle() external view returns(address); - function withdrawalQueue() external view returns(address); - function withdrawalVault() external view returns(address); - function postTokenRebaseReceiver() external view returns(address); - function oracleDaemonConfig() external view returns(address); - function coreComponents() external view returns( + + function accountingOracle() external view returns (address); + function depositSecurityModule() external view returns (address); + function elRewardsVault() external view returns (address); + function legacyOracle() external view returns (address); + function lido() external view returns (address); + function oracleReportSanityChecker() external view returns (address); + function burner() external view returns (address); + function stakingRouter() external view returns (address); + function treasury() external view returns (address); + function validatorsExitBusOracle() external view returns (address); + function withdrawalQueue() external view returns (address); + function withdrawalVault() external view returns (address); + function postTokenRebaseReceiver() external view returns (address); + function oracleDaemonConfig() external view returns (address); + function wstEth() external view returns (address); + + /// @dev Returns a batch of core components addresses at once. + /// It's just a more gas-efficient way of calling several public getters at once. + function coreComponents() external view returns ( address elRewardsVault, address oracleReportSanityChecker, address stakingRouter, @@ -28,7 +32,10 @@ interface ILidoLocator { address withdrawalQueue, address withdrawalVault ); - function oracleReportComponentsForLido() external view returns( + + /// @dev Returns a batch of addresses that is used specifically during oracle report handling in the Lido contract. + /// It's just a more gas-efficient way of calling several public getters at once. + function oracleReportComponentsForLido() external view returns ( address accountingOracle, address elRewardsVault, address oracleReportSanityChecker, diff --git a/lib/deploy.ts b/lib/deploy.ts index ae947e996..74c6792fe 100644 --- a/lib/deploy.ts +++ b/lib/deploy.ts @@ -54,7 +54,7 @@ async function getDeployTxParams(deployer: string) { maxFeePerGas: ethers.parseUnits(String(GAS_MAX_FEE), "gwei"), }; } else { - throw new Error("Must specify gas ENV vars: \"GAS_PRIORITY_FEE\" and \"GAS_MAX_FEE\" in gwei (like just \"3\")"); + throw new Error('Must specify gas ENV vars: "GAS_PRIORITY_FEE" and "GAS_MAX_FEE" in gwei (like just "3")'); } } diff --git a/lib/event.ts b/lib/event.ts index 09406645a..1a9a65a5f 100644 --- a/lib/event.ts +++ b/lib/event.ts @@ -42,11 +42,15 @@ const parseLogEntry = (entry: Log, interfaces: Interface[]): LogDescription | nu return null; }; -export function findEventsWithInterfaces(receipt: ContractTransactionReceipt, eventName: string, interfaces: Interface[]): LogDescription[] { +export function findEventsWithInterfaces( + receipt: ContractTransactionReceipt, + eventName: string, + interfaces: Interface[], +): LogDescription[] { const events: LogDescription[] = []; const notParsedLogs: Log[] = []; - receipt.logs.forEach(entry => { + receipt.logs.forEach((entry) => { const logDescription = parseLogEntry(entry, interfaces); if (logDescription) { events.push(logDescription); @@ -59,7 +63,7 @@ export function findEventsWithInterfaces(receipt: ContractTransactionReceipt, ev // log.warning("The following logs could not be parsed:", notParsedLogs); } - return events.filter(e => e.name === eventName); + return events.filter((e) => e.name === eventName); } export function findEvents(receipt: ContractTransactionReceipt, eventName: string) { diff --git a/lib/protocol/context.ts b/lib/protocol/context.ts index 0fae96c37..35a8965ff 100644 --- a/lib/protocol/context.ts +++ b/lib/protocol/context.ts @@ -13,7 +13,7 @@ const getSigner = async (signer: Signer, balance = ether("100"), signers: Protoc export const getProtocolContext = async (): Promise => { const { contracts, signers } = await discover(); - const interfaces = Object.values(contracts).map(contract => contract.interface); + const interfaces = Object.values(contracts).map((contract) => contract.interface); // By default, all flags are "on" const flags = { @@ -30,7 +30,8 @@ export const getProtocolContext = async (): Promise => { interfaces, flags, getSigner: async (signer: Signer, balance?: bigint) => getSigner(signer, balance, signers), - getEvents: (receipt: ContractTransactionReceipt, eventName: string) => findEventsWithInterfaces(receipt, eventName, interfaces), + getEvents: (receipt: ContractTransactionReceipt, eventName: string) => + findEventsWithInterfaces(receipt, eventName, interfaces), } as ProtocolContext; await provision(context); diff --git a/lib/protocol/discover.ts b/lib/protocol/discover.ts index ee99d8de6..f090a40be 100644 --- a/lib/protocol/discover.ts +++ b/lib/protocol/discover.ts @@ -64,39 +64,39 @@ const getFoundationContracts = async (locator: LoadedContract, conf (await batch({ accountingOracle: loadContract( "AccountingOracle", - config.get("accountingOracle") || await locator.accountingOracle(), + config.get("accountingOracle") || (await locator.accountingOracle()), ), depositSecurityModule: loadContract( "DepositSecurityModule", - config.get("depositSecurityModule") || await locator.depositSecurityModule(), + config.get("depositSecurityModule") || (await locator.depositSecurityModule()), ), elRewardsVault: loadContract( "LidoExecutionLayerRewardsVault", - config.get("elRewardsVault") || await locator.elRewardsVault(), + config.get("elRewardsVault") || (await locator.elRewardsVault()), ), - legacyOracle: loadContract("LegacyOracle", config.get("legacyOracle") || await locator.legacyOracle()), - lido: loadContract("Lido", config.get("lido") || await locator.lido()), + legacyOracle: loadContract("LegacyOracle", config.get("legacyOracle") || (await locator.legacyOracle())), + lido: loadContract("Lido", config.get("lido") || (await locator.lido())), oracleReportSanityChecker: loadContract( "OracleReportSanityChecker", - config.get("oracleReportSanityChecker") || await locator.oracleReportSanityChecker(), + config.get("oracleReportSanityChecker") || (await locator.oracleReportSanityChecker()), ), - burner: loadContract("Burner", config.get("burner") || await locator.burner()), - stakingRouter: loadContract("StakingRouter", config.get("stakingRouter") || await locator.stakingRouter()), + burner: loadContract("Burner", config.get("burner") || (await locator.burner())), + stakingRouter: loadContract("StakingRouter", config.get("stakingRouter") || (await locator.stakingRouter())), validatorsExitBusOracle: loadContract( "ValidatorsExitBusOracle", - config.get("validatorsExitBusOracle") || await locator.validatorsExitBusOracle(), + config.get("validatorsExitBusOracle") || (await locator.validatorsExitBusOracle()), ), withdrawalQueue: loadContract( "WithdrawalQueueERC721", - config.get("withdrawalQueue") || await locator.withdrawalQueue(), + config.get("withdrawalQueue") || (await locator.withdrawalQueue()), ), withdrawalVault: loadContract( "WithdrawalVault", - config.get("withdrawalVault") || await locator.withdrawalVault(), + config.get("withdrawalVault") || (await locator.withdrawalVault()), ), oracleDaemonConfig: loadContract( "OracleDaemonConfig", - config.get("oracleDaemonConfig") || await locator.oracleDaemonConfig(), + config.get("oracleDaemonConfig") || (await locator.oracleDaemonConfig()), ), })) as CoreContracts; @@ -104,11 +104,11 @@ const getFoundationContracts = async (locator: LoadedContract, conf * Load Aragon contracts required for protocol. */ const getAragonContracts = async (lido: LoadedContract, config: ProtocolNetworkConfig) => { - const kernelAddress = config.get("kernel") || await lido.kernel(); + const kernelAddress = config.get("kernel") || (await lido.kernel()); const kernel = await loadContract("Kernel", kernelAddress); return (await batch({ kernel: new Promise((resolve) => resolve(kernel)), // Avoiding double loading - acl: loadContract("ACL", config.get("acl") || await kernel.acl()), + acl: loadContract("ACL", config.get("acl") || (await kernel.acl())), })) as AragonContracts; }; @@ -127,7 +127,7 @@ const getStakingModules = async (stakingRouter: LoadedContract, c * Load HashConsensus contract for accounting oracle. */ const getHashConsensus = async (accountingOracle: LoadedContract, config: ProtocolNetworkConfig) => { - const hashConsensusAddress = config.get("hashConsensus") || await accountingOracle.getConsensusContract(); + const hashConsensusAddress = config.get("hashConsensus") || (await accountingOracle.getConsensusContract()); return (await batch({ hashConsensus: loadContract("HashConsensus", hashConsensusAddress), })) as HashConsensusContracts; diff --git a/lib/protocol/helpers/accounting.ts b/lib/protocol/helpers/accounting.ts index a531ebaa4..0cd20b441 100644 --- a/lib/protocol/helpers/accounting.ts +++ b/lib/protocol/helpers/accounting.ts @@ -385,19 +385,17 @@ export const handleOracleReport = async ( "El Rewards Vault Balance": ethers.formatEther(elRewardsVaultBalance), }); - const handleReportTx = await lido - .connect(accountingOracleAccount) - .handleOracleReport( - reportTimestamp, - 1n * 24n * 60n * 60n, // 1 day - beaconValidators, - clBalance, - withdrawalVaultBalance, - elRewardsVaultBalance, - sharesRequestedToBurn, - [], - 0n, - ); + const handleReportTx = await lido.connect(accountingOracleAccount).handleOracleReport( + reportTimestamp, + 1n * 24n * 60n * 60n, // 1 day + beaconValidators, + clBalance, + withdrawalVaultBalance, + elRewardsVaultBalance, + sharesRequestedToBurn, + [], + 0n, + ); await trace("lido.handleOracleReport", handleReportTx); } catch (error) { @@ -621,10 +619,7 @@ export const submitReport = async ( /** * Ensure that the oracle committee has the required number of members. */ -export const ensureOracleCommitteeMembers = async ( - ctx: ProtocolContext, - minMembersCount = MIN_MEMBERS_COUNT, -) => { +export const ensureOracleCommitteeMembers = async (ctx: ProtocolContext, minMembersCount = MIN_MEMBERS_COUNT) => { const { hashConsensus } = ctx.contracts; const members = await hashConsensus.getFastLaneMembers(); diff --git a/lib/protocol/helpers/index.ts b/lib/protocol/helpers/index.ts index 7bac22b1f..14b1fdfb0 100644 --- a/lib/protocol/helpers/index.ts +++ b/lib/protocol/helpers/index.ts @@ -1,13 +1,6 @@ -export { - unpauseStaking, - ensureStakeLimit, -} from "./staking"; - +export { unpauseStaking, ensureStakeLimit } from "./staking"; -export { - unpauseWithdrawalQueue, - finalizeWithdrawalQueue, -} from "./withdrawal"; +export { unpauseWithdrawalQueue, finalizeWithdrawalQueue } from "./withdrawal"; export { OracleReportOptions, @@ -20,10 +13,6 @@ export { report, } from "./accounting"; -export { - sdvtEnsureOperators, -} from "./sdvt.helper"; +export { sdvtEnsureOperators } from "./sdvt.helper"; -export { - norEnsureOperators, -} from "./nor.helper"; +export { norEnsureOperators } from "./nor.helper"; diff --git a/lib/protocol/helpers/nor.helper.ts b/lib/protocol/helpers/nor.helper.ts index 4c11d0511..c37cf5efa 100644 --- a/lib/protocol/helpers/nor.helper.ts +++ b/lib/protocol/helpers/nor.helper.ts @@ -201,8 +201,11 @@ const norSetOperatorStakingLimit = async ( log.success(`Set NOR operator ${operatorId} staking limit`); }; -export const getOperatorName = (module: StakingModuleName, id: bigint, group: bigint = 0n) => `${module}:op-${group}-${id}`; +export const getOperatorName = (module: StakingModuleName, id: bigint, group: bigint = 0n) => + `${module}:op-${group}-${id}`; -export const getOperatorRewardAddress = (module: StakingModuleName, id: bigint, group: bigint = 0n) => certainAddress(`${module}:op:ra-${group}-${id}`); +export const getOperatorRewardAddress = (module: StakingModuleName, id: bigint, group: bigint = 0n) => + certainAddress(`${module}:op:ra-${group}-${id}`); -export const getOperatorManagerAddress = (module: StakingModuleName, id: bigint, group: bigint = 0n) => certainAddress(`${module}:op:ma-${group}-${id}`); +export const getOperatorManagerAddress = (module: StakingModuleName, id: bigint, group: bigint = 0n) => + certainAddress(`${module}:op:ma-${group}-${id}`); diff --git a/lib/protocol/helpers/withdrawal.ts b/lib/protocol/helpers/withdrawal.ts index 1b9ed67ce..43315298b 100644 --- a/lib/protocol/helpers/withdrawal.ts +++ b/lib/protocol/helpers/withdrawal.ts @@ -65,16 +65,12 @@ export const finalizeWithdrawalQueue = async ( "Last request ID": lastRequestId, }); - const submitTx = await ctx.contracts.lido - .connect(ethHolder) - .submit(ZeroAddress, { value: ether("10000") }); + const submitTx = await ctx.contracts.lido.connect(ethHolder).submit(ZeroAddress, { value: ether("10000") }); await trace("lido.submit", submitTx); } - const submitTx = await ctx.contracts.lido - .connect(ethHolder) - .submit(ZeroAddress, { value: ether("10000") }); + const submitTx = await ctx.contracts.lido.connect(ethHolder).submit(ZeroAddress, { value: ether("10000") }); await trace("lido.submit", submitTx); diff --git a/lib/protocol/networks.ts b/lib/protocol/networks.ts index 5675c946e..34314ade8 100644 --- a/lib/protocol/networks.ts +++ b/lib/protocol/networks.ts @@ -19,8 +19,7 @@ export class ProtocolNetworkConfig { constructor( public readonly env: Record, public readonly defaults: Record, - ) { - } + ) {} get(key: keyof ProtocolNetworkItems): string { return process.env[this.env[key]] || this.defaults[key] || ""; @@ -46,6 +45,7 @@ const defaultEnv = { withdrawalQueue: "WITHDRAWAL_QUEUE_ADDRESS", withdrawalVault: "WITHDRAWAL_VAULT_ADDRESS", oracleDaemonConfig: "ORACLE_DAEMON_CONFIG_ADDRESS", + wstEth: "WST_ETH_ADDRESS", // aragon contracts kernel: "ARAGON_KERNEL_ADDRESS", acl: "ARAGON_ACL_ADDRESS", @@ -57,14 +57,10 @@ const defaultEnv = { } as ProtocolNetworkItems; const getPrefixedEnv = (prefix: string, obj: Record): Record => - Object.fromEntries( - Object.entries(obj).map(([key, value]) => [key, `${prefix}_${value}`]), - ); + Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, `${prefix}_${value}`])); const getDefaults = (obj: Record): Record => - Object.fromEntries( - Object.entries(obj).map(([key]) => [key, ""]), - ); + Object.fromEntries(Object.entries(obj).map(([key]) => [key, ""])); export async function getNetworkConfig(network: string): Promise { const defaults = getDefaults(defaultEnv) as Record; @@ -72,34 +68,28 @@ export async function getNetworkConfig(network: string): Promise { - await ensureHashConsensusInitialEpoch(ctx); await ensureOracleCommitteeMembers(ctx, 5n); diff --git a/lib/protocol/types.ts b/lib/protocol/types.ts index 192b1a3a8..7c3176169 100644 --- a/lib/protocol/types.ts +++ b/lib/protocol/types.ts @@ -20,6 +20,7 @@ import { ValidatorsExitBusOracle, WithdrawalQueueERC721, WithdrawalVault, + WstETH, } from "typechain-types"; export type ProtocolNetworkItems = { @@ -41,6 +42,7 @@ export type ProtocolNetworkItems = { withdrawalQueue: string; withdrawalVault: string; oracleDaemonConfig: string; + wstEth: string; // aragon contracts kernel: string; acl: string; @@ -65,6 +67,7 @@ export interface ContractTypes { WithdrawalQueueERC721: WithdrawalQueueERC721; WithdrawalVault: WithdrawalVault; OracleDaemonConfig: OracleDaemonConfig; + WstETH: WstETH; Kernel: Kernel; ACL: ACL; HashConsensus: HashConsensus; @@ -93,6 +96,7 @@ export type CoreContracts = { withdrawalQueue: LoadedContract; withdrawalVault: LoadedContract; oracleDaemonConfig: LoadedContract; + wstEth: LoadedContract; }; export type AragonContracts = { @@ -111,11 +115,10 @@ export type HashConsensusContracts = { hashConsensus: LoadedContract; }; -export type ProtocolContracts = { locator: LoadedContract } - & CoreContracts - & AragonContracts - & StakingModuleContracts - & HashConsensusContracts; +export type ProtocolContracts = { locator: LoadedContract } & CoreContracts & + AragonContracts & + StakingModuleContracts & + HashConsensusContracts; export type ProtocolSigners = { agent: string; @@ -127,7 +130,7 @@ export type Signer = keyof ProtocolSigners; export type ProtocolContextFlags = { withSimpleDvtModule: boolean; -} +}; export type ProtocolContext = { contracts: ProtocolContracts; diff --git a/package.json b/package.json index d6f783c75..fcdc028e0 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,9 @@ ], "./**/*.{ts,md,json}": [ "prettier --write" + ], + "./test/**/*.sol": [ + "prettier --write" ] }, "devDependencies": { @@ -44,7 +47,7 @@ "@eslint/compat": "^1.1.1", "@eslint/js": "^9.9.0", "@nomicfoundation/hardhat-chai-matchers": "^2.0.7", - "@nomicfoundation/hardhat-ethers": "^3.0.6", + "@nomicfoundation/hardhat-ethers": "^3.0.7", "@nomicfoundation/hardhat-ignition": "^0.15.5", "@nomicfoundation/hardhat-ignition-ethers": "^0.15.5", "@nomicfoundation/hardhat-network-helpers": "^1.0.11", @@ -57,29 +60,30 @@ "@types/eslint": "^9.6.0", "@types/eslint__js": "^8.42.3", "@types/mocha": "10.0.7", - "@types/node": "20.14.15", + "@types/node": "20.16.1", "bigint-conversion": "^2.4.3", "chai": "^4.5.0", "chalk": "^4.1.2", "dotenv": "^16.4.5", "eslint": "^9.9.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-no-only-tests": "^3.1.0", + "eslint-plugin-no-only-tests": "^3.3.0", "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-simple-import-sort": "12.1.1", "ethereumjs-util": "^7.1.5", "ethers": "^6.13.2", "glob": "^11.0.0", "globals": "^15.9.0", - "hardhat": "^2.22.8", + "hardhat": "^2.22.9", "hardhat-contract-sizer": "^2.10.0", "hardhat-gas-reporter": "^1.0.10", "hardhat-ignore-warnings": "^0.2.11", "hardhat-tracer": "3.1.0", "hardhat-watcher": "2.5.0", - "husky": "^9.1.4", - "lint-staged": "^15.2.8", + "husky": "^9.1.5", + "lint-staged": "^15.2.9", "prettier": "^3.3.3", + "prettier-plugin-solidity": "^1.4.1", "solhint": "^5.0.3", "solhint-plugin-lido": "^0.0.4", "solidity-coverage": "^0.8.12", @@ -87,7 +91,7 @@ "tsconfig-paths": "^4.2.0", "typechain": "^8.3.2", "typescript": "^5.5.4", - "typescript-eslint": "^8.0.1" + "typescript-eslint": "^8.2.0" }, "dependencies": { "@aragon/apps-agent": "2.1.0", diff --git a/scripts/scratch/steps/09-deploy-non-aragon-contracts.ts b/scripts/scratch/steps/09-deploy-non-aragon-contracts.ts index 0407a852a..e26732357 100644 --- a/scripts/scratch/steps/09-deploy-non-aragon-contracts.ts +++ b/scripts/scratch/steps/09-deploy-non-aragon-contracts.ts @@ -301,6 +301,7 @@ async function main() { withdrawalQueueERC721.address, withdrawalVaultAddress, oracleDaemonConfig.address, + wstETH.address, ]; await updateProxyImplementation(Sk.lidoLocator, "LidoLocator", locator.address, proxyContractsOwner, [locatorConfig]); diff --git a/scripts/upgrade/deploy-locator.ts b/scripts/upgrade/deploy-locator.ts index 614bce889..25ec12e33 100644 --- a/scripts/upgrade/deploy-locator.ts +++ b/scripts/upgrade/deploy-locator.ts @@ -19,6 +19,7 @@ const VIEW_NAMES_AND_CTOR_ARGS = [ "withdrawalQueue", "withdrawalVault", "oracleDaemonConfig", + "wstEth", ]; /////////////// GLOBAL VARIABLES /////////////// @@ -52,12 +53,14 @@ async function main() { const newOrCurrent = async (name: string) => { return await getNewFromEnvOrCurrent(name, locator); }; + const ctorArgs = await Promise.all(VIEW_NAMES_AND_CTOR_ARGS.map(newOrCurrent)); if (Object.keys(g_newAddresses).length === 0) { log(`No new addresses specified: exiting doing nothing`); process.exit(0); } + log.splitter(); for (const name in g_newAddresses) { log(`(!) "${name}" new address: ${g_newAddresses[name]}`); diff --git a/test/0.4.24/contracts/AccountingOracle__MockForLegacyOracle.sol b/test/0.4.24/contracts/AccountingOracle__MockForLegacyOracle.sol index b5e8d0669..6361bf3c2 100644 --- a/test/0.4.24/contracts/AccountingOracle__MockForLegacyOracle.sol +++ b/test/0.4.24/contracts/AccountingOracle__MockForLegacyOracle.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity >=0.4.24 <0.9.0; import {AccountingOracle, ILido} from "contracts/0.8.9/oracle/AccountingOracle.sol"; @@ -29,10 +30,7 @@ contract AccountingOracle__MockForLegacyOracle { return ITimeProvider(CONSENSUS_CONTRACT).getTime(); } - function submitReportData( - AccountingOracle.ReportData calldata data, - uint256 /* contractVersion */ - ) external { + function submitReportData(AccountingOracle.ReportData calldata data, uint256 /* contractVersion */) external { uint256 slotsElapsed = data.refSlot - _lastRefSlot; _lastRefSlot = data.refSlot; diff --git a/test/0.4.24/contracts/Burner__MockForLidoHandleOracleReport.sol b/test/0.4.24/contracts/Burner__MockForLidoHandleOracleReport.sol index a73ea84a1..1ad3e2711 100644 --- a/test/0.4.24/contracts/Burner__MockForLidoHandleOracleReport.sol +++ b/test/0.4.24/contracts/Burner__MockForLidoHandleOracleReport.sol @@ -1,26 +1,27 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; contract Burner__MockForLidoHandleOracleReport { - event StETHBurnRequested( - bool indexed isCover, - address indexed requestedBy, - uint256 amountOfStETH, - uint256 amountOfShares - ); + event StETHBurnRequested( + bool indexed isCover, + address indexed requestedBy, + uint256 amountOfStETH, + uint256 amountOfShares + ); - event Mock__CommitSharesToBurnWasCalled(); + event Mock__CommitSharesToBurnWasCalled(); - function requestBurnShares(address _from, uint256 _sharesAmountToBurn) external { - // imitating share to steth rate 1:2 - uint256 _stETHAmount = _sharesAmountToBurn * 2; - emit StETHBurnRequested(false, msg.sender, _stETHAmount, _sharesAmountToBurn); - } + function requestBurnShares(address _from, uint256 _sharesAmountToBurn) external { + // imitating share to steth rate 1:2 + uint256 _stETHAmount = _sharesAmountToBurn * 2; + emit StETHBurnRequested(false, msg.sender, _stETHAmount, _sharesAmountToBurn); + } - function commitSharesToBurn(uint256 _sharesToBurn) external { - _sharesToBurn; + function commitSharesToBurn(uint256 _sharesToBurn) external { + _sharesToBurn; - emit Mock__CommitSharesToBurnWasCalled(); - } + emit Mock__CommitSharesToBurnWasCalled(); + } } diff --git a/test/0.4.24/contracts/HashConsensus__MockForLegacyOracle.sol b/test/0.4.24/contracts/HashConsensus__HarnessForLegacyOracle.sol similarity index 70% rename from test/0.4.24/contracts/HashConsensus__MockForLegacyOracle.sol rename to test/0.4.24/contracts/HashConsensus__HarnessForLegacyOracle.sol index b0bc31c08..ad4826a6b 100644 --- a/test/0.4.24/contracts/HashConsensus__MockForLegacyOracle.sol +++ b/test/0.4.24/contracts/HashConsensus__HarnessForLegacyOracle.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only -pragma solidity >=0.4.24 <0.9.0; -import {IHashConsensus} from "contracts/0.4.24/oracle/LegacyOracle.sol"; +pragma solidity 0.4.24; -contract HashConsensus__MockForLegacyOracle is IHashConsensus { +import {IHashConsensus} from "contracts/0.4.24/oracle/LegacyOracle.sol"; +contract HashConsensus__HarnessForLegacyOracle is IHashConsensus { uint256 internal _time = 2513040315; /// Chain specification @@ -46,16 +46,8 @@ contract HashConsensus__MockForLegacyOracle is IHashConsensus { _setFrameConfig(initialEpoch, epochsPerFrame, fastLaneLengthSlots); } - function _setFrameConfig( - uint256 initialEpoch, - uint256 epochsPerFrame, - uint256 fastLaneLengthSlots - ) internal { - _frameConfig = FrameConfig( - uint64(initialEpoch), - uint64(epochsPerFrame), - uint64(fastLaneLengthSlots) - ); + function _setFrameConfig(uint256 initialEpoch, uint256 epochsPerFrame, uint256 fastLaneLengthSlots) internal { + _frameConfig = FrameConfig(uint64(initialEpoch), uint64(epochsPerFrame), uint64(fastLaneLengthSlots)); } function setTime(uint256 newTime) external { @@ -70,26 +62,20 @@ contract HashConsensus__MockForLegacyOracle is IHashConsensus { return _time; } - function getChainConfig() external view returns ( - uint256 slotsPerEpoch, - uint256 secondsPerSlot, - uint256 genesisTime - ) { + function getChainConfig() + external + view + returns (uint256 slotsPerEpoch, uint256 secondsPerSlot, uint256 genesisTime) + { return (SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME); } - function getFrameConfig() external view returns ( - uint256 initialEpoch, - uint256 epochsPerFrame - ) { + function getFrameConfig() external view returns (uint256 initialEpoch, uint256 epochsPerFrame) { FrameConfig memory config = _frameConfig; return (config.initialEpoch, config.epochsPerFrame); } - function getCurrentFrame() external view returns ( - uint256 refSlot, - uint256 reportProcessingDeadlineSlot - ) { + function getCurrentFrame() external view returns (uint256 refSlot, uint256 reportProcessingDeadlineSlot) { ConsensusFrame memory frame = _getCurrentFrame(); return (frame.refSlot, frame.reportProcessingDeadlineSlot); } @@ -98,15 +84,14 @@ contract HashConsensus__MockForLegacyOracle is IHashConsensus { return _getFrameAtTimestamp(_getTime(), _frameConfig); } - function _getFrameAtTimestamp(uint256 timestamp, FrameConfig memory config) - internal view returns (ConsensusFrame memory) - { + function _getFrameAtTimestamp( + uint256 timestamp, + FrameConfig memory config + ) internal view returns (ConsensusFrame memory) { return _getFrameAtIndex(_computeFrameIndex(timestamp, config), config); } - function _computeFrameIndex(uint256 timestamp, FrameConfig memory config) - internal view returns (uint256) - { + function _computeFrameIndex(uint256 timestamp, FrameConfig memory config) internal view returns (uint256) { uint256 epoch = _computeEpochAtTimestamp(timestamp); return (epoch - config.initialEpoch) / config.epochsPerFrame; } @@ -115,18 +100,20 @@ contract HashConsensus__MockForLegacyOracle is IHashConsensus { return _computeEpochAtSlot(_computeSlotAtTimestamp(timestamp)); } - function _getFrameAtIndex(uint256 frameIndex, FrameConfig memory config) - internal view returns (ConsensusFrame memory) - { + function _getFrameAtIndex( + uint256 frameIndex, + FrameConfig memory config + ) internal view returns (ConsensusFrame memory) { uint256 frameStartEpoch = _computeStartEpochOfFrameWithIndex(frameIndex, config); uint256 frameStartSlot = _computeStartSlotAtEpoch(frameStartEpoch); uint256 nextFrameStartSlot = frameStartSlot + config.epochsPerFrame * SLOTS_PER_EPOCH; - return ConsensusFrame({ - index: frameIndex, - refSlot: uint64(frameStartSlot - 1), - reportProcessingDeadlineSlot: uint64(nextFrameStartSlot - 1 - DEADLINE_SLOT_OFFSET) - }); + return + ConsensusFrame({ + index: frameIndex, + refSlot: uint64(frameStartSlot - 1), + reportProcessingDeadlineSlot: uint64(nextFrameStartSlot - 1 - DEADLINE_SLOT_OFFSET) + }); } // Math @@ -145,9 +132,10 @@ contract HashConsensus__MockForLegacyOracle is IHashConsensus { return epoch * SLOTS_PER_EPOCH; } - function _computeStartEpochOfFrameWithIndex(uint256 frameIndex, FrameConfig memory config) - internal pure returns (uint256) - { + function _computeStartEpochOfFrameWithIndex( + uint256 frameIndex, + FrameConfig memory config + ) internal pure returns (uint256) { return config.initialEpoch + frameIndex * config.epochsPerFrame; } diff --git a/test/0.4.24/contracts/LegacyOracle__Harness.sol b/test/0.4.24/contracts/LegacyOracle__Harness.sol index 696aaa8b1..d0bfdf85a 100644 --- a/test/0.4.24/contracts/LegacyOracle__Harness.sol +++ b/test/0.4.24/contracts/LegacyOracle__Harness.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; import {LegacyOracle} from "contracts/0.4.24/oracle/LegacyOracle.sol"; @@ -9,7 +10,6 @@ interface ITimeProvider { } contract LegacyOracle__Harness is LegacyOracle { - // @dev this is a way to not use block.timestamp in the tests function _getTime() internal view returns (uint256) { address accountingOracle = ACCOUNTING_ORACLE_POSITION.getStorageAddress(); diff --git a/test/0.4.24/contracts/LegacyOracle__MockForAccountingOracle.sol b/test/0.4.24/contracts/LegacyOracle__MockForAccountingOracle.sol index ecac6e535..ad158c8a9 100644 --- a/test/0.4.24/contracts/LegacyOracle__MockForAccountingOracle.sol +++ b/test/0.4.24/contracts/LegacyOracle__MockForAccountingOracle.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.4.24; @@ -7,12 +6,10 @@ pragma solidity 0.4.24; import "contracts/0.4.24/oracle/LegacyOracle.sol"; interface ILegacyOracle { - function getBeaconSpec() external view returns ( - uint64 epochsPerFrame, - uint64 slotsPerEpoch, - uint64 secondsPerSlot, - uint64 genesisTime - ); + function getBeaconSpec() + external + view + returns (uint64 epochsPerFrame, uint64 slotsPerEpoch, uint64 secondsPerSlot, uint64 genesisTime); function getLastCompletedEpochId() external view returns (uint256); } @@ -21,9 +18,7 @@ interface ITimeProvider { function getTime() external view returns (uint256); } - contract LegacyOracle__MockForAccountingOracle is ILegacyOracle, LegacyOracle { - struct HandleConsensusLayerReportCallData { uint256 totalCalls; uint256 refSlot; @@ -33,14 +28,11 @@ contract LegacyOracle__MockForAccountingOracle is ILegacyOracle, LegacyOracle { HandleConsensusLayerReportCallData public lastCall__handleConsensusLayerReport; - - function getBeaconSpec() external view returns ( - uint64 epochsPerFrame, - uint64 slotsPerEpoch, - uint64 secondsPerSlot, - uint64 genesisTime - ) { - + function getBeaconSpec() + external + view + returns (uint64 epochsPerFrame, uint64 slotsPerEpoch, uint64 secondsPerSlot, uint64 genesisTime) + { ChainSpec memory spec = _getChainSpec(); epochsPerFrame = spec.epochsPerFrame; slotsPerEpoch = spec.slotsPerEpoch; @@ -48,14 +40,15 @@ contract LegacyOracle__MockForAccountingOracle is ILegacyOracle, LegacyOracle { genesisTime = spec.genesisTime; } - function setBeaconSpec(uint64 epochsPerFrame, + function setBeaconSpec( + uint64 epochsPerFrame, uint64 slotsPerEpoch, uint64 secondsPerSlot, - uint64 genesisTime) external { + uint64 genesisTime + ) external { _setChainSpec(ChainSpec(epochsPerFrame, slotsPerEpoch, secondsPerSlot, genesisTime)); } - function _getTime() internal view returns (uint256) { address accountingOracle = ACCOUNTING_ORACLE_POSITION.getStorageAddress(); return ITimeProvider(accountingOracle).getTime(); @@ -65,16 +58,13 @@ contract LegacyOracle__MockForAccountingOracle is ILegacyOracle, LegacyOracle { return _getTime(); } - function handleConsensusLayerReport(uint256 refSlot, uint256 clBalance, uint256 clValidators) - external - { + function handleConsensusLayerReport(uint256 refSlot, uint256 clBalance, uint256 clValidators) external { ++lastCall__handleConsensusLayerReport.totalCalls; lastCall__handleConsensusLayerReport.refSlot = refSlot; lastCall__handleConsensusLayerReport.clBalance = clBalance; lastCall__handleConsensusLayerReport.clValidators = clValidators; } - function setParams( uint64 epochsPerFrame, uint64 slotsPerEpoch, @@ -102,5 +92,4 @@ contract LegacyOracle__MockForAccountingOracle is ILegacyOracle, LegacyOracle { function setLido(address lido) external { LIDO_POSITION.setStorageAddress(lido); } - } diff --git a/test/0.4.24/contracts/LidoExecutionLayerRewardsVault__MockForLidoHandleOracleReport.sol b/test/0.4.24/contracts/LidoExecutionLayerRewardsVault__MockForLidoHandleOracleReport.sol index b8ee26050..8995cf13a 100644 --- a/test/0.4.24/contracts/LidoExecutionLayerRewardsVault__MockForLidoHandleOracleReport.sol +++ b/test/0.4.24/contracts/LidoExecutionLayerRewardsVault__MockForLidoHandleOracleReport.sol @@ -1,13 +1,14 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; contract LidoExecutionLayerRewardsVault__MockForLidoHandleOracleReport { - event Mock__RewardsWithdrawn(); + event Mock__RewardsWithdrawn(); - function withdrawRewards(uint256 _maxAmount) external returns (uint256 amount) { - // emiting mock event to test that the function was in fact called - emit Mock__RewardsWithdrawn(); - return _maxAmount; - } + function withdrawRewards(uint256 _maxAmount) external returns (uint256 amount) { + // emitting mock event to test that the function was in fact called + emit Mock__RewardsWithdrawn(); + return _maxAmount; + } } diff --git a/test/0.4.24/contracts/LidoLocator__MutableMock.sol b/test/0.4.24/contracts/LidoLocator__MutableMock.sol deleted file mode 100644 index c717ab7ed..000000000 --- a/test/0.4.24/contracts/LidoLocator__MutableMock.sol +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// for testing purposes only -pragma solidity 0.8.9; - -contract LidoLocator__MutableMock { - struct Config { - address accountingOracle; - address depositSecurityModule; - address elRewardsVault; - address legacyOracle; - address lido; - address oracleReportSanityChecker; - address postTokenRebaseReceiver; - address burner; - address stakingRouter; - address treasury; - address validatorsExitBusOracle; - address withdrawalQueue; - address withdrawalVault; - address oracleDaemonConfig; - } - - error ZeroAddress(); - - address public accountingOracle; - address public immutable depositSecurityModule; - address public immutable elRewardsVault; - address public immutable legacyOracle; - address public immutable lido; - address public immutable oracleReportSanityChecker; - address public postTokenRebaseReceiver; - address public immutable burner; - address public immutable stakingRouter; - address public immutable treasury; - address public immutable validatorsExitBusOracle; - address public immutable withdrawalQueue; - address public immutable withdrawalVault; - address public immutable oracleDaemonConfig; - - /** - * @notice declare service locations - * @dev accepts a struct to avoid the "stack-too-deep" error - * @param _config struct of addresses - */ - constructor(Config memory _config) { - accountingOracle = _assertNonZero(_config.accountingOracle); - depositSecurityModule = _assertNonZero(_config.depositSecurityModule); - elRewardsVault = _assertNonZero(_config.elRewardsVault); - legacyOracle = _assertNonZero(_config.legacyOracle); - lido = _assertNonZero(_config.lido); - oracleReportSanityChecker = _assertNonZero(_config.oracleReportSanityChecker); - postTokenRebaseReceiver = _assertNonZero(_config.postTokenRebaseReceiver); - burner = _assertNonZero(_config.burner); - stakingRouter = _assertNonZero(_config.stakingRouter); - treasury = _assertNonZero(_config.treasury); - validatorsExitBusOracle = _assertNonZero(_config.validatorsExitBusOracle); - withdrawalQueue = _assertNonZero(_config.withdrawalQueue); - withdrawalVault = _assertNonZero(_config.withdrawalVault); - oracleDaemonConfig = _assertNonZero(_config.oracleDaemonConfig); - } - - function coreComponents() external view returns (address, address, address, address, address, address) { - return (elRewardsVault, oracleReportSanityChecker, stakingRouter, treasury, withdrawalQueue, withdrawalVault); - } - - function oracleReportComponentsForLido() - external - view - returns (address, address, address, address, address, address, address) - { - return ( - accountingOracle, - elRewardsVault, - oracleReportSanityChecker, - burner, - withdrawalQueue, - withdrawalVault, - postTokenRebaseReceiver - ); - } - - function _assertNonZero(address _address) internal pure returns (address) { - if (_address == address(0)) revert ZeroAddress(); - return _address; - } - - function mock___updatePostTokenRebaseReceiver(address newAddress) external { - postTokenRebaseReceiver = newAddress; - } - - function mock___updateAccountingOracle(address newAddress) external { - accountingOracle = newAddress; - } -} diff --git a/test/0.4.24/contracts/Lido__HarnessForFinalizeUpgradeV2.sol b/test/0.4.24/contracts/Lido__HarnessForFinalizeUpgradeV2.sol new file mode 100644 index 000000000..e928f1374 --- /dev/null +++ b/test/0.4.24/contracts/Lido__HarnessForFinalizeUpgradeV2.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.4.24; + +import {Lido} from "contracts/0.4.24/Lido.sol"; + +contract Lido__HarnessForFinalizeUpgradeV2 is Lido { + function harness__initialize(uint256 _initialVersion) external payable { + assert(address(this).balance != 0); + _bootstrapInitialHolder(); + _setContractVersion(_initialVersion); + initialized(); + } + + function harness__mintSharesWithoutChecks(address account, uint256 amount) external returns (uint256) { + return super._mintShares(account, amount); + } + + function harness__burnInitialHoldersShares() external returns (uint256) { + return super._burnShares(INITIAL_TOKEN_HOLDER, _sharesOf(INITIAL_TOKEN_HOLDER)); + } +} diff --git a/test/0.4.24/contracts/Lido__MockForFinalizeUpgradeV2.sol b/test/0.4.24/contracts/Lido__MockForFinalizeUpgradeV2.sol deleted file mode 100644 index 38503cbd4..000000000 --- a/test/0.4.24/contracts/Lido__MockForFinalizeUpgradeV2.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// for testing purposes only -pragma solidity 0.4.24; - -import {Lido} from "contracts/0.4.24/Lido.sol"; - -contract Lido__MockForFinalizeUpgradeV2 is Lido { - function mock__initialize(uint256 _initialVersion) external payable { - assert(address(this).balance != 0); - _bootstrapInitialHolder(); - _setContractVersion(_initialVersion); - initialized(); - } - - function mock__mintSharesWithoutChecks(address account, uint256 amount) external returns (uint256) { - return super._mintShares(account, amount); - } - - function mock__burnInitialHoldersShares() external returns (uint256) { - return super._burnShares(INITIAL_TOKEN_HOLDER, _sharesOf(INITIAL_TOKEN_HOLDER)); - } -} diff --git a/test/0.4.24/contracts/NodeOperatorsRegistry__Harness.sol b/test/0.4.24/contracts/NodeOperatorsRegistry__Harness.sol index 1f2931dd4..5ffd4a8ca 100644 --- a/test/0.4.24/contracts/NodeOperatorsRegistry__Harness.sol +++ b/test/0.4.24/contracts/NodeOperatorsRegistry__Harness.sol @@ -1,164 +1,175 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; import {NodeOperatorsRegistry} from "contracts/0.4.24/nos/NodeOperatorsRegistry.sol"; import {Packed64x4} from "contracts/0.4.24/lib/Packed64x4.sol"; contract NodeOperatorsRegistry__Harness is NodeOperatorsRegistry { - bytes public obtainedPublicKeys; - bytes public obtainedSignatures; - - function harness__initialize(uint256 _initialVersion) external { - _setContractVersion(_initialVersion); - initialized(); - } - - function harness__setDepositedSigningKeysCount(uint256 _nodeOperatorId, uint256 _depositedSigningKeysCount) public { - _onlyExistedNodeOperator(_nodeOperatorId); - // NodeOperator storage nodeOperator = _nodeOperators[_nodeOperatorId]; - Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); - uint256 depositedSigningKeysCountBefore = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); - if (_depositedSigningKeysCount == depositedSigningKeysCountBefore) { - return; + bytes public obtainedPublicKeys; + bytes public obtainedSignatures; + + function harness__initialize(uint256 _initialVersion) external { + _setContractVersion(_initialVersion); + initialized(); + } + + function harness__setDepositedSigningKeysCount(uint256 _nodeOperatorId, uint256 _depositedSigningKeysCount) public { + _onlyExistedNodeOperator(_nodeOperatorId); + // NodeOperator storage nodeOperator = _nodeOperators[_nodeOperatorId]; + Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); + uint256 depositedSigningKeysCountBefore = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + if (_depositedSigningKeysCount == depositedSigningKeysCountBefore) { + return; + } + + require( + _depositedSigningKeysCount <= signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET), + "DEPOSITED_SIGNING_KEYS_COUNT_TOO_HIGH" + ); + require( + _depositedSigningKeysCount >= signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET), + "DEPOSITED_SIGNING_KEYS_COUNT_TOO_LOW" + ); + + signingKeysStats.set(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET, uint64(_depositedSigningKeysCount)); + _saveOperatorSigningKeysStats(_nodeOperatorId, signingKeysStats); + + emit DepositedSigningKeysCountChanged(_nodeOperatorId, _depositedSigningKeysCount); + _increaseValidatorsKeysNonce(); + } + + function harness__addNodeOperator( + string _name, + address _rewardAddress, + uint64 totalSigningKeysCount, + uint64 vettedSigningKeysCount, + uint64 depositedSigningKeysCount, + uint64 exitedSigningKeysCount + ) external returns (uint256 id) { + id = getNodeOperatorsCount(); + + TOTAL_OPERATORS_COUNT_POSITION.setStorageUint256(id + 1); + + NodeOperator storage operator = _nodeOperators[id]; + + uint256 activeOperatorsCount = getActiveNodeOperatorsCount(); + ACTIVE_OPERATORS_COUNT_POSITION.setStorageUint256(activeOperatorsCount + 1); + + operator.active = true; + operator.name = _name; + operator.rewardAddress = _rewardAddress; + + Packed64x4.Packed memory signingKeysStats; + signingKeysStats.set(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET, depositedSigningKeysCount); + signingKeysStats.set(TOTAL_VETTED_KEYS_COUNT_OFFSET, vettedSigningKeysCount); + signingKeysStats.set(TOTAL_EXITED_KEYS_COUNT_OFFSET, exitedSigningKeysCount); + signingKeysStats.set(TOTAL_KEYS_COUNT_OFFSET, totalSigningKeysCount); + + operator.signingKeysStats = signingKeysStats; + + Packed64x4.Packed memory operatorTargetStats; + operatorTargetStats.set(MAX_VALIDATORS_COUNT_OFFSET, vettedSigningKeysCount); + operator.targetValidatorsStats = operatorTargetStats; + + emit NodeOperatorAdded(id, _name, _rewardAddress, 0); + + Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); + summarySigningKeysStats.add(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET, vettedSigningKeysCount); + summarySigningKeysStats.add(SUMMARY_EXITED_KEYS_COUNT_OFFSET, exitedSigningKeysCount); + summarySigningKeysStats.add(SUMMARY_TOTAL_KEYS_COUNT_OFFSET, totalSigningKeysCount); + summarySigningKeysStats.add(SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET, depositedSigningKeysCount); + _saveSummarySigningKeysStats(summarySigningKeysStats); + } + + function harness__setNodeOperatorLimits( + uint256 _nodeOperatorId, + uint64 stuckValidatorsCount, + uint64 refundedValidatorsCount, + uint64 stuckPenaltyEndAt + ) external { + Packed64x4.Packed memory stuckPenaltyStats = _nodeOperators[_nodeOperatorId].stuckPenaltyStats; + stuckPenaltyStats.set(STUCK_VALIDATORS_COUNT_OFFSET, stuckValidatorsCount); + stuckPenaltyStats.set(REFUNDED_VALIDATORS_COUNT_OFFSET, refundedValidatorsCount); + stuckPenaltyStats.set(STUCK_PENALTY_END_TIMESTAMP_OFFSET, stuckPenaltyEndAt); + _nodeOperators[_nodeOperatorId].stuckPenaltyStats = stuckPenaltyStats; + _updateSummaryMaxValidatorsCount(_nodeOperatorId); + } + + function harness__obtainDepositData( + uint256 _keysToAllocate + ) external returns (uint256 loadedValidatorsKeysCount, bytes memory publicKeys, bytes memory signatures) { + (publicKeys, signatures) = this.obtainDepositData(_keysToAllocate, new bytes(0)); + + obtainedPublicKeys = publicKeys; + obtainedSignatures = signatures; + + emit ValidatorsKeysLoaded(publicKeys, signatures); + } + + function harness__loadAllocatedSigningKeys( + uint256 _keysCountToLoad, + uint256[] _nodeOperatorIds, + uint256[] _activeKeyCountsAfterAllocation + ) external returns (bytes memory pubkeys, bytes memory signatures) { + (pubkeys, signatures) = _loadAllocatedSigningKeys( + _keysCountToLoad, + _nodeOperatorIds, + _activeKeyCountsAfterAllocation + ); + + obtainedPublicKeys = pubkeys; + obtainedSignatures = signatures; + + emit ValidatorsKeysLoaded(pubkeys, signatures); + } + + function harness__getSigningKeysAllocationData( + uint256 _keysCount + ) + external + view + returns ( + uint256 allocatedKeysCount, + uint256[] memory nodeOperatorIds, + uint256[] memory activeKeyCountsAfterAllocation + ) + { + return _getSigningKeysAllocationData(_keysCount); } - require( - _depositedSigningKeysCount <= signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET), - "DEPOSITED_SIGNING_KEYS_COUNT_TOO_HIGH" - ); - require( - _depositedSigningKeysCount >= signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET), - "DEPOSITED_SIGNING_KEYS_COUNT_TOO_LOW" - ); - - signingKeysStats.set(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET, uint64(_depositedSigningKeysCount)); - _saveOperatorSigningKeysStats(_nodeOperatorId, signingKeysStats); - - emit DepositedSigningKeysCountChanged(_nodeOperatorId, _depositedSigningKeysCount); - _increaseValidatorsKeysNonce(); - } - - function harness__addNodeOperator( - string _name, - address _rewardAddress, - uint64 totalSigningKeysCount, - uint64 vettedSigningKeysCount, - uint64 depositedSigningKeysCount, - uint64 exitedSigningKeysCount - ) external returns (uint256 id) { - id = getNodeOperatorsCount(); - - TOTAL_OPERATORS_COUNT_POSITION.setStorageUint256(id + 1); - - NodeOperator storage operator = _nodeOperators[id]; - - uint256 activeOperatorsCount = getActiveNodeOperatorsCount(); - ACTIVE_OPERATORS_COUNT_POSITION.setStorageUint256(activeOperatorsCount + 1); - - operator.active = true; - operator.name = _name; - operator.rewardAddress = _rewardAddress; - - Packed64x4.Packed memory signingKeysStats; - signingKeysStats.set(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET, depositedSigningKeysCount); - signingKeysStats.set(TOTAL_VETTED_KEYS_COUNT_OFFSET, vettedSigningKeysCount); - signingKeysStats.set(TOTAL_EXITED_KEYS_COUNT_OFFSET, exitedSigningKeysCount); - signingKeysStats.set(TOTAL_KEYS_COUNT_OFFSET, totalSigningKeysCount); - - operator.signingKeysStats = signingKeysStats; - - Packed64x4.Packed memory operatorTargetStats; - operatorTargetStats.set(MAX_VALIDATORS_COUNT_OFFSET, vettedSigningKeysCount); - operator.targetValidatorsStats = operatorTargetStats; - - emit NodeOperatorAdded(id, _name, _rewardAddress, 0); - - Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); - summarySigningKeysStats.add(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET, vettedSigningKeysCount); - summarySigningKeysStats.add(SUMMARY_EXITED_KEYS_COUNT_OFFSET, exitedSigningKeysCount); - summarySigningKeysStats.add(SUMMARY_TOTAL_KEYS_COUNT_OFFSET, totalSigningKeysCount); - summarySigningKeysStats.add(SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET, depositedSigningKeysCount); - _saveSummarySigningKeysStats(summarySigningKeysStats); - } - - function harness__setNodeOperatorLimits( - uint256 _nodeOperatorId, - uint64 stuckValidatorsCount, - uint64 refundedValidatorsCount, - uint64 stuckPenaltyEndAt - ) external { - Packed64x4.Packed memory stuckPenaltyStats = _nodeOperators[_nodeOperatorId].stuckPenaltyStats; - stuckPenaltyStats.set(STUCK_VALIDATORS_COUNT_OFFSET, stuckValidatorsCount); - stuckPenaltyStats.set(REFUNDED_VALIDATORS_COUNT_OFFSET, refundedValidatorsCount); - stuckPenaltyStats.set(STUCK_PENALTY_END_TIMESTAMP_OFFSET, stuckPenaltyEndAt); - _nodeOperators[_nodeOperatorId].stuckPenaltyStats = stuckPenaltyStats; - _updateSummaryMaxValidatorsCount(_nodeOperatorId); - } - - function harness__obtainDepositData( - uint256 _keysToAllocate - ) external returns (uint256 loadedValidatorsKeysCount, bytes memory publicKeys, bytes memory signatures) { - (publicKeys, signatures) = this.obtainDepositData(_keysToAllocate, new bytes(0)); - - obtainedPublicKeys = publicKeys; - obtainedSignatures = signatures; - - emit ValidatorsKeysLoaded(publicKeys, signatures); - } - - function harness__loadAllocatedSigningKeys( - uint256 _keysCountToLoad, - uint256[] _nodeOperatorIds, - uint256[] _activeKeyCountsAfterAllocation - ) external returns (bytes memory pubkeys, bytes memory signatures) { - (pubkeys, signatures) = _loadAllocatedSigningKeys(_keysCountToLoad, _nodeOperatorIds, _activeKeyCountsAfterAllocation); - - obtainedPublicKeys = pubkeys; - obtainedSignatures = signatures; - - emit ValidatorsKeysLoaded(pubkeys, signatures); - } - - function harness__getSigningKeysAllocationData(uint256 _keysCount) external view returns ( - uint256 allocatedKeysCount, - uint256[] memory nodeOperatorIds, - uint256[] memory activeKeyCountsAfterAllocation - ) { - return _getSigningKeysAllocationData(_keysCount); - } - - event ValidatorsKeysLoaded(bytes publicKeys, bytes signatures); - - function harness__setLocator(address _mockedLocator) external { - LIDO_LOCATOR_POSITION.setStorageAddress(_mockedLocator); - } - - function harness__setStuckPenaltyDelay(uint256 _stuckPenaltyDelay) external { - STUCK_PENALTY_DELAY_POSITION.setStorageUint256(_stuckPenaltyDelay); - } - - function harness__setNonce(uint256 _nonce) external { - KEYS_OP_INDEX_POSITION.setStorageUint256(_nonce); - } - - /** - * @dev Extra care is needed. - * Doesn't update the active node operators counter and node operator's summary - */ - function harness__unsafeSetNodeOperatorIsActive(uint256 _nodeOperatorId, bool _isActive) external { - _nodeOperators[_nodeOperatorId].active = _isActive; - } - - function harness__unsafeResetModuleSummary() external { - Packed64x4.Packed memory summarySigningKeysStats = Packed64x4.Packed(0); - _saveSummarySigningKeysStats(summarySigningKeysStats); - } - - function harness__unsafeSetVettedKeys(uint256 _nodeOperatorId, uint256 _newVettedKeys) external { - Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); - - signingKeysStats.set(TOTAL_VETTED_KEYS_COUNT_OFFSET, _newVettedKeys); - _saveOperatorSigningKeysStats(_nodeOperatorId, signingKeysStats); - } + event ValidatorsKeysLoaded(bytes publicKeys, bytes signatures); + + function harness__setLocator(address _mockedLocator) external { + LIDO_LOCATOR_POSITION.setStorageAddress(_mockedLocator); + } + + function harness__setStuckPenaltyDelay(uint256 _stuckPenaltyDelay) external { + STUCK_PENALTY_DELAY_POSITION.setStorageUint256(_stuckPenaltyDelay); + } + + function harness__setNonce(uint256 _nonce) external { + KEYS_OP_INDEX_POSITION.setStorageUint256(_nonce); + } + + /** + * @dev Extra care is needed. + * Doesn't update the active node operators counter and node operator's summary + */ + function harness__unsafeSetNodeOperatorIsActive(uint256 _nodeOperatorId, bool _isActive) external { + _nodeOperators[_nodeOperatorId].active = _isActive; + } + + function harness__unsafeResetModuleSummary() external { + Packed64x4.Packed memory summarySigningKeysStats = Packed64x4.Packed(0); + _saveSummarySigningKeysStats(summarySigningKeysStats); + } + + function harness__unsafeSetVettedKeys(uint256 _nodeOperatorId, uint256 _newVettedKeys) external { + Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); + + signingKeysStats.set(TOTAL_VETTED_KEYS_COUNT_OFFSET, _newVettedKeys); + _saveOperatorSigningKeysStats(_nodeOperatorId, signingKeysStats); + } } diff --git a/test/0.4.24/contracts/OracleReportSanityChecker__MockForLidoHandleOracleReport.sol b/test/0.4.24/contracts/OracleReportSanityChecker__MockForLidoHandleOracleReport.sol index e6df15ce2..86425c627 100644 --- a/test/0.4.24/contracts/OracleReportSanityChecker__MockForLidoHandleOracleReport.sol +++ b/test/0.4.24/contracts/OracleReportSanityChecker__MockForLidoHandleOracleReport.sol @@ -1,88 +1,92 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; contract OracleReportSanityChecker__MockForLidoHandleOracleReport { - bool private checkAccountingOracleReportReverts; - bool private checkWithdrawalQueueOracleReportReverts; - bool private checkSimulatedShareRateReverts; + bool private checkAccountingOracleReportReverts; + bool private checkWithdrawalQueueOracleReportReverts; + bool private checkSimulatedShareRateReverts; - uint256 private _withdrawals; - uint256 private _elRewards; - uint256 private _simulatedSharesToBurn; - uint256 private _sharesToBurn; + uint256 private _withdrawals; + uint256 private _elRewards; + uint256 private _simulatedSharesToBurn; + uint256 private _sharesToBurn; - function checkAccountingOracleReport( - uint256 _timeElapsed, - uint256 _preCLBalance, - uint256 _postCLBalance, - uint256 _withdrawalVaultBalance, - uint256 _elRewardsVaultBalance, - uint256 _sharesRequestedToBurn, - uint256 _preCLValidators, - uint256 _postCLValidators - ) external view { - if (checkAccountingOracleReportReverts) revert(); - } + function checkAccountingOracleReport( + uint256 _timeElapsed, + uint256 _preCLBalance, + uint256 _postCLBalance, + uint256 _withdrawalVaultBalance, + uint256 _elRewardsVaultBalance, + uint256 _sharesRequestedToBurn, + uint256 _preCLValidators, + uint256 _postCLValidators + ) external view { + if (checkAccountingOracleReportReverts) revert(); + } - function checkWithdrawalQueueOracleReport(uint256 _lastFinalizableRequestId, uint256 _reportTimestamp) external view { - if (checkWithdrawalQueueOracleReportReverts) revert(); - } + function checkWithdrawalQueueOracleReport( + uint256 _lastFinalizableRequestId, + uint256 _reportTimestamp + ) external view { + if (checkWithdrawalQueueOracleReportReverts) revert(); + } - function smoothenTokenRebase( - uint256 _preTotalPooledEther, - uint256 _preTotalShares, - uint256 _preCLBalance, - uint256 _postCLBalance, - uint256 _withdrawalVaultBalance, - uint256 _elRewardsVaultBalance, - uint256 _sharesRequestedToBurn, - uint256 _etherToLockForWithdrawals, - uint256 _newSharesToBurnForWithdrawals - ) - external - view - returns (uint256 withdrawals, uint256 elRewards, uint256 simulatedSharesToBurn, uint256 sharesToBurn) - { - withdrawals = _withdrawals; - elRewards = _elRewards; - simulatedSharesToBurn = _simulatedSharesToBurn; - sharesToBurn = _sharesToBurn; - } + function smoothenTokenRebase( + uint256 _preTotalPooledEther, + uint256 _preTotalShares, + uint256 _preCLBalance, + uint256 _postCLBalance, + uint256 _withdrawalVaultBalance, + uint256 _elRewardsVaultBalance, + uint256 _sharesRequestedToBurn, + uint256 _etherToLockForWithdrawals, + uint256 _newSharesToBurnForWithdrawals + ) + external + view + returns (uint256 withdrawals, uint256 elRewards, uint256 simulatedSharesToBurn, uint256 sharesToBurn) + { + withdrawals = _withdrawals; + elRewards = _elRewards; + simulatedSharesToBurn = _simulatedSharesToBurn; + sharesToBurn = _sharesToBurn; + } - function checkSimulatedShareRate( - uint256 _postTotalPooledEther, - uint256 _postTotalShares, - uint256 _etherLockedOnWithdrawalQueue, - uint256 _sharesBurntDueToWithdrawals, - uint256 _simulatedShareRate - ) external view { - if (checkSimulatedShareRateReverts) revert(); - } + function checkSimulatedShareRate( + uint256 _postTotalPooledEther, + uint256 _postTotalShares, + uint256 _etherLockedOnWithdrawalQueue, + uint256 _sharesBurntDueToWithdrawals, + uint256 _simulatedShareRate + ) external view { + if (checkSimulatedShareRateReverts) revert(); + } - // mocking + // mocking - function mock__checkAccountingOracleReportReverts(bool reverts) external { - checkAccountingOracleReportReverts = reverts; - } + function mock__checkAccountingOracleReportReverts(bool reverts) external { + checkAccountingOracleReportReverts = reverts; + } - function mock__checkWithdrawalQueueOracleReportReverts(bool reverts) external { - checkWithdrawalQueueOracleReportReverts = reverts; - } + function mock__checkWithdrawalQueueOracleReportReverts(bool reverts) external { + checkWithdrawalQueueOracleReportReverts = reverts; + } - function mock__checkSimulatedShareRateReverts(bool reverts) external { - checkSimulatedShareRateReverts = reverts; - } + function mock__checkSimulatedShareRateReverts(bool reverts) external { + checkSimulatedShareRateReverts = reverts; + } - function mock__smoothenTokenRebaseReturn( - uint256 withdrawals, - uint256 elRewards, - uint256 simulatedSharesToBurn, - uint256 sharesToBurn - ) external { - _withdrawals = withdrawals; - _elRewards = elRewards; - _simulatedSharesToBurn = simulatedSharesToBurn; - _sharesToBurn = sharesToBurn; - } + function mock__smoothenTokenRebaseReturn( + uint256 withdrawals, + uint256 elRewards, + uint256 simulatedSharesToBurn, + uint256 sharesToBurn + ) external { + _withdrawals = withdrawals; + _elRewards = elRewards; + _simulatedSharesToBurn = simulatedSharesToBurn; + _sharesToBurn = sharesToBurn; + } } diff --git a/test/0.4.24/contracts/Packed64x4__Harness.sol b/test/0.4.24/contracts/Packed64x4__Harness.sol index 1f3f09379..d7c16fffa 100644 --- a/test/0.4.24/contracts/Packed64x4__Harness.sol +++ b/test/0.4.24/contracts/Packed64x4__Harness.sol @@ -1,6 +1,5 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for test purposes only +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity ^0.4.24; diff --git a/test/0.4.24/contracts/PausableMockWithExposedApi.sol b/test/0.4.24/contracts/Pausable__Harness.sol similarity index 83% rename from test/0.4.24/contracts/PausableMockWithExposedApi.sol rename to test/0.4.24/contracts/Pausable__Harness.sol index da6f8ccb0..aeae6ddb5 100644 --- a/test/0.4.24/contracts/PausableMockWithExposedApi.sol +++ b/test/0.4.24/contracts/Pausable__Harness.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; import {Pausable} from "contracts/0.4.24/utils/Pausable.sol"; -contract PausableMockWithExposedApi is Pausable { +contract Pausable__Harness is Pausable { function stop() external { _stop(); } @@ -12,4 +13,4 @@ contract PausableMockWithExposedApi is Pausable { function resume() external { _resume(); } -} \ No newline at end of file +} diff --git a/test/0.4.24/contracts/PostTokenRebaseReceiver__MockForLidoHandleOracleReport.sol b/test/0.4.24/contracts/PostTokenRebaseReceiver__MockForLidoHandleOracleReport.sol index ee425bdb5..2d8098900 100644 --- a/test/0.4.24/contracts/PostTokenRebaseReceiver__MockForLidoHandleOracleReport.sol +++ b/test/0.4.24/contracts/PostTokenRebaseReceiver__MockForLidoHandleOracleReport.sol @@ -1,18 +1,20 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; contract PostTokenRebaseReceiver__MockForLidoHandleOracleReport { - event Mock__PostTokenRebaseHandled(); - function handlePostTokenRebase( - uint256 _reportTimestamp, - uint256 _timeElapsed, - uint256 _preTotalShares, - uint256 _preTotalEther, - uint256 _postTotalShares, - uint256 _postTotalEther, - uint256 _sharesMintedAsFees - ) external { - emit Mock__PostTokenRebaseHandled(); - } + event Mock__PostTokenRebaseHandled(); + + function handlePostTokenRebase( + uint256 _reportTimestamp, + uint256 _timeElapsed, + uint256 _preTotalShares, + uint256 _preTotalEther, + uint256 _postTotalShares, + uint256 _postTotalEther, + uint256 _sharesMintedAsFees + ) external { + emit Mock__PostTokenRebaseHandled(); + } } diff --git a/test/0.4.24/contracts/SigningKeys__Harness.sol b/test/0.4.24/contracts/SigningKeys__Harness.sol index ee23b676a..e7c164171 100644 --- a/test/0.4.24/contracts/SigningKeys__Harness.sol +++ b/test/0.4.24/contracts/SigningKeys__Harness.sol @@ -1,6 +1,5 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for test purposes only +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity 0.4.24; @@ -34,18 +33,20 @@ contract SigningKeys__Harness { return KEYSSIGS_POSITION.saveKeysSigs(_nodeOperatorId, _startIndex, _keysCount, _publicKeys, _signatures); } - function removeKeysSigs(uint256 _nodeOperatorId, uint256 _startIndex, uint256 _keysCount, uint256 _lastIndex) - external - returns (uint256) - { + function removeKeysSigs( + uint256 _nodeOperatorId, + uint256 _startIndex, + uint256 _keysCount, + uint256 _lastIndex + ) external returns (uint256) { return KEYSSIGS_POSITION.removeKeysSigs(_nodeOperatorId, _startIndex, _keysCount, _lastIndex); } - function loadKeysSigs(uint256 _nodeOperatorId, uint256 _startIndex, uint256 _keysCount) - external - view - returns (bytes memory pubkeys, bytes memory signatures) - { + function loadKeysSigs( + uint256 _nodeOperatorId, + uint256 _startIndex, + uint256 _keysCount + ) external view returns (bytes memory pubkeys, bytes memory signatures) { (pubkeys, signatures) = SigningKeys.initKeysSigsBuf(_keysCount); KEYSSIGS_POSITION.loadKeysSigs( diff --git a/test/0.4.24/contracts/StETHPermit__HarnessForWithdrawalQueueDeploy.sol b/test/0.4.24/contracts/StETHPermit__HarnessForWithdrawalQueueDeploy.sol new file mode 100644 index 000000000..439c1e51b --- /dev/null +++ b/test/0.4.24/contracts/StETHPermit__HarnessForWithdrawalQueueDeploy.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.4.24; + +import {StETHPermit} from "contracts/0.4.24/StETHPermit.sol"; +import {StETH__HarnessForWithdrawalQueueDeploy} from "./StETH__HarnessForWithdrawalQueueDeploy.sol"; + +contract StETHPermit__HarnessForWithdrawalQueueDeploy is StETHPermit, StETH__HarnessForWithdrawalQueueDeploy { + function initializeEIP712StETH(address _eip712StETH) external { + _initializeEIP712StETH(_eip712StETH); + } + + function getBlockTime() external view returns (uint256) { + return block.timestamp; + } +} diff --git a/test/0.4.24/contracts/StETHPermit__HarnessWithEip712Initialization.sol b/test/0.4.24/contracts/StETHPermit__HarnessWithEip712Initialization.sol new file mode 100644 index 000000000..0de25a8d4 --- /dev/null +++ b/test/0.4.24/contracts/StETHPermit__HarnessWithEip712Initialization.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.4.24; + +import {StETHPermit} from "contracts/0.4.24/StETHPermit.sol"; +import {StETH__Harness} from "test/0.4.24/contracts/StETH__Harness.sol"; + +contract StETHPermit__HarnessWithEip712Initialization is StETHPermit, StETH__Harness { + constructor(address _holder) payable StETH__Harness(_holder) {} + + function initializeEIP712StETH(address _eip712StETH) external { + _initializeEIP712StETH(_eip712StETH); + } +} diff --git a/test/0.4.24/contracts/StETHPermit__MockForWithdrawalQueueDeploy.sol b/test/0.4.24/contracts/StETHPermit__MockForWithdrawalQueueDeploy.sol deleted file mode 100644 index 0aee5345d..000000000 --- a/test/0.4.24/contracts/StETHPermit__MockForWithdrawalQueueDeploy.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.4.24; - -import "contracts/0.4.24/StETHPermit.sol"; -import "./StETH__MockForWithdrawalQueueDeploy.sol"; - -/** - * @dev Only for testing purposes! - * StETHPermit mock version of mintable/burnable/stoppable token. - */ -contract StETHPermit__MockForWithdrawalQueueDeploy is StETHPermit, StETH__MockForWithdrawalQueueDeploy { - function initializeEIP712StETH(address _eip712StETH) external { - _initializeEIP712StETH(_eip712StETH); - } - - function getBlockTime() external view returns (uint256) { - return block.timestamp; - } -} diff --git a/test/0.4.24/contracts/StETH__Harness.sol b/test/0.4.24/contracts/StETH__Harness.sol new file mode 100644 index 000000000..26b21e9f1 --- /dev/null +++ b/test/0.4.24/contracts/StETH__Harness.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.4.24; + +import {StETH} from "contracts/0.4.24/StETH.sol"; + +contract StETH__Harness is StETH { + uint256 private totalPooledEther; + + constructor(address _holder) public payable { + _resume(); + uint256 balance = address(this).balance; + assert(balance != 0); + + setTotalPooledEther(balance); + _mintShares(_holder, balance); + } + + function _getTotalPooledEther() internal view returns (uint256) { + return totalPooledEther; + } + + function setTotalPooledEther(uint256 _totalPooledEther) public { + totalPooledEther = _totalPooledEther; + } + + function mintShares(address _recipient, uint256 _sharesAmount) external returns (uint256) { + return super._mintShares(_recipient, _sharesAmount); + } + + function burnShares(address _account, uint256 _sharesAmount) external returns (uint256) { + return super._burnShares(_account, _sharesAmount); + } +} diff --git a/test/0.4.24/contracts/StETH__MockForWithdrawalQueueDeploy.sol b/test/0.4.24/contracts/StETH__HarnessForWithdrawalQueueDeploy.sol similarity index 82% rename from test/0.4.24/contracts/StETH__MockForWithdrawalQueueDeploy.sol rename to test/0.4.24/contracts/StETH__HarnessForWithdrawalQueueDeploy.sol index b1947e144..87d92af09 100644 --- a/test/0.4.24/contracts/StETH__MockForWithdrawalQueueDeploy.sol +++ b/test/0.4.24/contracts/StETH__HarnessForWithdrawalQueueDeploy.sol @@ -1,16 +1,11 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.4.24; -import "contracts/0.4.24/StETH.sol"; +import {StETH} from "contracts/0.4.24/StETH.sol"; -/** - * @dev Only for testing purposes! - * StETH mock version of mintable/burnable/stoppable token. - */ -contract StETH__MockForWithdrawalQueueDeploy is StETH { +contract StETH__HarnessForWithdrawalQueueDeploy is StETH { uint256 private totalPooledEther; constructor() public payable { diff --git a/test/0.4.24/contracts/StakeLimitUtils__Harness.sol b/test/0.4.24/contracts/StakeLimitUtils__Harness.sol index 260413a59..3b690d507 100644 --- a/test/0.4.24/contracts/StakeLimitUtils__Harness.sol +++ b/test/0.4.24/contracts/StakeLimitUtils__Harness.sol @@ -1,172 +1,186 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for test purposes only +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity 0.4.24; import {StakeLimitUtils, StakeLimitUnstructuredStorage, StakeLimitState} from "contracts/0.4.24/lib/StakeLimitUtils.sol"; contract StakeLimitUnstructuredStorage__Harness { - using StakeLimitUnstructuredStorage for bytes32; - - bytes32 public constant position = keccak256("test.test.test"); - - event DataSet( - uint32 prevStakeBlockNumber, - uint96 prevStakeLimit, - uint32 maxStakeLimitGrowthBlocks, - uint96 maxStakeLimit - ); - - function getStorageStakeLimit() - external - view - returns (uint32 prevStakeBlockNumber, uint96 prevStakeLimit, uint32 maxStakeLimitGrowthBlocks, uint96 maxStakeLimit) - { - StakeLimitState.Data memory stakeLimit = position.getStorageStakeLimitStruct(); - - prevStakeBlockNumber = stakeLimit.prevStakeBlockNumber; - prevStakeLimit = stakeLimit.prevStakeLimit; - maxStakeLimitGrowthBlocks = stakeLimit.maxStakeLimitGrowthBlocks; - maxStakeLimit = stakeLimit.maxStakeLimit; - } - - function setStorageStakeLimit( - uint32 _prevStakeBlockNumber, - uint96 _prevStakeLimit, - uint32 _maxStakeLimitGrowthBlocks, - uint96 _maxStakeLimit - ) external { - StakeLimitState.Data memory stakeLimit = StakeLimitState.Data( - _prevStakeBlockNumber, - _prevStakeLimit, - _maxStakeLimitGrowthBlocks, - _maxStakeLimit - ); - - position.setStorageStakeLimitStruct(stakeLimit); + using StakeLimitUnstructuredStorage for bytes32; - emit DataSet(_prevStakeBlockNumber, _prevStakeLimit, _maxStakeLimitGrowthBlocks, _maxStakeLimit); - } + bytes32 public constant position = keccak256("test.test.test"); - function harness__getStorageStakeLimit() - external - view - returns (uint32 prevStakeBlockNumber, uint96 prevStakeLimit, uint32 maxStakeLimitGrowthBlocks, uint96 maxStakeLimit) - { - // the other way around for the tests purposes - // could have done with calldata slices with a newer solidity versions + event DataSet( + uint32 prevStakeBlockNumber, + uint96 prevStakeLimit, + uint32 maxStakeLimitGrowthBlocks, + uint96 maxStakeLimit + ); - bytes32 _position = position; - assembly { - let slot_val := sload(_position) // load whole slot data from storage to memory + function getStorageStakeLimit() + external + view + returns ( + uint32 prevStakeBlockNumber, + uint96 prevStakeLimit, + uint32 maxStakeLimitGrowthBlocks, + uint96 maxStakeLimit + ) + { + StakeLimitState.Data memory stakeLimit = position.getStorageStakeLimitStruct(); + + prevStakeBlockNumber = stakeLimit.prevStakeBlockNumber; + prevStakeLimit = stakeLimit.prevStakeLimit; + maxStakeLimitGrowthBlocks = stakeLimit.maxStakeLimitGrowthBlocks; + maxStakeLimit = stakeLimit.maxStakeLimit; + } - prevStakeBlockNumber := shr(mul(0x00, 8), slot_val) - prevStakeLimit := shr(mul(0x04, 8), slot_val) - maxStakeLimitGrowthBlocks := shr(mul(0x10, 8), slot_val) - maxStakeLimit := shr(mul(0x14, 8), slot_val) + function setStorageStakeLimit( + uint32 _prevStakeBlockNumber, + uint96 _prevStakeLimit, + uint32 _maxStakeLimitGrowthBlocks, + uint96 _maxStakeLimit + ) external { + StakeLimitState.Data memory stakeLimit = StakeLimitState.Data( + _prevStakeBlockNumber, + _prevStakeLimit, + _maxStakeLimitGrowthBlocks, + _maxStakeLimit + ); + + position.setStorageStakeLimitStruct(stakeLimit); + + emit DataSet(_prevStakeBlockNumber, _prevStakeLimit, _maxStakeLimitGrowthBlocks, _maxStakeLimit); } - } - - function harness__setStorageStakeLimit( - uint32 _prevStakeBlockNumber, - uint96 _prevStakeLimit, - uint32 _maxStakeLimitGrowthBlocks, - uint96 _maxStakeLimit - ) external { - bytes memory encoded = abi.encodePacked( - _maxStakeLimit, - _maxStakeLimitGrowthBlocks, - _prevStakeLimit, - _prevStakeBlockNumber - ); - // should be a single storage slot length exactly - assert(encoded.length == 32); - bytes32 _position = position; - assembly { - sstore(_position, mload(add(encoded, 0x20))) // store the value from memory to storage + function harness__getStorageStakeLimit() + external + view + returns ( + uint32 prevStakeBlockNumber, + uint96 prevStakeLimit, + uint32 maxStakeLimitGrowthBlocks, + uint96 maxStakeLimit + ) + { + // the other way around for the tests purposes + // could have done with calldata slices with a newer solidity versions + + bytes32 _position = position; + assembly { + let slot_val := sload(_position) // load whole slot data from storage to memory + + prevStakeBlockNumber := shr(mul(0x00, 8), slot_val) + prevStakeLimit := shr(mul(0x04, 8), slot_val) + maxStakeLimitGrowthBlocks := shr(mul(0x10, 8), slot_val) + maxStakeLimit := shr(mul(0x14, 8), slot_val) + } } - emit DataSet(_prevStakeBlockNumber, _prevStakeLimit, _maxStakeLimitGrowthBlocks, _maxStakeLimit); - } + function harness__setStorageStakeLimit( + uint32 _prevStakeBlockNumber, + uint96 _prevStakeLimit, + uint32 _maxStakeLimitGrowthBlocks, + uint96 _maxStakeLimit + ) external { + bytes memory encoded = abi.encodePacked( + _maxStakeLimit, + _maxStakeLimitGrowthBlocks, + _prevStakeLimit, + _prevStakeBlockNumber + ); + // should be a single storage slot length exactly + assert(encoded.length == 32); + + bytes32 _position = position; + assembly { + sstore(_position, mload(add(encoded, 0x20))) // store the value from memory to storage + } + + emit DataSet(_prevStakeBlockNumber, _prevStakeLimit, _maxStakeLimitGrowthBlocks, _maxStakeLimit); + } } contract StakeLimitUtils__Harness { - using StakeLimitUtils for StakeLimitState.Data; - - StakeLimitState.Data public state; - - event DataSet( - uint32 prevStakeBlockNumber, - uint96 prevStakeLimit, - uint32 maxStakeLimitGrowthBlocks, - uint96 maxStakeLimit - ); - - event StakingLimitSet(uint256 maxStakeLimit, uint256 stakeLimitIncreasePerBlock); - event StakingLimitRemoved(); - event PrevStakeLimitUpdated(uint256 newPrevStakeLimit); - event StakeLimitPauseStateSet(bool isPaused); - - function harness_setState( - uint32 _prevStakeBlockNumber, - uint96 _prevStakeLimit, - uint32 _maxStakeLimitGrowthBlocks, - uint96 _maxStakeLimit - ) external { - state.prevStakeBlockNumber = _prevStakeBlockNumber; - state.prevStakeLimit = _prevStakeLimit; - state.maxStakeLimitGrowthBlocks = _maxStakeLimitGrowthBlocks; - state.maxStakeLimit = _maxStakeLimit; - - emit DataSet(_prevStakeBlockNumber, _prevStakeLimit, _maxStakeLimitGrowthBlocks, _maxStakeLimit); - } - - function harness_getState() - external - view - returns (uint32 prevStakeBlockNumber, uint96 prevStakeLimit, uint32 maxStakeLimitGrowthBlocks, uint96 maxStakeLimit) - { - prevStakeBlockNumber = state.prevStakeBlockNumber; - prevStakeLimit = state.prevStakeLimit; - maxStakeLimitGrowthBlocks = state.maxStakeLimitGrowthBlocks; - maxStakeLimit = state.maxStakeLimit; - } - - function calculateCurrentStakeLimit() external view returns (uint256 limit) { - limit = state.calculateCurrentStakeLimit(); - } - - function isStakingPaused() external view returns (bool) { - return state.isStakingPaused(); - } - - function setStakingLimit(uint256 _maxStakeLimit, uint256 _stakeLimitIncreasePerBlock) external { - state = state.setStakingLimit(_maxStakeLimit, _stakeLimitIncreasePerBlock); - - emit StakingLimitSet(_maxStakeLimit, _stakeLimitIncreasePerBlock); - } - - function removeStakingLimit() external { - state = state.removeStakingLimit(); - - emit StakingLimitRemoved(); - } - - function updatePrevStakeLimit(uint256 _newPrevStakeLimit) external { - state = state.updatePrevStakeLimit(_newPrevStakeLimit); - - emit PrevStakeLimitUpdated(_newPrevStakeLimit); - } - - function setStakeLimitPauseState(bool _isPaused) external { - state = state.setStakeLimitPauseState(_isPaused); - - emit StakeLimitPauseStateSet(_isPaused); - } - - function constGasMin(uint256 _lhs, uint256 _rhs) external pure returns (uint256 min) { - min = StakeLimitUtils._constGasMin(_lhs, _rhs); - } + using StakeLimitUtils for StakeLimitState.Data; + + StakeLimitState.Data public state; + + event DataSet( + uint32 prevStakeBlockNumber, + uint96 prevStakeLimit, + uint32 maxStakeLimitGrowthBlocks, + uint96 maxStakeLimit + ); + + event StakingLimitSet(uint256 maxStakeLimit, uint256 stakeLimitIncreasePerBlock); + event StakingLimitRemoved(); + event PrevStakeLimitUpdated(uint256 newPrevStakeLimit); + event StakeLimitPauseStateSet(bool isPaused); + + function harness_setState( + uint32 _prevStakeBlockNumber, + uint96 _prevStakeLimit, + uint32 _maxStakeLimitGrowthBlocks, + uint96 _maxStakeLimit + ) external { + state.prevStakeBlockNumber = _prevStakeBlockNumber; + state.prevStakeLimit = _prevStakeLimit; + state.maxStakeLimitGrowthBlocks = _maxStakeLimitGrowthBlocks; + state.maxStakeLimit = _maxStakeLimit; + + emit DataSet(_prevStakeBlockNumber, _prevStakeLimit, _maxStakeLimitGrowthBlocks, _maxStakeLimit); + } + + function harness_getState() + external + view + returns ( + uint32 prevStakeBlockNumber, + uint96 prevStakeLimit, + uint32 maxStakeLimitGrowthBlocks, + uint96 maxStakeLimit + ) + { + prevStakeBlockNumber = state.prevStakeBlockNumber; + prevStakeLimit = state.prevStakeLimit; + maxStakeLimitGrowthBlocks = state.maxStakeLimitGrowthBlocks; + maxStakeLimit = state.maxStakeLimit; + } + + function calculateCurrentStakeLimit() external view returns (uint256 limit) { + limit = state.calculateCurrentStakeLimit(); + } + + function isStakingPaused() external view returns (bool) { + return state.isStakingPaused(); + } + + function setStakingLimit(uint256 _maxStakeLimit, uint256 _stakeLimitIncreasePerBlock) external { + state = state.setStakingLimit(_maxStakeLimit, _stakeLimitIncreasePerBlock); + + emit StakingLimitSet(_maxStakeLimit, _stakeLimitIncreasePerBlock); + } + + function removeStakingLimit() external { + state = state.removeStakingLimit(); + + emit StakingLimitRemoved(); + } + + function updatePrevStakeLimit(uint256 _newPrevStakeLimit) external { + state = state.updatePrevStakeLimit(_newPrevStakeLimit); + + emit PrevStakeLimitUpdated(_newPrevStakeLimit); + } + + function setStakeLimitPauseState(bool _isPaused) external { + state = state.setStakeLimitPauseState(_isPaused); + + emit StakeLimitPauseStateSet(_isPaused); + } + + function constGasMin(uint256 _lhs, uint256 _rhs) external pure returns (uint256 min) { + min = StakeLimitUtils._constGasMin(_lhs, _rhs); + } } diff --git a/test/0.4.24/contracts/StakingRouter__MockForLidoHandleOracleReport.sol b/test/0.4.24/contracts/StakingRouter__MockForLidoHandleOracleReport.sol index d2825a9c4..ae5581f0f 100644 --- a/test/0.4.24/contracts/StakingRouter__MockForLidoHandleOracleReport.sol +++ b/test/0.4.24/contracts/StakingRouter__MockForLidoHandleOracleReport.sol @@ -1,49 +1,50 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only -pragma solidity 0.4.24; + +pragma solidity 0.8.9; contract StakingRouter__MockForLidoHandleOracleReport { - event Mock__MintedRewardsReported(); + event Mock__MintedRewardsReported(); - address[] private recipients__mocked; - uint256[] private stakingModuleIds__mocked; - uint96[] private stakingModuleFees__mocked; - uint96 private totalFee__mocked; - uint256 private precisionPoint__mocked; + address[] private recipients__mocked; + uint256[] private stakingModuleIds__mocked; + uint96[] private stakingModuleFees__mocked; + uint96 private totalFee__mocked; + uint256 private precisionPoint__mocked; - function getStakingRewardsDistribution() - public - view - returns ( - address[] memory recipients, - uint256[] memory stakingModuleIds, - uint96[] memory stakingModuleFees, - uint96 totalFee, - uint256 precisionPoints - ) - { - recipients = recipients__mocked; - stakingModuleIds = stakingModuleIds__mocked; - stakingModuleFees = stakingModuleFees__mocked; - totalFee = totalFee__mocked; - precisionPoints = precisionPoint__mocked; - } + function getStakingRewardsDistribution() + public + view + returns ( + address[] memory recipients, + uint256[] memory stakingModuleIds, + uint96[] memory stakingModuleFees, + uint96 totalFee, + uint256 precisionPoints + ) + { + recipients = recipients__mocked; + stakingModuleIds = stakingModuleIds__mocked; + stakingModuleFees = stakingModuleFees__mocked; + totalFee = totalFee__mocked; + precisionPoints = precisionPoint__mocked; + } - function reportRewardsMinted(uint256[] _stakingModuleIds, uint256[] _totalShares) external { - emit Mock__MintedRewardsReported(); - } + function reportRewardsMinted(uint256[] calldata _stakingModuleIds, uint256[] calldata _totalShares) external { + emit Mock__MintedRewardsReported(); + } - function mock__getStakingRewardsDistribution( - address[] _recipients, - uint256[] _stakingModuleIds, - uint96[] _stakingModuleFees, - uint96 _totalFee, - uint256 _precisionPoints - ) external { - recipients__mocked = _recipients; - stakingModuleIds__mocked = _stakingModuleIds; - stakingModuleFees__mocked = _stakingModuleFees; - totalFee__mocked = _totalFee; - precisionPoint__mocked = _precisionPoints; - } + function mock__getStakingRewardsDistribution( + address[] calldata _recipients, + uint256[] calldata _stakingModuleIds, + uint96[] calldata _stakingModuleFees, + uint96 _totalFee, + uint256 _precisionPoints + ) external { + recipients__mocked = _recipients; + stakingModuleIds__mocked = _stakingModuleIds; + stakingModuleFees__mocked = _stakingModuleFees; + totalFee__mocked = _totalFee; + precisionPoint__mocked = _precisionPoints; + } } diff --git a/test/0.4.24/contracts/StakingRouter__MockForLidoMisc.sol b/test/0.4.24/contracts/StakingRouter__MockForLidoMisc.sol index 3b949ef57..c14368284 100644 --- a/test/0.4.24/contracts/StakingRouter__MockForLidoMisc.sol +++ b/test/0.4.24/contracts/StakingRouter__MockForLidoMisc.sol @@ -1,51 +1,50 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only -pragma solidity 0.8.9; +pragma solidity 0.8.9; contract StakingRouter__MockForLidoMisc { - event Mock__DepositCalled(); - - uint256 private stakingModuleMaxDepositsCount; - - function getWithdrawalCredentials() external view returns(bytes32) { - return 0x010000000000000000000000b9d7934878b5fb9610b3fe8a5e441e8fad7e293f; // Lido Withdrawal Creds - } - - function getTotalFeeE4Precision() external view returns(uint16) { - return 1000; // 10% - } - - function TOTAL_BASIS_POINTS() external view returns(uint256) { - return 10000; // 100% - } - - function getStakingFeeAggregateDistributionE4Precision() external view returns( - uint16 treasuryFee, - uint16 modulesFee - ) { - treasuryFee = 500; - modulesFee = 500; - } - - function getStakingModuleMaxDepositsCount(uint256 _stakingModuleId, uint256 _maxDepositsValue) - public - view - returns (uint256) - { - return stakingModuleMaxDepositsCount; - } - - - function deposit( - uint256 _depositsCount, - uint256 _stakingModuleId, - bytes calldata _depositCalldata - ) external payable { - emit Mock__DepositCalled(); - } - - function mock__getStakingModuleMaxDepositsCount(uint256 newValue) external { - stakingModuleMaxDepositsCount = newValue; - } + event Mock__DepositCalled(); + + uint256 private stakingModuleMaxDepositsCount; + + function getWithdrawalCredentials() external view returns (bytes32) { + return 0x010000000000000000000000b9d7934878b5fb9610b3fe8a5e441e8fad7e293f; // Lido Withdrawal Creds + } + + function getTotalFeeE4Precision() external view returns (uint16) { + return 1000; // 10% + } + + function TOTAL_BASIS_POINTS() external view returns (uint256) { + return 10000; // 100% + } + + function getStakingFeeAggregateDistributionE4Precision() + external + view + returns (uint16 treasuryFee, uint16 modulesFee) + { + treasuryFee = 500; + modulesFee = 500; + } + + function getStakingModuleMaxDepositsCount( + uint256 _stakingModuleId, + uint256 _maxDepositsValue + ) public view returns (uint256) { + return stakingModuleMaxDepositsCount; + } + + function deposit( + uint256 _depositsCount, + uint256 _stakingModuleId, + bytes calldata _depositCalldata + ) external payable { + emit Mock__DepositCalled(); + } + + function mock__getStakingModuleMaxDepositsCount(uint256 newValue) external { + stakingModuleMaxDepositsCount = newValue; + } } diff --git a/test/0.4.24/contracts/StethPermitMockWithEip712Initialization.sol b/test/0.4.24/contracts/StethPermitMockWithEip712Initialization.sol deleted file mode 100644 index 19fbb5b50..000000000 --- a/test/0.4.24/contracts/StethPermitMockWithEip712Initialization.sol +++ /dev/null @@ -1,13 +0,0 @@ -// For testing purposes only -pragma solidity 0.4.24; - -import {StETHPermit} from "contracts/0.4.24/StETHPermit.sol"; -import {Steth__MinimalMock} from "test/0.4.24/contracts/Steth__MinimalMock.sol"; - -contract StethPermitMockWithEip712Initialization is StETHPermit, Steth__MinimalMock { - constructor(address _holder) payable Steth__MinimalMock(_holder) {} - - function initializeEIP712StETH(address _eip712StETH) external { - _initializeEIP712StETH(_eip712StETH); - } -} diff --git a/test/0.4.24/contracts/Steth__MinimalMock.sol b/test/0.4.24/contracts/Steth__MinimalMock.sol deleted file mode 100644 index b3775d9f3..000000000 --- a/test/0.4.24/contracts/Steth__MinimalMock.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.4.24; - -import {StETH} from "contracts/0.4.24/StETH.sol"; - -contract Steth__MinimalMock is StETH { - uint256 private totalPooledEther; - - constructor(address _holder) public payable { - _resume(); - uint256 balance = address(this).balance; - assert(balance != 0); - - setTotalPooledEther(balance); - _mintShares(_holder, balance); - } - - function _getTotalPooledEther() internal view returns (uint256) { - return totalPooledEther; - } - - function setTotalPooledEther(uint256 _totalPooledEther) public { - totalPooledEther = _totalPooledEther; - } - - function mintShares(address _recipient, uint256 _sharesAmount) external returns (uint256) { - return super._mintShares(_recipient, _sharesAmount); - } - - function burnShares(address _account, uint256 _sharesAmount) external returns (uint256) { - return super._burnShares(_account, _sharesAmount); - } -} diff --git a/test/0.4.24/contracts/Versioned__Harness0424.sol b/test/0.4.24/contracts/Versioned__Harness0424.sol index 17c58042b..4abc583b4 100644 --- a/test/0.4.24/contracts/Versioned__Harness0424.sol +++ b/test/0.4.24/contracts/Versioned__Harness0424.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.4.24; diff --git a/test/0.4.24/contracts/WithdrawalQueue__MockForLidoHandleOracleReport.sol b/test/0.4.24/contracts/WithdrawalQueue__MockForLidoHandleOracleReport.sol index 0d4e39f3c..238d76ee1 100644 --- a/test/0.4.24/contracts/WithdrawalQueue__MockForLidoHandleOracleReport.sol +++ b/test/0.4.24/contracts/WithdrawalQueue__MockForLidoHandleOracleReport.sol @@ -1,57 +1,56 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; contract WithdrawalQueue__MockForLidoHandleOracleReport { - event WithdrawalsFinalized( - uint256 indexed from, - uint256 indexed to, - uint256 amountOfETHLocked, - uint256 sharesToBurn, - uint256 timestamp - ); - - bool public isPaused; - - uint256 private ethToLock_; - uint256 private sharesToBurn_; - - function prefinalize( - uint256[] _batches, - uint256 _maxShareRate - ) external view returns (uint256 ethToLock, uint256 sharesToBurn) { - // listing params to avoid unused variable error - _batches; - _maxShareRate; - - ethToLock = ethToLock_; - sharesToBurn = sharesToBurn_; - } - - function finalize(uint256 _lastRequestIdToBeFinalized, uint256 _maxShareRate) external payable { - _maxShareRate; - - // some random fake event values - uint256 firstRequestIdToFinalize = 0; - uint256 sharesToBurn = msg.value; - - emit WithdrawalsFinalized( - firstRequestIdToFinalize, - _lastRequestIdToBeFinalized, - msg.value, - sharesToBurn, - block.timestamp + event WithdrawalsFinalized( + uint256 indexed from, + uint256 indexed to, + uint256 amountOfETHLocked, + uint256 sharesToBurn, + uint256 timestamp ); - } - - // test helpers - - function mock__isPaused(bool paused) external { - isPaused = paused; - } - function mock__prefinalizeReturn(uint256 _ethToLock, uint256 _sharesToBurn) external { - ethToLock_ = _ethToLock; - sharesToBurn_ = _sharesToBurn; - } + bool public isPaused; + + uint256 private ethToLock_; + uint256 private sharesToBurn_; + + function prefinalize( + uint256[] _batches, + uint256 _maxShareRate + ) external view returns (uint256 ethToLock, uint256 sharesToBurn) { + // listing params to avoid unused variable error + _batches; + _maxShareRate; + + ethToLock = ethToLock_; + sharesToBurn = sharesToBurn_; + } + + function finalize(uint256 _lastRequestIdToBeFinalized, uint256 _maxShareRate) external payable { + _maxShareRate; + + // some random fake event values + uint256 firstRequestIdToFinalize = 0; + uint256 sharesToBurn = msg.value; + + emit WithdrawalsFinalized( + firstRequestIdToFinalize, + _lastRequestIdToBeFinalized, + msg.value, + sharesToBurn, + block.timestamp + ); + } + + function mock__isPaused(bool paused) external { + isPaused = paused; + } + + function mock__prefinalizeReturn(uint256 _ethToLock, uint256 _sharesToBurn) external { + ethToLock_ = _ethToLock; + sharesToBurn_ = _sharesToBurn; + } } diff --git a/test/0.4.24/contracts/WithdrawalQueue__MockForLidoMisc.sol b/test/0.4.24/contracts/WithdrawalQueue__MockForLidoMisc.sol index 1eb0277ef..387d474e1 100644 --- a/test/0.4.24/contracts/WithdrawalQueue__MockForLidoMisc.sol +++ b/test/0.4.24/contracts/WithdrawalQueue__MockForLidoMisc.sol @@ -1,18 +1,17 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; contract WithdrawalQueue__MockForLidoMisc { - bool public isBunkerModeActive; - uint256 public unfinalizedStETH; - - // test helpers + bool public isBunkerModeActive; + uint256 public unfinalizedStETH; - function mock__bunkerMode(bool active) external { - isBunkerModeActive = active; - } + function mock__bunkerMode(bool active) external { + isBunkerModeActive = active; + } - function mock__unfinalizedStETH(uint256 amount) external { - unfinalizedStETH = amount; - } + function mock__unfinalizedStETH(uint256 amount) external { + unfinalizedStETH = amount; + } } diff --git a/test/0.4.24/contracts/WithdrawalVault__MockForLidoHandleOracleReport.sol b/test/0.4.24/contracts/WithdrawalVault__MockForLidoHandleOracleReport.sol index 3eee7d3b7..9de9542ab 100644 --- a/test/0.4.24/contracts/WithdrawalVault__MockForLidoHandleOracleReport.sol +++ b/test/0.4.24/contracts/WithdrawalVault__MockForLidoHandleOracleReport.sol @@ -1,14 +1,15 @@ // SPDX-License-Identifier: UNLICENSED // for testing purposes only + pragma solidity 0.4.24; contract WithdrawalVault__MockForLidoHandleOracleReport { - event Mock__WithdrawalsWithdrawn(); + event Mock__WithdrawalsWithdrawn(); - function withdrawWithdrawals(uint256 _amount) external { - _amount; + function withdrawWithdrawals(uint256 _amount) external { + _amount; - // emiting mock event to test that the function was in fact called - emit Mock__WithdrawalsWithdrawn(); - } + // emitting mock event to test that the function was in fact called + emit Mock__WithdrawalsWithdrawn(); + } } diff --git a/test/0.4.24/lib/packed64x4.t.sol b/test/0.4.24/lib/packed64x4.t.sol index be21673f1..a0c826c91 100644 --- a/test/0.4.24/lib/packed64x4.t.sol +++ b/test/0.4.24/lib/packed64x4.t.sol @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity ^0.4.24; diff --git a/test/0.4.24/lib/stakeLimitUtils.test.ts b/test/0.4.24/lib/stakeLimitUtils.test.ts index 6506a26df..e119c7769 100644 --- a/test/0.4.24/lib/stakeLimitUtils.test.ts +++ b/test/0.4.24/lib/stakeLimitUtils.test.ts @@ -216,9 +216,7 @@ describe("StakeLimitUtils.sol", () => { const baseStakeLimit = 0n; await stakeLimitUtils.harness_setState(prevStakeBlockNumber, 0n, maxStakeLimitGrowthBlocks, maxStakeLimit); // 1 block passed due to the setter call above - expect(await stakeLimitUtils.calculateCurrentStakeLimit()).to.equal( - maxStakeLimit / maxStakeLimitGrowthBlocks, - ); + expect(await stakeLimitUtils.calculateCurrentStakeLimit()).to.equal(maxStakeLimit / maxStakeLimitGrowthBlocks); // growth blocks passed (might be not equal to maxStakeLimit yet due to rounding) await mineUpTo(BigInt(prevStakeBlockNumber) + maxStakeLimitGrowthBlocks); diff --git a/test/0.4.24/lido/lido.finalizeUpgrade_v2.test.ts b/test/0.4.24/lido/lido.finalizeUpgrade_v2.test.ts index ab19fa4ed..61bddfa85 100644 --- a/test/0.4.24/lido/lido.finalizeUpgrade_v2.test.ts +++ b/test/0.4.24/lido/lido.finalizeUpgrade_v2.test.ts @@ -5,18 +5,19 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { time } from "@nomicfoundation/hardhat-network-helpers"; -import { Lido__MockForFinalizeUpgradeV2, Lido__MockForFinalizeUpgradeV2__factory, LidoLocator } from "typechain-types"; +import { Lido__HarnessForFinalizeUpgradeV2, LidoLocator } from "typechain-types"; import { certainAddress, INITIAL_STETH_HOLDER, ONE_ETHER, proxify } from "lib"; import { deployLidoLocator } from "test/deploy"; +import { Snapshot } from "test/suite"; -describe("Lido:finalizeUpgrade_v2", () => { +describe("Lido.sol:finalizeUpgrade_v2", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; - let impl: Lido__MockForFinalizeUpgradeV2; - let lido: Lido__MockForFinalizeUpgradeV2; + let impl: Lido__HarnessForFinalizeUpgradeV2; + let lido: Lido__HarnessForFinalizeUpgradeV2; let locator: LidoLocator; const initialValue = 1n; @@ -27,20 +28,25 @@ describe("Lido:finalizeUpgrade_v2", () => { let burnerAddress: string; const eip712helperAddress = certainAddress("lido:initialize:eip712helper"); - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, user] = await ethers.getSigners(); - const lidoFactory = new Lido__MockForFinalizeUpgradeV2__factory(deployer); - impl = await lidoFactory.deploy(); + impl = await ethers.deployContract("Lido__HarnessForFinalizeUpgradeV2"); [lido] = await proxify({ impl, admin: deployer }); locator = await deployLidoLocator(); [withdrawalQueueAddress, burnerAddress] = await Promise.all([locator.withdrawalQueue(), locator.burner()]); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + it("Reverts if contract version does not equal zero", async () => { const unexpectedVersion = 1n; - await expect(lido.mock__initialize(unexpectedVersion, { value: initialValue })) + await expect(lido.harness__initialize(unexpectedVersion, { value: initialValue })) .to.emit(lido, "Submitted") .withArgs(INITIAL_STETH_HOLDER, initialValue, ZeroAddress) .and.to.emit(lido, "Transfer") @@ -58,10 +64,10 @@ describe("Lido:finalizeUpgrade_v2", () => { }); context("contractVersion equals 0", () => { - beforeEach(async () => { + before(async () => { const latestBlock = BigInt(await time.latestBlock()); - await expect(lido.mock__initialize(initialVersion, { value: initialValue })) + await expect(lido.harness__initialize(initialVersion, { value: initialValue })) .to.emit(lido, "Submitted") .withArgs(INITIAL_STETH_HOLDER, initialValue, ZeroAddress) .and.to.emit(lido, "Transfer") @@ -85,9 +91,9 @@ describe("Lido:finalizeUpgrade_v2", () => { it("Reverts if the balance of initial holder is zero", async () => { // first get someone else's some tokens to avoid division by 0 error - await lido.mock__mintSharesWithoutChecks(user, ONE_ETHER); + await lido.harness__mintSharesWithoutChecks(user, ONE_ETHER); // then burn initial user's tokens - await lido.mock__burnInitialHoldersShares(); + await lido.harness__burnInitialHoldersShares(); await expect(lido.finalizeUpgrade_v2(locator, eip712helperAddress)).to.be.revertedWith("INITIAL_HOLDER_EXISTS"); }); diff --git a/test/0.4.24/lido/lido.handleOracleReport.test.ts b/test/0.4.24/lido/lido.handleOracleReport.test.ts index e56ee5b05..59a2d9893 100644 --- a/test/0.4.24/lido/lido.handleOracleReport.test.ts +++ b/test/0.4.24/lido/lido.handleOracleReport.test.ts @@ -8,32 +8,24 @@ import { getStorageAt, setBalance } from "@nomicfoundation/hardhat-network-helpe import { ACL, Burner__MockForLidoHandleOracleReport, - Burner__MockForLidoHandleOracleReport__factory, Lido, LidoExecutionLayerRewardsVault__MockForLidoHandleOracleReport, - LidoExecutionLayerRewardsVault__MockForLidoHandleOracleReport__factory, LidoLocator, - LidoLocator__factory, OracleReportSanityChecker__MockForLidoHandleOracleReport, - OracleReportSanityChecker__MockForLidoHandleOracleReport__factory, PostTokenRebaseReceiver__MockForLidoHandleOracleReport, - PostTokenRebaseReceiver__MockForLidoHandleOracleReport__factory, StakingRouter__MockForLidoHandleOracleReport, - StakingRouter__MockForLidoHandleOracleReport__factory, WithdrawalQueue__MockForLidoHandleOracleReport, - WithdrawalQueue__MockForLidoHandleOracleReport__factory, WithdrawalVault__MockForLidoHandleOracleReport, - WithdrawalVault__MockForLidoHandleOracleReport__factory, } from "typechain-types"; import { certainAddress, ether, getNextBlockTimestamp, impersonate, streccak } from "lib"; import { deployLidoDao, updateLidoLocatorImplementation } from "test/deploy"; +import { Snapshot } from "test/suite"; // TODO: improve coverage -// TODO: probably needs some refactoring and optimization // TODO: more math-focused tests -describe("Lido:report", () => { +describe("Lido.sol:report", () => { let deployer: HardhatEthersSigner; let accountingOracle: HardhatEthersSigner; let stethWhale: HardhatEthersSigner; @@ -50,7 +42,9 @@ describe("Lido:report", () => { let stakingRouter: StakingRouter__MockForLidoHandleOracleReport; let postTokenRebaseReceiver: PostTokenRebaseReceiver__MockForLidoHandleOracleReport; - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, accountingOracle, stethWhale, stranger] = await ethers.getSigners(); [ @@ -62,13 +56,13 @@ describe("Lido:report", () => { withdrawalQueue, withdrawalVault, ] = await Promise.all([ - new Burner__MockForLidoHandleOracleReport__factory(deployer).deploy(), - new LidoExecutionLayerRewardsVault__MockForLidoHandleOracleReport__factory(deployer).deploy(), - new OracleReportSanityChecker__MockForLidoHandleOracleReport__factory(deployer).deploy(), - new PostTokenRebaseReceiver__MockForLidoHandleOracleReport__factory(deployer).deploy(), - new StakingRouter__MockForLidoHandleOracleReport__factory(deployer).deploy(), - new WithdrawalQueue__MockForLidoHandleOracleReport__factory(deployer).deploy(), - new WithdrawalVault__MockForLidoHandleOracleReport__factory(deployer).deploy(), + ethers.deployContract("Burner__MockForLidoHandleOracleReport"), + ethers.deployContract("LidoExecutionLayerRewardsVault__MockForLidoHandleOracleReport"), + ethers.deployContract("OracleReportSanityChecker__MockForLidoHandleOracleReport"), + ethers.deployContract("PostTokenRebaseReceiver__MockForLidoHandleOracleReport"), + ethers.deployContract("StakingRouter__MockForLidoHandleOracleReport"), + ethers.deployContract("WithdrawalQueue__MockForLidoHandleOracleReport"), + ethers.deployContract("WithdrawalVault__MockForLidoHandleOracleReport"), ]); ({ lido, acl } = await deployLidoDao({ @@ -86,7 +80,7 @@ describe("Lido:report", () => { }, })); - locator = LidoLocator__factory.connect(await lido.getLidoLocator(), deployer); + locator = await ethers.getContractAt("LidoLocator", await lido.getLidoLocator(), deployer); await acl.createPermission(deployer, lido, await lido.RESUME_ROLE(), deployer); await acl.createPermission(deployer, lido, await lido.PAUSE_ROLE(), deployer); @@ -96,6 +90,10 @@ describe("Lido:report", () => { lido = lido.connect(accountingOracle); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("handleOracleReport", () => { it("Reverts when the contract is stopped", async () => { await lido.connect(deployer).stop(); @@ -572,8 +570,8 @@ describe("Lido:report", () => { const lidoLocatorAddress = await lido.getLidoLocator(); // Change the locator implementation to support zero address - await updateLidoLocatorImplementation(lidoLocatorAddress, {}, "LidoLocator__MutableMock", deployer); - const locatorMutable = await ethers.getContractAt("LidoLocator__MutableMock", lidoLocatorAddress, deployer); + await updateLidoLocatorImplementation(lidoLocatorAddress, {}, "LidoLocator__MockMutable", deployer); + const locatorMutable = await ethers.getContractAt("LidoLocator__MockMutable", lidoLocatorAddress, deployer); await locatorMutable.mock___updatePostTokenRebaseReceiver(ZeroAddress); expect(await locator.postTokenRebaseReceiver()).to.equal(ZeroAddress); diff --git a/test/0.4.24/lido/lido.initialize.test.ts b/test/0.4.24/lido/lido.initialize.test.ts index 927011842..ad949dd8a 100644 --- a/test/0.4.24/lido/lido.initialize.test.ts +++ b/test/0.4.24/lido/lido.initialize.test.ts @@ -5,14 +5,14 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { setStorageAt, time } from "@nomicfoundation/hardhat-network-helpers"; -import { Lido, Lido__factory, LidoLocator } from "typechain-types"; +import { Lido, LidoLocator } from "typechain-types"; import { certainAddress, INITIAL_STETH_HOLDER, proxify, streccak } from "lib"; import { deployLidoLocator } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("Lido:initialize", () => { +describe("Lido.sol:initialize", () => { let deployer: HardhatEthersSigner; let lido: Lido; @@ -21,8 +21,7 @@ describe("Lido:initialize", () => { before(async () => { [deployer] = await ethers.getSigners(); - const factory = new Lido__factory(deployer); - const impl = await factory.deploy(); + const impl = await ethers.deployContract("Lido", deployer); expect(await impl.getInitializationBlock()).to.equal(MaxUint256); [lido] = await proxify({ impl, admin: deployer }); @@ -42,7 +41,7 @@ describe("Lido:initialize", () => { let locator: LidoLocator; - beforeEach(async () => { + before(async () => { locator = await deployLidoLocator({ lido }); [withdrawalQueueAddress, burnerAddress] = await Promise.all([locator.withdrawalQueue(), locator.burner()]); }); diff --git a/test/0.4.24/lido/lido.misc.test.ts b/test/0.4.24/lido/lido.misc.test.ts index d7d23eb12..a2e3e8934 100644 --- a/test/0.4.24/lido/lido.misc.test.ts +++ b/test/0.4.24/lido/lido.misc.test.ts @@ -8,18 +8,15 @@ import { ACL, Lido, LidoLocator, - LidoLocator__factory, StakingRouter__MockForLidoMisc, - StakingRouter__MockForLidoMisc__factory, WithdrawalQueue__MockForLidoMisc, - WithdrawalQueue__MockForLidoMisc__factory, } from "typechain-types"; import { batch, certainAddress, ether, impersonate, ONE_ETHER } from "lib"; import { deployLidoDao } from "test/deploy"; -describe("Lido:misc", () => { +describe("Lido.sol:misc", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; let stranger: HardhatEthersSigner; @@ -36,11 +33,12 @@ describe("Lido:misc", () => { const elRewardsVaultBalance = ether("100.0"); const withdrawalsVaultBalance = ether("100.0"); + /// @notice structure of the test does not allow Snapshot usage beforeEach(async () => { [deployer, user, stranger, depositSecurityModule] = await ethers.getSigners(); - withdrawalQueue = await new WithdrawalQueue__MockForLidoMisc__factory(deployer).deploy(); - stakingRouter = await new StakingRouter__MockForLidoMisc__factory(deployer).deploy(); + withdrawalQueue = await ethers.deployContract("WithdrawalQueue__MockForLidoMisc", deployer); + stakingRouter = await ethers.deployContract("StakingRouter__MockForLidoMisc", deployer); ({ lido, acl } = await deployLidoDao({ rootAccount: deployer, @@ -57,7 +55,7 @@ describe("Lido:misc", () => { await acl.createPermission(user, lido, await lido.UNSAFE_CHANGE_DEPOSITED_VALIDATORS_ROLE(), deployer); lido = lido.connect(user); - locator = LidoLocator__factory.connect(await lido.getLidoLocator(), user); + locator = await ethers.getContractAt("LidoLocator", await lido.getLidoLocator(), user); elRewardsVault = await impersonate(await locator.elRewardsVault(), elRewardsVaultBalance); withdrawalsVault = await impersonate(await locator.withdrawalVault(), withdrawalsVaultBalance); diff --git a/test/0.4.24/lido/lido.pausable.test.ts b/test/0.4.24/lido/lido.pausable.test.ts index 2ef7ee8a5..9744abcc7 100644 --- a/test/0.4.24/lido/lido.pausable.test.ts +++ b/test/0.4.24/lido/lido.pausable.test.ts @@ -6,8 +6,9 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { ACL, Lido } from "typechain-types"; import { deployLidoDao } from "test/deploy"; +import { Snapshot } from "test/suite"; -describe("Lido:Pausable", () => { +describe("Lido.sol:pausable", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; let stranger: HardhatEthersSigner; @@ -15,7 +16,9 @@ describe("Lido:Pausable", () => { let lido: Lido; let acl: ACL; - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, user, stranger] = await ethers.getSigners(); ({ lido, acl } = await deployLidoDao({ rootAccount: deployer, initialized: true })); @@ -28,6 +31,10 @@ describe("Lido:Pausable", () => { lido = lido.connect(user); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("resumeStaking", () => { it("Resumes staking", async () => { expect(await lido.isStakingPaused()).to.equal(true); diff --git a/test/0.4.24/lido/lido.staking-limit.test.ts b/test/0.4.24/lido/lido.staking-limit.test.ts index 50bc960de..e7c9e3a66 100644 --- a/test/0.4.24/lido/lido.staking-limit.test.ts +++ b/test/0.4.24/lido/lido.staking-limit.test.ts @@ -10,8 +10,9 @@ import { ACL, Lido } from "typechain-types"; import { certainAddress, ether, ONE_ETHER } from "lib"; import { deployLidoDao } from "test/deploy"; +import { Snapshot } from "test/suite"; -describe("Lido:staking-limit", () => { +describe("Lido.sol:staking-limit", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; let stranger: HardhatEthersSigner; @@ -22,7 +23,9 @@ describe("Lido:staking-limit", () => { const maxStakeLimit = ether("10.0"); const stakeLimitIncreasePerBlock = ether("2.0"); - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, user, stranger] = await ethers.getSigners(); ({ lido, acl } = await deployLidoDao({ rootAccount: deployer, initialized: true })); @@ -35,6 +38,10 @@ describe("Lido:staking-limit", () => { lido = lido.connect(user); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("getCurrentStakeLimit", () => { it("Returns zero if staking is paused", async () => { expect(await lido.getCurrentStakeLimit()).to.equal(0); diff --git a/test/0.4.24/lido/lido.staking.test.ts b/test/0.4.24/lido/lido.staking.test.ts index 71b1bead1..dfe1f3fe9 100644 --- a/test/0.4.24/lido/lido.staking.test.ts +++ b/test/0.4.24/lido/lido.staking.test.ts @@ -9,8 +9,9 @@ import { ACL, Lido } from "typechain-types"; import { certainAddress, ether, ONE_ETHER } from "lib"; import { deployLidoDao } from "test/deploy"; +import { Snapshot } from "test/suite"; -describe("Lido:staking", () => { +describe("Lido.sol:staking", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; @@ -20,7 +21,9 @@ describe("Lido:staking", () => { const maxStakeLimit = ether("10.0"); const stakeLimitIncreasePerBlock = ether("2.0"); - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, user] = await ethers.getSigners(); ({ lido, acl } = await deployLidoDao({ rootAccount: deployer, initialized: true })); @@ -33,6 +36,10 @@ describe("Lido:staking", () => { lido = lido.connect(user); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("fallback", () => { beforeEach(async () => { await lido.resumeStaking(); diff --git a/test/0.4.24/nor/nor.aux.test.ts b/test/0.4.24/nor/nor.aux.test.ts index a09a1816b..635416708 100644 --- a/test/0.4.24/nor/nor.aux.test.ts +++ b/test/0.4.24/nor/nor.aux.test.ts @@ -4,22 +4,14 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - ACL, - Kernel, - Lido, - LidoLocator, - LidoLocator__factory, - NodeOperatorsRegistry__Harness, - NodeOperatorsRegistry__Harness__factory, -} from "typechain-types"; +import { ACL, Kernel, Lido, LidoLocator, NodeOperatorsRegistry__Harness } from "typechain-types"; import { addNodeOperator, certainAddress, NodeOperatorConfig, prepIdsCountsPayload } from "lib"; import { addAragonApp, deployLidoDao } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("NodeOperatorsRegistry:auxiliary", () => { +describe("NodeOperatorsRegistry.sol:auxiliary", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; let stranger: HardhatEthersSigner; @@ -107,7 +99,7 @@ describe("NodeOperatorsRegistry:auxiliary", () => { }, })); - impl = await new NodeOperatorsRegistry__Harness__factory(deployer).deploy(); + impl = await ethers.deployContract("NodeOperatorsRegistry__Harness", deployer); const appProxy = await addAragonApp({ dao, name: "node-operators-registry", @@ -115,7 +107,7 @@ describe("NodeOperatorsRegistry:auxiliary", () => { rootAccount: deployer, }); - nor = NodeOperatorsRegistry__Harness__factory.connect(appProxy, deployer); + nor = await ethers.getContractAt("NodeOperatorsRegistry__Harness", appProxy, deployer); await acl.createPermission(user, lido, await lido.RESUME_ROLE(), deployer); @@ -128,7 +120,7 @@ describe("NodeOperatorsRegistry:auxiliary", () => { // inside the harness__requestValidatorsKeysForDeposits() method await acl.grantPermission(nor, nor, await nor.STAKING_ROUTER_ROLE()); - locator = LidoLocator__factory.connect(await lido.getLidoLocator(), user); + locator = await ethers.getContractAt("LidoLocator", await lido.getLidoLocator(), user); // Initialize the nor's proxy. await expect(nor.initialize(locator, moduleType, penaltyDelay)) @@ -214,7 +206,7 @@ describe("NodeOperatorsRegistry:auxiliary", () => { ); }); - it("reverts with \"APP_AUTH_FAILED\" error when called by sender without STAKING_ROUTER_ROLE", async () => { + it('reverts with "APP_AUTH_FAILED" error when called by sender without STAKING_ROUTER_ROLE', async () => { expect(await acl["hasPermission(address,address,bytes32)"](stranger, nor, await nor.STAKING_ROUTER_ROLE())).to.be .false; @@ -223,7 +215,7 @@ describe("NodeOperatorsRegistry:auxiliary", () => { ); }); - it("reverts with \"OUT_OF_RANGE\" error when called with targetLimit > UINT64_MAX", async () => { + it('reverts with "OUT_OF_RANGE" error when called with targetLimit > UINT64_MAX', async () => { const targetLimitWrong = BigInt("0x10000000000000000"); await expect( @@ -335,13 +327,13 @@ describe("NodeOperatorsRegistry:auxiliary", () => { .withArgs( firstNodeOperatorId, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - - NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount, + NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount, ) .and.to.emit(nor, "NodeOperatorTotalKeysTrimmed") .withArgs( secondNodeOperatorId, NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount - - NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount, + NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount, ) .to.emit(nor, "KeysOpIndexSet") .withArgs(nonce + 1n) @@ -401,13 +393,13 @@ describe("NodeOperatorsRegistry:auxiliary", () => { .withArgs( firstNodeOperatorId, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - - NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount, + NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount, ) .and.to.emit(nor, "NodeOperatorTotalKeysTrimmed") .withArgs( secondNodeOperatorId, NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount - - NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount, + NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount, ) .to.emit(nor, "KeysOpIndexSet") .withArgs(nonce + 1n) diff --git a/test/0.4.24/nor/nor.initialize.upgrade.test.ts b/test/0.4.24/nor/nor.initialize.upgrade.test.ts index d8a229461..1a046be90 100644 --- a/test/0.4.24/nor/nor.initialize.upgrade.test.ts +++ b/test/0.4.24/nor/nor.initialize.upgrade.test.ts @@ -5,22 +5,14 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { time } from "@nomicfoundation/hardhat-network-helpers"; -import { - ACL, - Kernel, - Lido, - LidoLocator, - LidoLocator__factory, - NodeOperatorsRegistry__Harness, - NodeOperatorsRegistry__Harness__factory, -} from "typechain-types"; +import { ACL, Kernel, Lido, LidoLocator, NodeOperatorsRegistry__Harness } from "typechain-types"; import { addNodeOperator, certainAddress, NodeOperatorConfig } from "lib"; import { addAragonApp, deployLidoDao, deployLidoLocator } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("NodeOperatorsRegistry:initialize-and-upgrade", () => { +describe("NodeOperatorsRegistry.sol:initialize-and-upgrade", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; @@ -105,7 +97,7 @@ describe("NodeOperatorsRegistry:initialize-and-upgrade", () => { }, })); - const impl = await new NodeOperatorsRegistry__Harness__factory(deployer).deploy(); + const impl = await ethers.deployContract("NodeOperatorsRegistry__Harness", deployer); expect(await impl.getInitializationBlock()).to.equal(MaxUint256); const appProxy = await addAragonApp({ dao, @@ -114,7 +106,7 @@ describe("NodeOperatorsRegistry:initialize-and-upgrade", () => { rootAccount: deployer, }); - nor = NodeOperatorsRegistry__Harness__factory.connect(appProxy, deployer); + nor = await ethers.getContractAt("NodeOperatorsRegistry__Harness", appProxy, deployer); await acl.createPermission(user, lido, await lido.RESUME_ROLE(), deployer); @@ -127,7 +119,7 @@ describe("NodeOperatorsRegistry:initialize-and-upgrade", () => { // inside the harness__requestValidatorsKeysForDeposits() method await acl.grantPermission(nor, nor, await nor.STAKING_ROUTER_ROLE()); - locator = LidoLocator__factory.connect(await lido.getLidoLocator(), user); + locator = await ethers.getContractAt("LidoLocator", await lido.getLidoLocator(), user); }); beforeEach(async () => (originalState = await Snapshot.take())); @@ -319,24 +311,16 @@ describe("NodeOperatorsRegistry:initialize-and-upgrade", () => { expect(summary.depositableValidatorsCount).to.equal(0n + 8n + 0n + 0n); const firstNoInfo = await nor.getNodeOperator(firstNodeOperatorId, true); - expect(firstNoInfo.totalVettedValidators).to.equal( - NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount, - ); + expect(firstNoInfo.totalVettedValidators).to.equal(NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount); const secondNoInfo = await nor.getNodeOperator(secondNodeOperatorId, true); - expect(secondNoInfo.totalVettedValidators).to.equal( - NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount, - ); + expect(secondNoInfo.totalVettedValidators).to.equal(NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount); const thirdNoInfo = await nor.getNodeOperator(thirdNodeOperatorId, true); - expect(thirdNoInfo.totalVettedValidators).to.equal( - NODE_OPERATORS[thirdNodeOperatorId].depositedSigningKeysCount, - ); + expect(thirdNoInfo.totalVettedValidators).to.equal(NODE_OPERATORS[thirdNodeOperatorId].depositedSigningKeysCount); const fourthNoInfo = await nor.getNodeOperator(fourthNodeOperatorId, true); - expect(fourthNoInfo.totalVettedValidators).to.equal( - NODE_OPERATORS[fourthNodeOperatorId].vettedSigningKeysCount, - ); + expect(fourthNoInfo.totalVettedValidators).to.equal(NODE_OPERATORS[fourthNodeOperatorId].vettedSigningKeysCount); }); }); }); diff --git a/test/0.4.24/nor/nor.management.flow.test.ts b/test/0.4.24/nor/nor.management.flow.test.ts index 49fb69404..720142bcf 100644 --- a/test/0.4.24/nor/nor.management.flow.test.ts +++ b/test/0.4.24/nor/nor.management.flow.test.ts @@ -4,22 +4,14 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - ACL, - Kernel, - Lido, - LidoLocator, - LidoLocator__factory, - NodeOperatorsRegistry__Harness, - NodeOperatorsRegistry__Harness__factory, -} from "typechain-types"; +import { ACL, Kernel, Lido, LidoLocator, NodeOperatorsRegistry__Harness } from "typechain-types"; import { addNodeOperator, certainAddress, NodeOperatorConfig, randomAddress } from "lib"; import { addAragonApp, deployLidoDao } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("NodeOperatorsRegistry:management", () => { +describe("NodeOperatorsRegistry.sol:management", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; @@ -94,7 +86,7 @@ describe("NodeOperatorsRegistry:management", () => { }, })); - impl = await new NodeOperatorsRegistry__Harness__factory(deployer).deploy(); + impl = await ethers.deployContract("NodeOperatorsRegistry__Harness", deployer); const appProxy = await addAragonApp({ dao, name: "node-operators-registry", @@ -102,7 +94,7 @@ describe("NodeOperatorsRegistry:management", () => { rootAccount: deployer, }); - nor = NodeOperatorsRegistry__Harness__factory.connect(appProxy, deployer); + nor = await ethers.getContractAt("NodeOperatorsRegistry__Harness", appProxy, deployer); await acl.createPermission(user, lido, await lido.RESUME_ROLE(), deployer); @@ -115,7 +107,7 @@ describe("NodeOperatorsRegistry:management", () => { // inside the testing_requestValidatorsKeysForDeposits() method await acl.grantPermission(nor, nor, await nor.STAKING_ROUTER_ROLE()); - locator = LidoLocator__factory.connect(await lido.getLidoLocator(), user); + locator = await ethers.getContractAt("LidoLocator", await lido.getLidoLocator(), user); // Initialize the nor's proxy. await expect(nor.initialize(locator, moduleType, penaltyDelay)) @@ -134,9 +126,6 @@ describe("NodeOperatorsRegistry:management", () => { afterEach(async () => await Snapshot.restore(originalState)); context("addNodeOperator", () => { - beforeEach(async () => { - }); - it("Reverts if invalid name", async () => { await expect(nor.addNodeOperator("", certainAddress("reward-address-0"))).to.be.revertedWith("WRONG_NAME_LENGTH"); @@ -505,9 +494,7 @@ describe("NodeOperatorsRegistry:management", () => { expect(noInfo.totalVettedValidators).to.equal(NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount); expect(noInfo.totalExitedValidators).to.equal(NODE_OPERATORS[secondNodeOperatorId].exitedSigningKeysCount); expect(noInfo.totalAddedValidators).to.equal(NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount); - expect(noInfo.totalDepositedValidators).to.equal( - NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount, - ); + expect(noInfo.totalDepositedValidators).to.equal(NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount); }); it("Returns full info with name", async () => { @@ -519,9 +506,7 @@ describe("NodeOperatorsRegistry:management", () => { expect(noInfo.totalVettedValidators).to.equal(NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount); expect(noInfo.totalExitedValidators).to.equal(NODE_OPERATORS[secondNodeOperatorId].exitedSigningKeysCount); expect(noInfo.totalAddedValidators).to.equal(NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount); - expect(noInfo.totalDepositedValidators).to.equal( - NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount, - ); + expect(noInfo.totalDepositedValidators).to.equal(NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount); }); }); diff --git a/test/0.4.24/nor/nor.rewards.penalties.flow.test.ts b/test/0.4.24/nor/nor.rewards.penalties.flow.test.ts index 5d7bf4412..5e98e76e8 100644 --- a/test/0.4.24/nor/nor.rewards.penalties.flow.test.ts +++ b/test/0.4.24/nor/nor.rewards.penalties.flow.test.ts @@ -5,16 +5,7 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { time } from "@nomicfoundation/hardhat-network-helpers"; -import { - ACL, - Burner__MockForLidoHandleOracleReport__factory, - Kernel, - Lido, - LidoLocator, - LidoLocator__factory, - NodeOperatorsRegistry__Harness, - NodeOperatorsRegistry__Harness__factory, -} from "typechain-types"; +import { ACL, Kernel, Lido, LidoLocator, NodeOperatorsRegistry__Harness } from "typechain-types"; import { addNodeOperator, @@ -28,7 +19,7 @@ import { import { addAragonApp, deployLidoDao } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("NodeOperatorsRegistry:rewards-penalties", () => { +describe("NodeOperatorsRegistry.sol:rewards-penalties", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; let stranger: HardhatEthersSigner; @@ -96,7 +87,7 @@ describe("NodeOperatorsRegistry:rewards-penalties", () => { [deployer, user, stakingRouter, nodeOperatorsManager, signingKeysManager, limitsManager, stranger] = await ethers.getSigners(); - const burner = await new Burner__MockForLidoHandleOracleReport__factory(deployer).deploy(); + const burner = await ethers.deployContract("Burner__MockForLidoHandleOracleReport"); ({ lido, dao, acl } = await deployLidoDao({ rootAccount: deployer, @@ -107,7 +98,7 @@ describe("NodeOperatorsRegistry:rewards-penalties", () => { }, })); - impl = await new NodeOperatorsRegistry__Harness__factory(deployer).deploy(); + impl = await ethers.deployContract("NodeOperatorsRegistry__Harness"); const appProxy = await addAragonApp({ dao, name: "node-operators-registry", @@ -115,7 +106,7 @@ describe("NodeOperatorsRegistry:rewards-penalties", () => { rootAccount: deployer, }); - nor = NodeOperatorsRegistry__Harness__factory.connect(appProxy, deployer); + nor = await ethers.getContractAt("NodeOperatorsRegistry__Harness", appProxy, deployer); await acl.createPermission(user, lido, await lido.RESUME_ROLE(), deployer); @@ -128,7 +119,7 @@ describe("NodeOperatorsRegistry:rewards-penalties", () => { // inside the testing_requestValidatorsKeysForDeposits() method await acl.grantPermission(nor, nor, await nor.STAKING_ROUTER_ROLE()); - locator = LidoLocator__factory.connect(await lido.getLidoLocator(), user); + locator = await ethers.getContractAt("LidoLocator", await lido.getLidoLocator(), user); // Initialize the nor's proxy. await expect(nor.initialize(locator, moduleType, penaltyDelay)) diff --git a/test/0.4.24/nor/nor.signing.keys.test.ts b/test/0.4.24/nor/nor.signing.keys.test.ts index 646a7165c..b7d42fda5 100644 --- a/test/0.4.24/nor/nor.signing.keys.test.ts +++ b/test/0.4.24/nor/nor.signing.keys.test.ts @@ -4,15 +4,7 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - ACL, - Kernel, - Lido, - LidoLocator, - LidoLocator__factory, - NodeOperatorsRegistry__Harness, - NodeOperatorsRegistry__Harness__factory, -} from "typechain-types"; +import { ACL, Kernel, Lido, LidoLocator, NodeOperatorsRegistry__Harness } from "typechain-types"; import { addNodeOperator, @@ -30,7 +22,7 @@ import { import { addAragonApp, deployLidoDao } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("NodeOperatorsRegistry:signing-keys", () => { +describe("NodeOperatorsRegistry.sol:signing-keys", () => { const UINT64_MAX = 2n ** 64n - 1n; let deployer: HardhatEthersSigner; @@ -125,7 +117,7 @@ describe("NodeOperatorsRegistry:signing-keys", () => { }, })); - impl = await new NodeOperatorsRegistry__Harness__factory(deployer).deploy(); + impl = await ethers.deployContract("NodeOperatorsRegistry__Harness", deployer); const appProxy = await addAragonApp({ dao, name: "node-operators-registry", @@ -133,7 +125,7 @@ describe("NodeOperatorsRegistry:signing-keys", () => { rootAccount: deployer, }); - nor = NodeOperatorsRegistry__Harness__factory.connect(appProxy, deployer); + nor = await ethers.getContractAt("NodeOperatorsRegistry__Harness", appProxy, deployer); await acl.createPermission(user, lido, await lido.RESUME_ROLE(), deployer); @@ -146,7 +138,7 @@ describe("NodeOperatorsRegistry:signing-keys", () => { // inside the testing_requestValidatorsKeysForDeposits() method await acl.grantPermission(nor, nor, await nor.STAKING_ROUTER_ROLE()); - locator = LidoLocator__factory.connect(await lido.getLidoLocator(), user); + locator = await ethers.getContractAt("LidoLocator", await lido.getLidoLocator(), deployer); // Initialize the nor's proxy. await expect(nor.initialize(locator, moduleType, penaltyDelay)) @@ -257,9 +249,9 @@ describe("NodeOperatorsRegistry:signing-keys", () => { const summaryBefore = await nor.getStakingModuleSummary(); expect(summaryBefore.depositableValidatorsCount).to.equal( NODE_OPERATORS[firstNodeOperatorId].vettedSigningKeysCount - - NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount + - NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount - - NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount, + NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount + + NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount - + NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount, ); await expect(nor.connect(stakingRouter).harness__obtainDepositData(summaryBefore.depositableValidatorsCount)) @@ -628,9 +620,7 @@ describe("NodeOperatorsRegistry:signing-keys", () => { } expect(preFirstNOInfo[totalVettedValidatorsIndex]).to.equal(postFirstNOInfo[totalVettedValidatorsIndex] + 1n); - expect(preSecondNOInfo[totalVettedValidatorsIndex]).to.equal( - postSecondNOInfo[totalVettedValidatorsIndex] + 3n, - ); + expect(preSecondNOInfo[totalVettedValidatorsIndex]).to.equal(postSecondNOInfo[totalVettedValidatorsIndex] + 3n); expect(preFirstNOInfo[totalAddedValidatorsIndex]).to.equal(postFirstNOInfo[totalAddedValidatorsIndex] + 3n); expect(preSecondNOInfo[totalAddedValidatorsIndex]).to.equal(postSecondNOInfo[totalAddedValidatorsIndex] + 5n); @@ -782,9 +772,7 @@ describe("NodeOperatorsRegistry:signing-keys", () => { } expect(preFirstNOInfo[totalVettedValidatorsIndex]).to.equal(postFirstNOInfo[totalVettedValidatorsIndex] + 1n); - expect(preSecondNOInfo[totalVettedValidatorsIndex]).to.equal( - postSecondNOInfo[totalVettedValidatorsIndex] + 3n, - ); + expect(preSecondNOInfo[totalVettedValidatorsIndex]).to.equal(postSecondNOInfo[totalVettedValidatorsIndex] + 3n); expect(preFirstNOInfo[totalAddedValidatorsIndex]).to.equal(postFirstNOInfo[totalAddedValidatorsIndex] + 1n); expect(preSecondNOInfo[totalAddedValidatorsIndex]).to.equal(postSecondNOInfo[totalAddedValidatorsIndex] + 1n); diff --git a/test/0.4.24/oracle/legacyOracle.test.ts b/test/0.4.24/oracle/legacyOracle.test.ts index 6fe6b902d..59f91d254 100644 --- a/test/0.4.24/oracle/legacyOracle.test.ts +++ b/test/0.4.24/oracle/legacyOracle.test.ts @@ -6,7 +6,7 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { AccountingOracle__MockForLegacyOracle, - HashConsensus__MockForLegacyOracle, + HashConsensus__HarnessForLegacyOracle, LegacyOracle__Harness, LidoLocator, } from "typechain-types"; @@ -35,7 +35,7 @@ describe("LegacyOracle.sol", () => { let legacyOracle: LegacyOracle__Harness; let locator: LidoLocator; - let consensusContract: HashConsensus__MockForLegacyOracle; + let consensusContract: HashConsensus__HarnessForLegacyOracle; let accountingOracle: AccountingOracle__MockForLegacyOracle; let lido: string; @@ -50,7 +50,7 @@ describe("LegacyOracle.sol", () => { lido = certainAddress("legacy-oracle:lido"); - consensusContract = await ethers.deployContract("HashConsensus__MockForLegacyOracle", [ + consensusContract = await ethers.deployContract("HashConsensus__HarnessForLegacyOracle", [ SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME, @@ -151,10 +151,7 @@ describe("LegacyOracle.sol", () => { expect(frame.frameEpochId).to.equal((consensusFrame.refSlot + 1n) / SLOTS_PER_EPOCH, "frameEpochId"); expect(frame.frameStartTime).to.equal(timestampAtSlot(consensusFrame.refSlot + 1n), "frameStartTime"); - expect(frame.frameEndTime).to.equal( - timestampAtEpoch(frame.frameEpochId + EPOCHS_PER_FRAME) - 1n, - "frameEndTime", - ); + expect(frame.frameEndTime).to.equal(timestampAtEpoch(frame.frameEpochId + EPOCHS_PER_FRAME) - 1n, "frameEndTime"); }); it("Returns frame synced with consensus contract on the edge", async () => { @@ -289,11 +286,11 @@ describe("LegacyOracle.sol", () => { await updateLidoLocatorImplementation( brokenLocatorAddress, { accountingOracle }, - "LidoLocator__MutableMock", + "LidoLocator__MockMutable", admin, ); - const locatorMutable = await ethers.getContractAt("LidoLocator__MutableMock", brokenLocatorAddress); + const locatorMutable = await ethers.getContractAt("LidoLocator__MockMutable", brokenLocatorAddress); await locatorMutable.mock___updateAccountingOracle(ZeroAddress); await expect(legacyOracle.initialize(locatorMutable, ZeroAddress)).to.revertedWith( @@ -317,7 +314,7 @@ describe("LegacyOracle.sol", () => { epochsPerFrame = EPOCHS_PER_FRAME, initialFastLaneLengthSlots = INITIAL_FAST_LANE_LENGTH_SLOTS, }) { - const invalidConsensusContract = await ethers.deployContract("HashConsensus__MockForLegacyOracle", [ + const invalidConsensusContract = await ethers.deployContract("HashConsensus__HarnessForLegacyOracle", [ slotsPerEpoch, secondsPerSlot, genesisTime, diff --git a/test/0.4.24/steth.erc20.test.ts b/test/0.4.24/steth.erc20.test.ts index d71ac48ab..98a7db03a 100644 --- a/test/0.4.24/steth.erc20.test.ts +++ b/test/0.4.24/steth.erc20.test.ts @@ -1,7 +1,5 @@ import { ethers } from "hardhat"; -import { Steth__MinimalMock__factory } from "typechain-types"; - import { ether } from "lib/units"; import { testERC20Compliance } from "../common/erc20.test"; @@ -26,8 +24,7 @@ async function deploy(rebaseFactor: bigint = 100n) { const [deployer, holder, recipient, spender] = signers; const holderBalance = ether("10.0"); - const factory = new Steth__MinimalMock__factory(deployer); - const steth = await factory.deploy(holder, { value: holderBalance }); + const steth = await ethers.deployContract("StETH__Harness", [holder], { value: holderBalance, from: deployer }); const totalSupply = (holderBalance * rebaseFactor) / 100n; await steth.setTotalPooledEther(totalSupply); diff --git a/test/0.4.24/steth.erc2612.test.ts b/test/0.4.24/steth.erc2612.test.ts index a72c09d4f..b98e2ae89 100644 --- a/test/0.4.24/steth.erc2612.test.ts +++ b/test/0.4.24/steth.erc2612.test.ts @@ -1,11 +1,5 @@ import { ethers } from "hardhat"; -import { - EIP712StETH__factory, - ERC1271Wallet__factory, - StethPermitMockWithEip712Initialization__factory, -} from "typechain-types"; - import { ether, stethDomain } from "lib"; import { testERC2612Compliance } from "../common/erc2612.test"; @@ -16,9 +10,12 @@ testERC2612Compliance({ const [deployer, owner] = await ethers.getSigners(); const value = ether("1.0"); - const steth = await new StethPermitMockWithEip712Initialization__factory(deployer).deploy(owner, { value }); + const steth = await ethers.deployContract("StETHPermit__HarnessWithEip712Initialization", [owner], { + value, + from: deployer, + }); - const eip712helper = await new EIP712StETH__factory(deployer).deploy(steth); + const eip712helper = await ethers.deployContract("EIP712StETH", [steth], deployer); await steth.initializeEIP712StETH(eip712helper); return { @@ -36,12 +33,15 @@ testERC2612Compliance({ const [deployer, owner] = await ethers.getSigners(); const value = ether("1.0"); - const steth = await new StethPermitMockWithEip712Initialization__factory(deployer).deploy(owner, { value }); + const steth = await ethers.deployContract("StETHPermit__HarnessWithEip712Initialization", [owner], { + value, + from: deployer, + }); - const eip712helper = await new EIP712StETH__factory(deployer).deploy(steth); + const eip712helper = await ethers.deployContract("EIP712StETH", [steth], deployer); await steth.initializeEIP712StETH(eip712helper); - const wallet = await new ERC1271Wallet__factory(deployer).deploy(owner.address); + const wallet = await ethers.deployContract("ERC1271Wallet", [owner], deployer); await steth.connect(owner).transfer(await wallet.getAddress(), await steth.balanceOf(owner)); return { diff --git a/test/0.4.24/steth.test.ts b/test/0.4.24/steth.test.ts index 336100fc0..b73981782 100644 --- a/test/0.4.24/steth.test.ts +++ b/test/0.4.24/steth.test.ts @@ -5,14 +5,16 @@ import { beforeEach } from "mocha"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { Steth__MinimalMock, Steth__MinimalMock__factory } from "typechain-types"; +import { StETH__Harness } from "typechain-types"; import { batch, ether, impersonate, ONE_ETHER } from "lib"; +import { Snapshot } from "test/suite"; + const ONE_STETH = 10n ** 18n; const ONE_SHARE = 10n ** 18n; -describe("StETH:non-ERC-20 behavior", () => { +describe("StETH.sol:non-ERC-20 behavior", () => { let deployer: HardhatEthersSigner; let holder: HardhatEthersSigner; let recipient: HardhatEthersSigner; @@ -23,19 +25,23 @@ describe("StETH:non-ERC-20 behavior", () => { const holderBalance = ether("10.0"); const totalSupply = holderBalance; - let steth: Steth__MinimalMock; + let steth: StETH__Harness; + + let originalState: string; - beforeEach(async () => { + before(async () => { zeroAddressSigner = await impersonate(ZeroAddress, ONE_ETHER); - const signers = await ethers.getSigners(); - [deployer, holder, recipient, spender] = signers; + [deployer, holder, recipient, spender] = await ethers.getSigners(); - const factory = new Steth__MinimalMock__factory(deployer); - steth = await factory.deploy(holder, { value: holderBalance }); + steth = await ethers.deployContract("StETH__Harness", [holder], { value: holderBalance, from: deployer }); steth = steth.connect(holder); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("getTotalPooledEther", () => { it("Returns the amount of ether sent upon construction", async () => { expect(await steth.getTotalPooledEther()).to.equal(totalSupply); diff --git a/test/0.4.24/stethPermit.test.ts b/test/0.4.24/stethPermit.test.ts index 1c0f73ff8..5f6076cbb 100644 --- a/test/0.4.24/stethPermit.test.ts +++ b/test/0.4.24/stethPermit.test.ts @@ -4,17 +4,13 @@ import { ethers } from "hardhat"; import { time } from "@nomicfoundation/hardhat-network-helpers"; -import { - EIP712StETH__factory, - StethPermitMockWithEip712Initialization, - StethPermitMockWithEip712Initialization__factory, -} from "typechain-types"; +import { StETHPermit__HarnessWithEip712Initialization } from "typechain-types"; import { certainAddress, days, ether, Permit, signPermit, stethDomain } from "lib"; import { Snapshot } from "test/suite"; -describe("Permit", () => { +describe("StETHPermit.sol", () => { let deployer: Signer; let signer: Signer; @@ -22,13 +18,14 @@ describe("Permit", () => { let permit: Permit; let signature: Signature; - let steth: StethPermitMockWithEip712Initialization; + let steth: StETHPermit__HarnessWithEip712Initialization; before(async () => { [deployer, signer] = await ethers.getSigners(); - steth = await new StethPermitMockWithEip712Initialization__factory(deployer).deploy(signer, { + steth = await ethers.deployContract("StETHPermit__HarnessWithEip712Initialization", [signer], { value: ether("10.0"), + from: deployer, }); const holderBalance = await steth.balanceOf(signer); @@ -88,7 +85,7 @@ describe("Permit", () => { context("Initialized", () => { beforeEach(async () => { - const eip712helper = await new EIP712StETH__factory(deployer).deploy(steth); + const eip712helper = await ethers.deployContract("EIP712StETH", [steth], deployer); await steth.initializeEIP712StETH(eip712helper); }); diff --git a/test/0.4.24/utils/pausable.test.ts b/test/0.4.24/utils/pausable.test.ts index f1a128483..5e8274312 100644 --- a/test/0.4.24/utils/pausable.test.ts +++ b/test/0.4.24/utils/pausable.test.ts @@ -1,16 +1,24 @@ import { expect } from "chai"; import { ethers } from "hardhat"; -import { PausableMockWithExposedApi } from "typechain-types"; +import { Pausable__Harness } from "typechain-types"; -describe("Pausable", () => { - let pausable: PausableMockWithExposedApi; +import { Snapshot } from "test/suite"; - beforeEach(async () => { - pausable = await ethers.deployContract("PausableMockWithExposedApi"); +describe("Pausable.sol", () => { + let pausable: Pausable__Harness; + + let originalState: string; + + before(async () => { + pausable = await ethers.deployContract("Pausable__Harness"); expect(await pausable.isStopped()).to.equal(true); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("isStopped", () => { it("Returns true if stopped", async () => { expect(await pausable.isStopped()).to.equal(true); diff --git a/test/0.4.24/versioned.test.ts b/test/0.4.24/versioned.test.ts index de951fcc1..c878beb9e 100644 --- a/test/0.4.24/versioned.test.ts +++ b/test/0.4.24/versioned.test.ts @@ -3,10 +3,10 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { OssifiableProxy, Versioned__Harness0424, Versioned__Harness0424__factory } from "typechain-types"; +import { OssifiableProxy, Versioned__Harness0424 } from "typechain-types"; // TODO: rewrite to be reusable for any derived contract -describe("Versioned", () => { +describe("Versioned.sol", () => { let admin: HardhatEthersSigner; let user: HardhatEthersSigner; let proxy: OssifiableProxy; @@ -22,8 +22,8 @@ describe("Versioned", () => { // because we have two VersionMocks, we have to specify the full path to the contract // which for some reason loses the typing impl = await ethers.deployContract("Versioned__Harness0424"); - proxy = await ethers.deployContract("OssifiableProxy", [await impl.getAddress(), admin.address, new Uint8Array()], { from: admin }); - versioned = Versioned__Harness0424__factory.connect(await proxy.getAddress(), user); + proxy = await ethers.deployContract("OssifiableProxy", [impl, admin, new Uint8Array()], { from: admin }); + versioned = await ethers.getContractAt("Versioned__Harness0424", proxy, user); }); it("Implementation is petrified.", async () => { diff --git a/test/0.6.12/contracts/StETH__HarnessForWstETH.sol b/test/0.6.12/contracts/StETH__HarnessForWstETH.sol new file mode 100644 index 000000000..f0a215fde --- /dev/null +++ b/test/0.6.12/contracts/StETH__HarnessForWstETH.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.4.24; + +import {StETH} from "contracts/0.4.24/StETH.sol"; + +contract StETH__HarnessForWstETH is StETH { + uint256 private totalPooledEther; + + constructor(address _holder) public payable { + _resume(); + uint256 balance = address(this).balance; + assert(balance != 0); + + setTotalPooledEther(balance); + _mintShares(_holder, balance); + } + + function _getTotalPooledEther() internal view returns (uint256) { + return totalPooledEther; + } + + function setTotalPooledEther(uint256 _totalPooledEther) public { + totalPooledEther = _totalPooledEther; + } + + function submit(address _referral) public payable returns (uint256) { + uint256 sharesAmount = getSharesByPooledEth(msg.value); + _mintShares(msg.sender, sharesAmount); + _emitTransferAfterMintingShares(msg.sender, sharesAmount); + + setTotalPooledEther(_getTotalPooledEther() + msg.value); + + return sharesAmount; + } +} diff --git a/test/0.6.12/contracts/Steth__MockForWsteth.sol b/test/0.6.12/contracts/Steth__MockForWsteth.sol deleted file mode 100644 index 67827944e..000000000 --- a/test/0.6.12/contracts/Steth__MockForWsteth.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.4.24; - -import {StETH} from "contracts/0.4.24/StETH.sol"; - -contract Steth__MockForWsteth is StETH { - uint256 private totalPooledEther; - - constructor(address _holder) public payable { - _resume(); - uint256 balance = address(this).balance; - assert(balance != 0); - - setTotalPooledEther(balance); - _mintShares(_holder, balance); - } - - function _getTotalPooledEther() internal view returns (uint256) { - return totalPooledEther; - } - - function setTotalPooledEther(uint256 _totalPooledEther) public { - totalPooledEther = _totalPooledEther; - } - - function submit(address _referral) public payable returns (uint256) { - uint256 sharesAmount = getSharesByPooledEth(msg.value); - _mintShares(msg.sender, sharesAmount); - _emitTransferAfterMintingShares(msg.sender, sharesAmount); - - setTotalPooledEther(_getTotalPooledEther() + msg.value); - - return sharesAmount; - } -} diff --git a/test/0.6.12/wsteth.erc20.test.ts b/test/0.6.12/wsteth.erc20.test.ts index a500c65d5..54ce6804a 100644 --- a/test/0.6.12/wsteth.erc20.test.ts +++ b/test/0.6.12/wsteth.erc20.test.ts @@ -1,7 +1,5 @@ import { ethers } from "hardhat"; -import { Steth__MinimalMock__factory, WstETH__factory } from "typechain-types"; - import { ether } from "lib/units"; import { testERC20Compliance } from "../common/erc20.test"; @@ -9,17 +7,13 @@ import { testERC20Compliance } from "../common/erc20.test"; testERC20Compliance({ tokenName: "wstETH", deploy: async () => { - const signers = await ethers.getSigners(); - const [deployer, holder, recipient, spender] = signers; + const [deployer, holder, recipient, spender] = await ethers.getSigners(); const totalSupply = ether("10.0"); - const stethFactory = new Steth__MinimalMock__factory(deployer); - const steth = await stethFactory.deploy(holder, { value: totalSupply }); - - const wstethFactory = new WstETH__factory(deployer); - const wsteth = await wstethFactory.deploy(await steth.getAddress()); + const steth = await ethers.deployContract("StETH__Harness", [holder], { value: totalSupply, from: deployer }); + const wsteth = await ethers.deployContract("WstETH", [steth], deployer); - await steth.connect(holder).approve(await wsteth.getAddress(), totalSupply); + await steth.connect(holder).approve(wsteth, totalSupply); await wsteth.connect(holder).wrap(totalSupply); return { diff --git a/test/0.6.12/wsteth.erc2612.test.ts b/test/0.6.12/wsteth.erc2612.test.ts index 30f63bda4..057d37218 100644 --- a/test/0.6.12/wsteth.erc2612.test.ts +++ b/test/0.6.12/wsteth.erc2612.test.ts @@ -1,7 +1,5 @@ import { ethers, network } from "hardhat"; -import { Steth__MinimalMock__factory, WstETH__factory } from "typechain-types"; - import { ether } from "lib/units"; import { testERC2612Compliance } from "../common/erc2612.test"; @@ -12,13 +10,10 @@ testERC2612Compliance({ const [deployer, owner] = await ethers.getSigners(); const totalSupply = ether("10.0"); - const stethFactory = new Steth__MinimalMock__factory(deployer); - const steth = await stethFactory.deploy(owner, { value: totalSupply }); - - const wstethFactory = new WstETH__factory(deployer); - const wsteth = await wstethFactory.deploy(await steth.getAddress()); + const steth = await ethers.deployContract("StETH__Harness", [owner], { value: totalSupply, from: deployer }); + const wsteth = await ethers.deployContract("WstETH", [steth], deployer); - await steth.connect(owner).approve(await wsteth.getAddress(), totalSupply); + await steth.connect(owner).approve(wsteth, totalSupply); await wsteth.connect(owner).wrap(totalSupply); return { diff --git a/test/0.6.12/wsteth.test.ts b/test/0.6.12/wsteth.test.ts index 018349750..f15ab9fef 100644 --- a/test/0.6.12/wsteth.test.ts +++ b/test/0.6.12/wsteth.test.ts @@ -4,27 +4,35 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { Steth__MockForWsteth, Steth__MockForWsteth__factory, WstETH, WstETH__factory } from "typechain-types"; +import { StETH__HarnessForWstETH, WstETH } from "typechain-types"; import { batch, ether, ONE_ETHER } from "lib"; -describe("WstETH", () => { - let steth: Steth__MockForWsteth; +import { Snapshot } from "test/suite"; + +describe("WstETH.sol", () => { + let steth: StETH__HarnessForWstETH; let wsteth: WstETH; let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, user] = await ethers.getSigners(); - steth = await new Steth__MockForWsteth__factory(deployer).deploy(user, { value: ether("1.0") }); - wsteth = await new WstETH__factory(deployer).deploy(steth); + steth = await ethers.deployContract("StETH__HarnessForWstETH", [user], { value: ether("1.0"), from: deployer }); + wsteth = await ethers.deployContract("WstETH", [steth], deployer); steth = steth.connect(user); wsteth = wsteth.connect(user); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("wrap", () => { beforeEach(async () => { // steth must be approved before wrapping diff --git a/test/0.8.4/contracts/Address__Harness.sol b/test/0.8.4/contracts/Address__Harness.sol index 135c37c76..1c4bae8c9 100644 --- a/test/0.8.4/contracts/Address__Harness.sol +++ b/test/0.8.4/contracts/Address__Harness.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.4; @@ -7,60 +6,64 @@ pragma solidity 0.8.4; import {Address} from "contracts/0.8.4/WithdrawalsManagerProxy.sol"; contract Address__Harness { - function isContract(address account) external view returns (bool) { - return Address.isContract(account); - } + function isContract(address account) external view returns (bool) { + return Address.isContract(account); + } - function sendValue(address payable recipient, uint256 amount) external payable { - Address.sendValue(recipient, amount); - } + function sendValue(address payable recipient, uint256 amount) external payable { + Address.sendValue(recipient, amount); + } - function functionCall(address target, bytes memory data) external returns (bytes memory) { - return Address.functionCall(target, data); - } + function functionCall(address target, bytes memory data) external returns (bytes memory) { + return Address.functionCall(target, data); + } - function functionCall(address target, bytes memory data, string memory errorMessage) external returns (bytes memory) { - return Address.functionCall(target, data, errorMessage); - } + function functionCall( + address target, + bytes memory data, + string memory errorMessage + ) external returns (bytes memory) { + return Address.functionCall(target, data, errorMessage); + } - function functionCallWithValue( - address target, - bytes memory data, - uint256 value - ) external payable returns (bytes memory) { - return Address.functionCallWithValue(target, data, value); - } + function functionCallWithValue( + address target, + bytes memory data, + uint256 value + ) external payable returns (bytes memory) { + return Address.functionCallWithValue(target, data, value); + } - function functionCallWithValue( - address target, - bytes memory data, - uint256 value, - string memory errorMessage - ) external payable returns (bytes memory) { - return Address.functionCallWithValue(target, data, value, errorMessage); - } + function functionCallWithValue( + address target, + bytes memory data, + uint256 value, + string memory errorMessage + ) external payable returns (bytes memory) { + return Address.functionCallWithValue(target, data, value, errorMessage); + } - function functionStaticCall(address target, bytes memory data) external view returns (bytes memory) { - return Address.functionStaticCall(target, data); - } + function functionStaticCall(address target, bytes memory data) external view returns (bytes memory) { + return Address.functionStaticCall(target, data); + } - function functionStaticCall( - address target, - bytes memory data, - string memory errorMessage - ) external view returns (bytes memory) { - return Address.functionStaticCall(target, data, errorMessage); - } + function functionStaticCall( + address target, + bytes memory data, + string memory errorMessage + ) external view returns (bytes memory) { + return Address.functionStaticCall(target, data, errorMessage); + } - function functionDelegateCall(address target, bytes memory data) external returns (bytes memory) { - return Address.functionDelegateCall(target, data); - } + function functionDelegateCall(address target, bytes memory data) external returns (bytes memory) { + return Address.functionDelegateCall(target, data); + } - function functionDelegateCall( - address target, - bytes memory data, - string memory errorMessage - ) external returns (bytes memory) { - return Address.functionDelegateCall(target, data, errorMessage); - } + function functionDelegateCall( + address target, + bytes memory data, + string memory errorMessage + ) external returns (bytes memory) { + return Address.functionDelegateCall(target, data, errorMessage); + } } diff --git a/test/0.8.4/contracts/ERC1967Proxy__Harness.sol b/test/0.8.4/contracts/ERC1967Proxy__Harness.sol index 49474074d..e93f2f4b4 100644 --- a/test/0.8.4/contracts/ERC1967Proxy__Harness.sol +++ b/test/0.8.4/contracts/ERC1967Proxy__Harness.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.4; @@ -7,9 +6,9 @@ pragma solidity 0.8.4; import {ERC1967Proxy} from "contracts/0.8.4/WithdrawalsManagerProxy.sol"; contract ERC1967Proxy__Harness is ERC1967Proxy { - constructor(address _logic, bytes memory _data) payable ERC1967Proxy(_logic, _data) {} + constructor(address _logic, bytes memory _data) payable ERC1967Proxy(_logic, _data) {} - function implementation() external view returns (address) { - return _implementation(); - } + function implementation() external view returns (address) { + return _implementation(); + } } diff --git a/test/0.8.4/contracts/Impl__MockForERC1967Proxy.sol b/test/0.8.4/contracts/Impl__MockForERC1967Proxy.sol deleted file mode 100644 index 121f5b720..000000000 --- a/test/0.8.4/contracts/Impl__MockForERC1967Proxy.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.8.4; - -contract Impl__MockForERC1967Proxy { - function writeToStorage(bytes32 slot, bytes32 value) external { - assembly { - sstore(slot, value) - } - } - - event Received(); - receive() external payable { - emit Received(); - } -} diff --git a/test/0.8.4/contracts/Proxy__Harness.sol b/test/0.8.4/contracts/Proxy__Harness.sol index 588238b55..e3c7e8eb3 100644 --- a/test/0.8.4/contracts/Proxy__Harness.sol +++ b/test/0.8.4/contracts/Proxy__Harness.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.4; @@ -7,17 +6,17 @@ pragma solidity 0.8.4; import {Proxy} from "contracts/0.8.4/WithdrawalsManagerProxy.sol"; contract Proxy__Harness is Proxy { - address private impl; + address private impl; - function setImplementation(address newImpl) external { - impl = newImpl; - } + function setImplementation(address newImpl) external { + impl = newImpl; + } - function implementation() external view returns (address) { - return _implementation(); - } + function implementation() external view returns (address) { + return _implementation(); + } - function _implementation() internal view override returns (address) { - return impl; - } + function _implementation() internal view override returns (address) { + return impl; + } } diff --git a/test/0.8.4/contracts/Recipient__MockForAddress.sol b/test/0.8.4/contracts/Recipient__MockForAddress.sol index f10ee029d..c2f3b3450 100644 --- a/test/0.8.4/contracts/Recipient__MockForAddress.sol +++ b/test/0.8.4/contracts/Recipient__MockForAddress.sol @@ -1,41 +1,40 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.4; contract Recipient__MockForAddress { - bool private receiveShouldRevert; + bool private receiveShouldRevert; - function mock__receive(bool shouldRevert) external { - receiveShouldRevert = shouldRevert; - } + function mock__receive(bool shouldRevert) external { + receiveShouldRevert = shouldRevert; + } - receive() external payable { - require(!receiveShouldRevert); - } + receive() external payable { + require(!receiveShouldRevert); + } - uint256 public number; + uint256 public number; - function increment() external payable { - number++; - } + function increment() external payable { + number++; + } - function revertsWithMessage() external view { - revert("Reverted"); - } + function revertsWithMessage() external view { + revert("Reverted"); + } - function staticFunction() external pure returns (string memory) { - return "0x1234"; - } + function staticFunction() external pure returns (string memory) { + return "0x1234"; + } - function writeToStorage(bytes32 slot, bytes32 value) external { - assembly { - sstore(slot, value) + function writeToStorage(bytes32 slot, bytes32 value) external { + assembly { + sstore(slot, value) + } } - } - function revertingFunction() external { - revert(); - } + function revertingFunction() external { + revert(); + } } diff --git a/test/0.8.4/contracts/WithdrawalsManagerProxy__Mock.sol b/test/0.8.4/contracts/WithdrawalsManagerProxy__Mock.sol new file mode 100644 index 000000000..0ce42bf18 --- /dev/null +++ b/test/0.8.4/contracts/WithdrawalsManagerProxy__Mock.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.4; + +contract WithdrawalsManagerProxy__Mock { + function writeToStorage(bytes32 slot, bytes32 value) external { + assembly { + sstore(slot, value) + } + } + + event Received(); + + receive() external payable { + emit Received(); + } +} diff --git a/test/0.8.4/contracts/WithdrawalsVault__MockForWithdrawalManagerProxy.sol b/test/0.8.4/contracts/WithdrawalsVault__MockForWithdrawalManagerProxy.sol index 493f0451a..cad8b03df 100644 --- a/test/0.8.4/contracts/WithdrawalsVault__MockForWithdrawalManagerProxy.sol +++ b/test/0.8.4/contracts/WithdrawalsVault__MockForWithdrawalManagerProxy.sol @@ -1,16 +1,15 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.4; contract WithdrawalsVault__MockForWithdrawalManagerProxy { - function mock__changeNumber(uint256 someNumber) external { - bytes32 slot = keccak256("someNumberSlot"); + function mock__changeNumber(uint256 someNumber) external { + bytes32 slot = keccak256("someNumberSlot"); - // solhint-disable-next-line no-inline-assembly - assembly { - sstore(slot, someNumber) + // solhint-disable-next-line no-inline-assembly + assembly { + sstore(slot, someNumber) + } } - } } diff --git a/test/0.8.4/address.test.ts b/test/0.8.4/withdrawalsManagerProxy.address.test.ts similarity index 94% rename from test/0.8.4/address.test.ts rename to test/0.8.4/withdrawalsManagerProxy.address.test.ts index 3889630e5..edf9d4a47 100644 --- a/test/0.8.4/address.test.ts +++ b/test/0.8.4/withdrawalsManagerProxy.address.test.ts @@ -6,32 +6,34 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { getStorageAt, setCode } from "@nomicfoundation/hardhat-network-helpers"; -import { - Address__Harness, - Address__Harness__factory, - Recipient__MockForAddress, - Recipient__MockForAddress__factory, -} from "typechain-types"; +import { Address__Harness, Recipient__MockForAddress } from "typechain-types"; import { batch, certainAddress } from "lib"; +import { Snapshot } from "test/suite"; + // this contract code reverts any call to it const INVALID_BYTECODE = "0xFE"; -// TODO: refactor similar tests for similar functions -describe("Address", () => { +describe("WithdrawalsManagerProxy.sol:address", () => { let deployer: HardhatEthersSigner; let user: HardhatEthersSigner; let address: Address__Harness; - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, user] = await ethers.getSigners(); - address = await new Address__Harness__factory(deployer).deploy(); + address = await ethers.deployContract("Address__Harness", deployer); address = address.connect(user); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("isContract", () => { it("Returns true if the account is a contract", async () => { const someContract = certainAddress("test:address-lib:random-contract"); @@ -84,8 +86,8 @@ describe("Address", () => { context("functionCall", () => { let recipient: Recipient__MockForAddress; - beforeEach(async () => { - recipient = await new Recipient__MockForAddress__factory(deployer).deploy(); + before(async () => { + recipient = await ethers.deployContract("Recipient__MockForAddress", deployer); }); context("functionCall(address,bytes)", () => { @@ -257,8 +259,8 @@ describe("Address", () => { context("functionCallWithValue", () => { let recipient: Recipient__MockForAddress; - beforeEach(async () => { - recipient = await new Recipient__MockForAddress__factory(deployer).deploy(); + before(async () => { + recipient = await ethers.deployContract("Recipient__MockForAddress", deployer); }); it("Reverts if there's not enough ether", async () => { diff --git a/test/0.8.4/erc1967proxy.test.ts b/test/0.8.4/withdrawalsManagerProxy.erc1967proxy.test.ts similarity index 50% rename from test/0.8.4/erc1967proxy.test.ts rename to test/0.8.4/withdrawalsManagerProxy.erc1967proxy.test.ts index f3cbf0bbc..c0ad41fa7 100644 --- a/test/0.8.4/erc1967proxy.test.ts +++ b/test/0.8.4/withdrawalsManagerProxy.erc1967proxy.test.ts @@ -6,35 +6,38 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { getStorageAt } from "@nomicfoundation/hardhat-network-helpers"; -import { - ERC1967Proxy__Harness, - ERC1967Proxy__Harness__factory, - Impl__MockForERC1967Proxy, - Impl__MockForERC1967Proxy__factory, -} from "typechain-types"; +import { ERC1967Proxy__Harness, WithdrawalsManagerProxy__Mock } from "typechain-types"; import { certainAddress } from "lib"; -describe("ERC1967Proxy", () => { +import { Snapshot } from "test/suite"; + +describe("WithdrawalsManagerProxy.sol:erc1967proxy", () => { let deployer: HardhatEthersSigner; let sender: HardhatEthersSigner; let proxy: ERC1967Proxy__Harness; - let impl: Impl__MockForERC1967Proxy; + let impl: WithdrawalsManagerProxy__Mock; + + let originalState: string; - beforeEach(async () => { + before(async () => { [deployer, sender] = await ethers.getSigners(); - impl = await new Impl__MockForERC1967Proxy__factory(deployer).deploy(); - proxy = await new ERC1967Proxy__Harness__factory(deployer).deploy(impl, "0x"); + impl = await ethers.deployContract("WithdrawalsManagerProxy__Mock", deployer); + proxy = await ethers.deployContract("ERC1967Proxy__Harness", [impl, "0x"], deployer); proxy = proxy.connect(sender); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("constructor", () => { it("Reverts if the implementation is not a contract", async () => { await expect( - new ERC1967Proxy__Harness__factory(deployer).deploy(certainAddress("test:erc1967:non-contract"), "0x"), + ethers.deployContract("ERC1967Proxy__Harness", [certainAddress("test:erc1967:non-contract"), "0x"], deployer), ).to.be.revertedWith("ERC1967Proxy: new implementation is not a contract"); }); @@ -42,18 +45,19 @@ describe("ERC1967Proxy", () => { const slot = hexlify(randomBytes(32)); const value = hexlify(randomBytes(32)); - proxy = await new ERC1967Proxy__Harness__factory(deployer).deploy( - impl, - impl.interface.encodeFunctionData("writeToStorage", [slot, value]), + proxy = await ethers.deployContract( + "ERC1967Proxy__Harness", + [impl, impl.interface.encodeFunctionData("writeToStorage", [slot, value])], + deployer, ); expect(await getStorageAt(await proxy.getAddress(), slot)).to.equal(value); }); it("Set the implementation", async () => { - proxy = await new ERC1967Proxy__Harness__factory(deployer).deploy(impl, "0x"); + proxy = await ethers.deployContract("ERC1967Proxy__Harness", [impl, "0x"], deployer); - expect(await proxy.implementation()).to.equal(await impl.getAddress()); + expect(await proxy.implementation()).to.equal(impl); }); }); }); diff --git a/test/0.8.4/proxy.test.ts b/test/0.8.4/withdrawalsManagerProxy.proxy.test.ts similarity index 78% rename from test/0.8.4/proxy.test.ts rename to test/0.8.4/withdrawalsManagerProxy.proxy.test.ts index b42bc3463..bd8f1c67c 100644 --- a/test/0.8.4/proxy.test.ts +++ b/test/0.8.4/withdrawalsManagerProxy.proxy.test.ts @@ -6,15 +6,12 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { getStorageAt } from "@nomicfoundation/hardhat-network-helpers"; -import { - Impl__MockForERC1967Proxy, - Impl__MockForERC1967Proxy__factory, - Proxy__Harness, - Proxy__Harness__factory, -} from "typechain-types"; +import { Proxy__Harness, WithdrawalsManagerProxy__Mock } from "typechain-types"; import { ether } from "lib"; +import { Snapshot } from "test/suite"; + // This is a test suite for a low-level OZ contract located in // contracts/0.8.4/WithdrawalsManagerProxy.sol:Proxy // Normally, we do not cover OZ contracts. @@ -22,22 +19,28 @@ import { ether } from "lib"; // as opposed to fetching from the OZ repository. // This means that it is accounted for in test coverage and // to get 100% coverage, we have to have a test suite for this contract -describe("WithdrawalsManagerProxy:Proxy", () => { +describe("WithdrawalsManagerProxy.sol:proxy", () => { let deployer: HardhatEthersSigner; let sender: HardhatEthersSigner; let proxy: Proxy__Harness; - let impl: Impl__MockForERC1967Proxy; + let impl: WithdrawalsManagerProxy__Mock; + + let originalState: string; - beforeEach(async () => { + before(async () => { [deployer, sender] = await ethers.getSigners(); - impl = await new Impl__MockForERC1967Proxy__factory(deployer).deploy(); - proxy = await new Proxy__Harness__factory(deployer).deploy(); + impl = await ethers.deployContract("WithdrawalsManagerProxy__Mock", deployer); + proxy = await ethers.deployContract("Proxy__Harness", deployer); proxy = proxy.connect(sender); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("implementation", () => { it("Returns implementation", async () => { expect(await proxy.implementation()).to.equal(ZeroAddress); diff --git a/test/0.8.4/withdrawals-manager-stub.test.ts b/test/0.8.4/withdrawalsManagerProxy.stub.test.ts similarity index 71% rename from test/0.8.4/withdrawals-manager-stub.test.ts rename to test/0.8.4/withdrawalsManagerProxy.stub.test.ts index 5790f83f0..13f79c768 100644 --- a/test/0.8.4/withdrawals-manager-stub.test.ts +++ b/test/0.8.4/withdrawalsManagerProxy.stub.test.ts @@ -3,20 +3,20 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { WithdrawalsManagerStub, WithdrawalsManagerStub__factory } from "typechain-types"; +import { WithdrawalsManagerStub } from "typechain-types"; import { ether } from "lib"; -describe("WithdrawalsManagerStub", () => { +describe("WithdrawalsManagerProxy.sol:stub", () => { let deployer: HardhatEthersSigner; let sender: HardhatEthersSigner; let stub: WithdrawalsManagerStub; - beforeEach(async () => { + before(async () => { [deployer, sender] = await ethers.getSigners(); - stub = await new WithdrawalsManagerStub__factory(deployer).deploy(); + stub = await ethers.deployContract("WithdrawalsManagerStub", deployer); }); context("receive", () => { diff --git a/test/0.8.4/withdrawals-manager-proxy.test.ts b/test/0.8.4/withdrawalsManagerProxy.test.ts similarity index 86% rename from test/0.8.4/withdrawals-manager-proxy.test.ts rename to test/0.8.4/withdrawalsManagerProxy.test.ts index 535c4e6fc..b7d75acf9 100644 --- a/test/0.8.4/withdrawals-manager-proxy.test.ts +++ b/test/0.8.4/withdrawalsManagerProxy.test.ts @@ -7,16 +7,15 @@ import { getStorageAt } from "@nomicfoundation/hardhat-network-helpers"; import { WithdrawalsManagerProxy, - WithdrawalsManagerProxy__factory, WithdrawalsManagerStub, - WithdrawalsManagerStub__factory, WithdrawalsVault__MockForWithdrawalManagerProxy, - WithdrawalsVault__MockForWithdrawalManagerProxy__factory, } from "typechain-types"; import { certainAddress, streccak } from "lib"; -describe("WithdrawalsManagerProxy", () => { +import { Snapshot } from "test/suite"; + +describe("WithdrawalsManagerProxy.sol", () => { let deployer: HardhatEthersSigner; let voting: HardhatEthersSigner; let stranger: HardhatEthersSigner; @@ -25,17 +24,23 @@ describe("WithdrawalsManagerProxy", () => { let proxy: WithdrawalsManagerProxy; let newImpl: WithdrawalsVault__MockForWithdrawalManagerProxy; - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, voting, stranger] = await ethers.getSigners(); - stub = await new WithdrawalsManagerStub__factory(deployer).deploy(); - proxy = await new WithdrawalsManagerProxy__factory(deployer).deploy(voting, stub); + stub = await ethers.deployContract("WithdrawalsManagerStub", deployer); + proxy = await ethers.deployContract("WithdrawalsManagerProxy", [voting, stub], deployer); proxy = proxy.connect(voting); - newImpl = await new WithdrawalsVault__MockForWithdrawalManagerProxy__factory(deployer).deploy(); + newImpl = await ethers.deployContract("WithdrawalsVault__MockForWithdrawalManagerProxy", deployer); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("implementation", () => { it("Returns the addres of the current implementation", async () => { expect(await proxy.implementation()).to.equal(stub); diff --git a/test/0.8.9/BeaconChainDepositor.t.sol b/test/0.8.9/BeaconChainDepositor.t.sol index 5491b6484..93def7cad 100644 --- a/test/0.8.9/BeaconChainDepositor.t.sol +++ b/test/0.8.9/BeaconChainDepositor.t.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -19,204 +18,204 @@ import {BeaconChainDepositor as BCDepositor} from "contracts/0.8.9/BeaconChainDe /// @notice BCDepositor invariants contract for the forge test utils /// @dev Uses two harness contracts to put the BCDepositor in the middle of them contract BCDepositorInvariants is Test { - DepositContractHarness public depositContract; - BCDepositorHarness public bcDepositor; - BCDepositorHandler public handler; - - function setUp() public { - depositContract = new DepositContractHarness(); - bcDepositor = new BCDepositorHarness(address(depositContract)); - handler = new BCDepositorHandler(bcDepositor, depositContract); - - bytes4[] memory selectors = new bytes4[](1); - selectors[0] = BCDepositorHandler.makeBeaconChainDeposits32ETH.selector; - - targetSelector(FuzzSelector({addr: address(handler), selectors: selectors})); - - targetContract(address(handler)); - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-invariant-configs - * forge-config: default.invariant.runs = 32 - * forge-config: default.invariant.depth = 16 - * forge-config: default.invariant.fail-on-revert = true - */ - function invariant_32ETHPaidPerKey() public view { - uint256 depositContractBalance = address(depositContract).balance; - assertEq(depositContractBalance, handler.ghost_totalETHDeposited(), "pays 32 ETH per key"); - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-invariant-configs - * forge-config: default.invariant.runs = 32 - * forge-config: default.invariant.depth = 16 - * forge-config: default.invariant.fail-on-revert = true - */ - function invariant_DepositsCountIsCoherent() public view { - assertEq( - depositContract.get_deposit_count(), - depositContract.to_little_endian_64(uint64(handler.ghost_totalDeposits())), - "deposit count grows coherently" - ); - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-invariant-configs - * forge-config: default.invariant.runs = 32 - * forge-config: default.invariant.depth = 16 - * forge-config: default.invariant.fail-on-revert = true - */ - function invariant_DepositDataIsNotCorrupted() public view { - for (uint256 depositId = 0; depositId < handler.ghost_totalDeposits(); ++depositId) { - ( - bytes memory pubkey, - bytes memory withdrawal_credentials, - bytes memory amount, - bytes memory signature, - bytes memory index - ) = depositContract.depositEvents(depositId); - - ( - bytes memory ghost_pubkey, - bytes memory ghost_withdrawal_credentials, - bytes memory ghost_amount, - bytes memory ghost_signature, - bytes memory ghost_index - ) = handler.ghost_DepositEvents(depositId); - - assertEq(amount, ghost_amount, "deposit amount is the same"); - assertEq(index, ghost_index, "deposit index is the same"); - assertEq(pubkey, ghost_pubkey, "deposit pubkey is the same"); - assertEq(signature, ghost_signature, "deposit signature is the same"); - assertEq(withdrawal_credentials, ghost_withdrawal_credentials, "deposit wc are the same"); + DepositContractHarness public depositContract; + BCDepositorHarness public bcDepositor; + BCDepositorHandler public handler; + + function setUp() public { + depositContract = new DepositContractHarness(); + bcDepositor = new BCDepositorHarness(address(depositContract)); + handler = new BCDepositorHandler(bcDepositor, depositContract); + + bytes4[] memory selectors = new bytes4[](1); + selectors[0] = BCDepositorHandler.makeBeaconChainDeposits32ETH.selector; + + targetSelector(FuzzSelector({addr: address(handler), selectors: selectors})); + + targetContract(address(handler)); + } + + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-invariant-configs + * forge-config: default.invariant.runs = 32 + * forge-config: default.invariant.depth = 16 + * forge-config: default.invariant.fail-on-revert = true + */ + function invariant_32ETHPaidPerKey() public view { + uint256 depositContractBalance = address(depositContract).balance; + assertEq(depositContractBalance, handler.ghost_totalETHDeposited(), "pays 32 ETH per key"); + } + + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-invariant-configs + * forge-config: default.invariant.runs = 32 + * forge-config: default.invariant.depth = 16 + * forge-config: default.invariant.fail-on-revert = true + */ + function invariant_DepositsCountIsCoherent() public view { + assertEq( + depositContract.get_deposit_count(), + depositContract.to_little_endian_64(uint64(handler.ghost_totalDeposits())), + "deposit count grows coherently" + ); + } + + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-invariant-configs + * forge-config: default.invariant.runs = 32 + * forge-config: default.invariant.depth = 16 + * forge-config: default.invariant.fail-on-revert = true + */ + function invariant_DepositDataIsNotCorrupted() public view { + for (uint256 depositId = 0; depositId < handler.ghost_totalDeposits(); ++depositId) { + ( + bytes memory pubkey, + bytes memory withdrawal_credentials, + bytes memory amount, + bytes memory signature, + bytes memory index + ) = depositContract.depositEvents(depositId); + + ( + bytes memory ghost_pubkey, + bytes memory ghost_withdrawal_credentials, + bytes memory ghost_amount, + bytes memory ghost_signature, + bytes memory ghost_index + ) = handler.ghost_DepositEvents(depositId); + + assertEq(amount, ghost_amount, "deposit amount is the same"); + assertEq(index, ghost_index, "deposit index is the same"); + assertEq(pubkey, ghost_pubkey, "deposit pubkey is the same"); + assertEq(signature, ghost_signature, "deposit signature is the same"); + assertEq(withdrawal_credentials, ghost_withdrawal_credentials, "deposit wc are the same"); + } } - } } contract BCDepositorHandler is CommonBase, StdAssertions, StdUtils { - uint256 public constant WITHDRAWAL_CREDENTIALS_START = 2 ** 248; // 0x01....00 - uint256 public constant WITHDRAWAL_CREDENTIALS_END = 2 ** 249 - 1; // 0x01FF...FF - - uint8 public constant MAX_DEPOSITS = 150; // max DSM deposits per block - - BCDepositorHarness public bcDepositor; - DepositContractHarness public depositContract; - - uint256 public ghost_totalDeposits; - uint256 public ghost_totalETHDeposited; - DepositContractHarness.DepositEventData[] public ghost_DepositEvents; - - constructor(BCDepositorHarness _bcDepositor, DepositContractHarness _depositContract) { - bcDepositor = _bcDepositor; - depositContract = _depositContract; - } - - /// @dev Ghosted version of the _makeBeaconChainDeposits32ETH for invariant checks - /// @param _keysCount amount of keys to deposit - /// @param _withdrawalCredentialsAsUint256 Commitment to a public key for withdrawals - /// @param _depositDataSeed Randomized seed for deposit data generation (auxiliary param) - function makeBeaconChainDeposits32ETH( - uint256 _keysCount, - uint256 _withdrawalCredentialsAsUint256, - uint256 _depositDataSeed - ) external { - // use MAX_DEPOSITS as defined for DSM per a single block - _keysCount = bound(_keysCount, 1, MAX_DEPOSITS); - // use withdrawal credentials with the `0x01` prefix - _withdrawalCredentialsAsUint256 = bound( - _withdrawalCredentialsAsUint256, - WITHDRAWAL_CREDENTIALS_START, - WITHDRAWAL_CREDENTIALS_END - ); - // leave some space to prevent overflow for the seed increments - _depositDataSeed = bound(_depositDataSeed, 0, type(uint248).max); - - bytes memory withdrawalCredentials = abi.encodePacked(_withdrawalCredentialsAsUint256); - - bytes memory encoded_keys; - bytes memory encoded_signatures; - - for (uint256 key = 0; key < _keysCount; key++) { - bytes memory pubkey = abi.encodePacked( - bytes16(sha256(abi.encodePacked(_depositDataSeed++))), - bytes16(sha256(abi.encodePacked(_depositDataSeed++))), - bytes16(sha256(abi.encodePacked(_depositDataSeed++))) - ); - encoded_keys = bytes.concat(encoded_keys, pubkey); - - bytes memory signature = abi.encodePacked( - sha256(abi.encodePacked(_depositDataSeed++)), - sha256(abi.encodePacked(_depositDataSeed++)), - sha256(abi.encodePacked(_depositDataSeed++)) - ); - encoded_signatures = bytes.concat(encoded_signatures, signature); - - ghost_DepositEvents.push( - DepositContractHarness.DepositEventData( - pubkey, - withdrawalCredentials, - depositContract.to_little_endian_64(uint64(32 ether / 1 gwei)), - signature, - depositContract.to_little_endian_64(uint64(ghost_totalDeposits)) - ) - ); - - ghost_totalDeposits += 1; - ghost_totalETHDeposited += 32 ether; + uint256 public constant WITHDRAWAL_CREDENTIALS_START = 2 ** 248; // 0x01....00 + uint256 public constant WITHDRAWAL_CREDENTIALS_END = 2 ** 249 - 1; // 0x01FF...FF + + uint8 public constant MAX_DEPOSITS = 150; // max DSM deposits per block + + BCDepositorHarness public bcDepositor; + DepositContractHarness public depositContract; + + uint256 public ghost_totalDeposits; + uint256 public ghost_totalETHDeposited; + DepositContractHarness.DepositEventData[] public ghost_DepositEvents; + + constructor(BCDepositorHarness _bcDepositor, DepositContractHarness _depositContract) { + bcDepositor = _bcDepositor; + depositContract = _depositContract; } - // top-up depositor's balance to perform deposits - vm.deal(address(bcDepositor), 32 ether * _keysCount); - bcDepositor.makeBeaconChainDeposits32ETH(_keysCount, withdrawalCredentials, encoded_keys, encoded_signatures); - } + /// @dev Ghosted version of the _makeBeaconChainDeposits32ETH for invariant checks + /// @param _keysCount amount of keys to deposit + /// @param _withdrawalCredentialsAsUint256 Commitment to a public key for withdrawals + /// @param _depositDataSeed Randomized seed for deposit data generation (auxiliary param) + function makeBeaconChainDeposits32ETH( + uint256 _keysCount, + uint256 _withdrawalCredentialsAsUint256, + uint256 _depositDataSeed + ) external { + // use MAX_DEPOSITS as defined for DSM per a single block + _keysCount = bound(_keysCount, 1, MAX_DEPOSITS); + // use withdrawal credentials with the `0x01` prefix + _withdrawalCredentialsAsUint256 = bound( + _withdrawalCredentialsAsUint256, + WITHDRAWAL_CREDENTIALS_START, + WITHDRAWAL_CREDENTIALS_END + ); + // leave some space to prevent overflow for the seed increments + _depositDataSeed = bound(_depositDataSeed, 0, type(uint248).max); + + bytes memory withdrawalCredentials = abi.encodePacked(_withdrawalCredentialsAsUint256); + + bytes memory encoded_keys; + bytes memory encoded_signatures; + + for (uint256 key = 0; key < _keysCount; key++) { + bytes memory pubkey = abi.encodePacked( + bytes16(sha256(abi.encodePacked(_depositDataSeed++))), + bytes16(sha256(abi.encodePacked(_depositDataSeed++))), + bytes16(sha256(abi.encodePacked(_depositDataSeed++))) + ); + encoded_keys = bytes.concat(encoded_keys, pubkey); + + bytes memory signature = abi.encodePacked( + sha256(abi.encodePacked(_depositDataSeed++)), + sha256(abi.encodePacked(_depositDataSeed++)), + sha256(abi.encodePacked(_depositDataSeed++)) + ); + encoded_signatures = bytes.concat(encoded_signatures, signature); + + ghost_DepositEvents.push( + DepositContractHarness.DepositEventData( + pubkey, + withdrawalCredentials, + depositContract.to_little_endian_64(uint64(32 ether / 1 gwei)), + signature, + depositContract.to_little_endian_64(uint64(ghost_totalDeposits)) + ) + ); + + ghost_totalDeposits += 1; + ghost_totalETHDeposited += 32 ether; + } + + // top-up depositor's balance to perform deposits + vm.deal(address(bcDepositor), 32 ether * _keysCount); + bcDepositor.makeBeaconChainDeposits32ETH(_keysCount, withdrawalCredentials, encoded_keys, encoded_signatures); + } } contract BCDepositorHarness is BCDepositor { - constructor(address _depositContract) BCDepositor(_depositContract) {} - - /// @dev Exposed version of the _makeBeaconChainDeposits32ETH - /// @param _keysCount amount of keys to deposit - /// @param _withdrawalCredentials Commitment to a public key for withdrawals - /// @param _publicKeysBatch A BLS12-381 public keys batch - /// @param _signaturesBatch A BLS12-381 signatures batch - function makeBeaconChainDeposits32ETH( - uint256 _keysCount, - bytes memory _withdrawalCredentials, - bytes memory _publicKeysBatch, - bytes memory _signaturesBatch - ) external { - _makeBeaconChainDeposits32ETH(_keysCount, _withdrawalCredentials, _publicKeysBatch, _signaturesBatch); - } + constructor(address _depositContract) BCDepositor(_depositContract) {} + + /// @dev Exposed version of the _makeBeaconChainDeposits32ETH + /// @param _keysCount amount of keys to deposit + /// @param _withdrawalCredentials Commitment to a public key for withdrawals + /// @param _publicKeysBatch A BLS12-381 public keys batch + /// @param _signaturesBatch A BLS12-381 signatures batch + function makeBeaconChainDeposits32ETH( + uint256 _keysCount, + bytes memory _withdrawalCredentials, + bytes memory _publicKeysBatch, + bytes memory _signaturesBatch + ) external { + _makeBeaconChainDeposits32ETH(_keysCount, _withdrawalCredentials, _publicKeysBatch, _signaturesBatch); + } } // This interface is designed to be compatible with the Vyper version. /// @notice This is the Ethereum 2.0 deposit contract interface. /// For more information see the Phase 0 specification under https://github.com/ethereum/consensus-specs/tree/dev/specs/phase0 interface IDepositContract { - /// @notice A processed deposit event. - event DepositEvent(bytes pubkey, bytes withdrawal_credentials, bytes amount, bytes signature, bytes index); - - /// @notice Submit a Phase 0 DepositData object. - /// @param pubkey A BLS12-381 public key. - /// @param withdrawal_credentials Commitment to a public key for withdrawals. - /// @param signature A BLS12-381 signature. - /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object. - /// Used as a protection against malformed input. - function deposit( - bytes calldata pubkey, - bytes calldata withdrawal_credentials, - bytes calldata signature, - bytes32 deposit_data_root - ) external payable; - - /// @notice Query the current deposit root hash. - /// @return The deposit root hash. - function get_deposit_root() external view returns (bytes32); - - /// @notice Query the current deposit count. - /// @return The deposit count encoded as a little endian 64-bit number. - function get_deposit_count() external view returns (bytes memory); + /// @notice A processed deposit event. + event DepositEvent(bytes pubkey, bytes withdrawal_credentials, bytes amount, bytes signature, bytes index); + + /// @notice Submit a Phase 0 DepositData object. + /// @param pubkey A BLS12-381 public key. + /// @param withdrawal_credentials Commitment to a public key for withdrawals. + /// @param signature A BLS12-381 signature. + /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object. + /// Used as a protection against malformed input. + function deposit( + bytes calldata pubkey, + bytes calldata withdrawal_credentials, + bytes calldata signature, + bytes32 deposit_data_root + ) external payable; + + /// @notice Query the current deposit root hash. + /// @return The deposit root hash. + function get_deposit_root() external view returns (bytes32); + + /// @notice Query the current deposit count. + /// @return The deposit count encoded as a little endian 64-bit number. + function get_deposit_count() external view returns (bytes memory); } // This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity. @@ -224,126 +223,141 @@ interface IDepositContract { /// @notice This is the Ethereum 2.0 deposit contract interface. /// For more information see the Phase 0 specification under https://github.com/ethereum/consensus-specs/tree/dev/specs/phase0 contract DepositContractHarness is IDepositContract, IERC165 { - uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32; - // NOTE: this also ensures `deposit_count` will fit into 64-bits - uint constant MAX_DEPOSIT_COUNT = 2 ** DEPOSIT_CONTRACT_TREE_DEPTH - 1; - - bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch; - uint256 deposit_count; - - bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes; - - struct DepositEventData { - bytes pubkey; - bytes withdrawal_credentials; - bytes amount; - bytes signature; - bytes index; - } - - // Dev: harness part - DepositEventData[] public depositEvents; - - constructor() { - // Compute hashes in empty sparse Merkle tree - for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++) - zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height])); - } - - function get_deposit_root() external view override returns (bytes32) { - bytes32 node; - uint size = deposit_count; - for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) { - if ((size & 1) == 1) node = sha256(abi.encodePacked(branch[height], node)); - else node = sha256(abi.encodePacked(node, zero_hashes[height])); - size /= 2; + uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32; + // NOTE: this also ensures `deposit_count` will fit into 64-bits + uint constant MAX_DEPOSIT_COUNT = 2 ** DEPOSIT_CONTRACT_TREE_DEPTH - 1; + + bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch; + uint256 deposit_count; + + bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes; + + struct DepositEventData { + bytes pubkey; + bytes withdrawal_credentials; + bytes amount; + bytes signature; + bytes index; } - return sha256(abi.encodePacked(node, to_little_endian_64(uint64(deposit_count)), bytes24(0))); - } - - function get_deposit_count() external view override returns (bytes memory) { - return to_little_endian_64(uint64(deposit_count)); - } - - function deposit( - bytes calldata pubkey, - bytes calldata withdrawal_credentials, - bytes calldata signature, - bytes32 deposit_data_root - ) external payable override { - // Extended ABI length checks since dynamic types are used. - require(pubkey.length == 48, "DepositContract: invalid pubkey length"); - require(withdrawal_credentials.length == 32, "DepositContract: invalid withdrawal_credentials length"); - require(signature.length == 96, "DepositContract: invalid signature length"); - - // Check deposit amount - require(msg.value >= 1 ether, "DepositContract: deposit value too low"); - require(msg.value % 1 gwei == 0, "DepositContract: deposit value not multiple of gwei"); - uint deposit_amount = msg.value / 1 gwei; - require(deposit_amount <= type(uint64).max, "DepositContract: deposit value too high"); - - // Emit `DepositEvent` log - bytes memory amount = to_little_endian_64(uint64(deposit_amount)); - emit DepositEvent(pubkey, withdrawal_credentials, amount, signature, to_little_endian_64(uint64(deposit_count))); // Dev: harness part - depositEvents.push( - DepositEventData(pubkey, withdrawal_credentials, amount, signature, to_little_endian_64(uint64(deposit_count))) - ); - - // Compute deposit data root (`DepositData` hash tree root) - bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0))); - bytes32 signature_root = sha256( - abi.encodePacked(sha256(abi.encodePacked(signature[:64])), sha256(abi.encodePacked(signature[64:], bytes32(0)))) - ); - bytes32 node = sha256( - abi.encodePacked( - sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)), - sha256(abi.encodePacked(amount, bytes24(0), signature_root)) - ) - ); - - // Verify computed and expected deposit data roots match - require( - node == deposit_data_root, - "DepositContract: reconstructed DepositData does not match supplied deposit_data_root" - ); - - // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`) - require(deposit_count < MAX_DEPOSIT_COUNT, "DepositContract: merkle tree full"); - - // Add deposit data root to Merkle tree (update a single `branch` node) - deposit_count += 1; - uint size = deposit_count; - for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) { - if ((size & 1) == 1) { - branch[height] = node; - return; - } - node = sha256(abi.encodePacked(branch[height], node)); - size /= 2; + DepositEventData[] public depositEvents; + + constructor() { + // Compute hashes in empty sparse Merkle tree + for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++) + zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height])); + } + + function get_deposit_root() external view override returns (bytes32) { + bytes32 node; + uint size = deposit_count; + for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) { + if ((size & 1) == 1) node = sha256(abi.encodePacked(branch[height], node)); + else node = sha256(abi.encodePacked(node, zero_hashes[height])); + size /= 2; + } + return sha256(abi.encodePacked(node, to_little_endian_64(uint64(deposit_count)), bytes24(0))); + } + + function get_deposit_count() external view override returns (bytes memory) { + return to_little_endian_64(uint64(deposit_count)); + } + + function deposit( + bytes calldata pubkey, + bytes calldata withdrawal_credentials, + bytes calldata signature, + bytes32 deposit_data_root + ) external payable override { + // Extended ABI length checks since dynamic types are used. + require(pubkey.length == 48, "DepositContract: invalid pubkey length"); + require(withdrawal_credentials.length == 32, "DepositContract: invalid withdrawal_credentials length"); + require(signature.length == 96, "DepositContract: invalid signature length"); + + // Check deposit amount + require(msg.value >= 1 ether, "DepositContract: deposit value too low"); + require(msg.value % 1 gwei == 0, "DepositContract: deposit value not multiple of gwei"); + uint deposit_amount = msg.value / 1 gwei; + require(deposit_amount <= type(uint64).max, "DepositContract: deposit value too high"); + + // Emit `DepositEvent` log + bytes memory amount = to_little_endian_64(uint64(deposit_amount)); + emit DepositEvent( + pubkey, + withdrawal_credentials, + amount, + signature, + to_little_endian_64(uint64(deposit_count)) + ); + + // Dev: harness part + depositEvents.push( + DepositEventData( + pubkey, + withdrawal_credentials, + amount, + signature, + to_little_endian_64(uint64(deposit_count)) + ) + ); + + // Compute deposit data root (`DepositData` hash tree root) + bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0))); + bytes32 signature_root = sha256( + abi.encodePacked( + sha256(abi.encodePacked(signature[:64])), + sha256(abi.encodePacked(signature[64:], bytes32(0))) + ) + ); + bytes32 node = sha256( + abi.encodePacked( + sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)), + sha256(abi.encodePacked(amount, bytes24(0), signature_root)) + ) + ); + + // Verify computed and expected deposit data roots match + require( + node == deposit_data_root, + "DepositContract: reconstructed DepositData does not match supplied deposit_data_root" + ); + + // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`) + require(deposit_count < MAX_DEPOSIT_COUNT, "DepositContract: merkle tree full"); + + // Add deposit data root to Merkle tree (update a single `branch` node) + deposit_count += 1; + uint size = deposit_count; + for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) { + if ((size & 1) == 1) { + branch[height] = node; + return; + } + node = sha256(abi.encodePacked(branch[height], node)); + size /= 2; + } + // As the loop should always end prematurely with the `return` statement, + // this code should be unreachable. We assert `false` just to be safe. + assert(false); + } + + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + return interfaceId == type(IERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId; + } + + // Dev: function visibility lifted + function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) { + ret = new bytes(8); + bytes8 bytesValue = bytes8(value); + // Byteswapping during copying to bytes. + ret[0] = bytesValue[7]; + ret[1] = bytesValue[6]; + ret[2] = bytesValue[5]; + ret[3] = bytesValue[4]; + ret[4] = bytesValue[3]; + ret[5] = bytesValue[2]; + ret[6] = bytesValue[1]; + ret[7] = bytesValue[0]; } - // As the loop should always end prematurely with the `return` statement, - // this code should be unreachable. We assert `false` just to be safe. - assert(false); - } - - function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { - return interfaceId == type(IERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId; - } - - // Dev: function visibility lifted - function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) { - ret = new bytes(8); - bytes8 bytesValue = bytes8(value); - // Byteswapping during copying to bytes. - ret[0] = bytesValue[7]; - ret[1] = bytesValue[6]; - ret[2] = bytesValue[5]; - ret[3] = bytesValue[4]; - ret[4] = bytesValue[3]; - ret[5] = bytesValue[2]; - ret[6] = bytesValue[1]; - ret[7] = bytesValue[0]; - } } diff --git a/test/0.8.9/Initializable.test.ts b/test/0.8.9/Initializable.test.ts index fc0c221c7..eb7c0ecd2 100644 --- a/test/0.8.9/Initializable.test.ts +++ b/test/0.8.9/Initializable.test.ts @@ -3,14 +3,22 @@ import { ethers } from "hardhat"; import { Initializable__Mock } from "typechain-types"; -describe("Initializable", function () { +import { Snapshot } from "test/suite"; + +describe("Initializable.sol", function () { let initializable: Initializable__Mock; - beforeEach(async function () { + let originalState: string; + + before(async function () { initializable = await ethers.deployContract("Initializable__Mock"); }); - describe("Initialization", function () { + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + + context("Initialization", function () { it("Should emit Initialized event", async function () { await expect(initializable.initialize(1)).to.emit(initializable, "Initialized").withArgs(1); }); diff --git a/test/0.8.9/burner.test.ts b/test/0.8.9/burner.test.ts index df37947b3..5b1fffe29 100644 --- a/test/0.8.9/burner.test.ts +++ b/test/0.8.9/burner.test.ts @@ -4,20 +4,11 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - Burner, - Burner__factory, - ERC20Token__MockForBurner, - ERC20Token__MockForBurner__factory, - NFT__GeneralMock, - NFT__GeneralMock__factory, - Steth__MinimalMock, - Steth__MinimalMock__factory, -} from "typechain-types"; +import { Burner, ERC20__Harness, ERC721__Harness, StETH__Harness } from "typechain-types"; import { batch, certainAddress, ether, impersonate } from "lib"; -describe("Burner", () => { +describe("Burner.sol", () => { let deployer: HardhatEthersSigner; let admin: HardhatEthersSigner; let holder: HardhatEthersSigner; @@ -25,7 +16,7 @@ describe("Burner", () => { let stethAsSigner: HardhatEthersSigner; let burner: Burner; - let steth: Steth__MinimalMock; + let steth: StETH__Harness; const treasury = certainAddress("test:burner:treasury"); const coverSharesBurnt = 0n; @@ -34,8 +25,12 @@ describe("Burner", () => { beforeEach(async () => { [deployer, admin, holder, stranger] = await ethers.getSigners(); - steth = await new Steth__MinimalMock__factory(deployer).deploy(holder, { value: ether("10.0") }); - burner = await new Burner__factory(deployer).deploy(admin, treasury, steth, coverSharesBurnt, nonCoverSharesBurnt); + steth = await ethers.deployContract("StETH__Harness", [holder], { value: ether("10.0"), from: deployer }); + burner = await ethers.deployContract( + "Burner", + [admin, treasury, steth, coverSharesBurnt, nonCoverSharesBurnt], + deployer, + ); steth = steth.connect(holder); burner = burner.connect(holder); @@ -64,20 +59,23 @@ describe("Burner", () => { const differentCoverSharesBurnt = 1n; const differentNonCoverSharesBurntNonZero = 3n; - burner = await new Burner__factory(deployer).deploy( - admin, - treasury, - steth, - differentCoverSharesBurnt, - differentNonCoverSharesBurntNonZero, + burner = await ethers.deployContract( + "Burner", + [admin, treasury, steth, differentCoverSharesBurnt, differentNonCoverSharesBurntNonZero], + deployer, ); + expect(await burner.getCoverSharesBurnt()).to.equal(differentCoverSharesBurnt); expect(await burner.getNonCoverSharesBurnt()).to.equal(differentNonCoverSharesBurntNonZero); }); it("Reverts if admin is zero address", async () => { await expect( - new Burner__factory(deployer).deploy(ZeroAddress, treasury, steth, coverSharesBurnt, nonCoverSharesBurnt), + ethers.deployContract( + "Burner", + [ZeroAddress, treasury, steth, coverSharesBurnt, nonCoverSharesBurnt], + deployer, + ), ) .to.be.revertedWithCustomError(burner, "ZeroAddress") .withArgs("_admin"); @@ -85,7 +83,7 @@ describe("Burner", () => { it("Reverts if Treasury is zero address", async () => { await expect( - new Burner__factory(deployer).deploy(admin, ZeroAddress, steth, coverSharesBurnt, nonCoverSharesBurnt), + ethers.deployContract("Burner", [admin, ZeroAddress, steth, coverSharesBurnt, nonCoverSharesBurnt], deployer), ) .to.be.revertedWithCustomError(burner, "ZeroAddress") .withArgs("_treasury"); @@ -93,7 +91,11 @@ describe("Burner", () => { it("Reverts if stETH is zero address", async () => { await expect( - new Burner__factory(deployer).deploy(admin, treasury, ZeroAddress, coverSharesBurnt, nonCoverSharesBurnt), + ethers.deployContract( + "Burner", + [admin, treasury, ZeroAddress, coverSharesBurnt, nonCoverSharesBurnt], + deployer, + ), ) .to.be.revertedWithCustomError(burner, "ZeroAddress") .withArgs("_stETH"); @@ -275,10 +277,10 @@ describe("Burner", () => { }); context("recoverERC20", () => { - let token: ERC20Token__MockForBurner; + let token: ERC20__Harness; beforeEach(async () => { - token = await new ERC20Token__MockForBurner__factory(deployer).deploy("Token", "TKN"); + token = await ethers.deployContract("ERC20__Harness", ["Token", "TKN"], deployer); await token.mint(burner, ether("1.0")); expect(await token.balanceOf(burner)).to.equal(ether("1.0")); @@ -315,11 +317,11 @@ describe("Burner", () => { }); context("recoverERC721", () => { - let nft: NFT__GeneralMock; + let nft: ERC721__Harness; const tokenId = 1n; beforeEach(async () => { - nft = await new NFT__GeneralMock__factory(deployer).deploy("NFT", "NFT"); + nft = await ethers.deployContract("ERC721__Harness", ["NFT", "NFT"], deployer); await nft.mint(burner, tokenId); expect(await nft.balanceOf(burner)).to.equal(1n); diff --git a/test/0.8.9/contracts/AccessControlEnumerable__Harness.sol b/test/0.8.9/contracts/AccessControlEnumerable__Harness.sol index 323aa113c..62c90c316 100644 --- a/test/0.8.9/contracts/AccessControlEnumerable__Harness.sol +++ b/test/0.8.9/contracts/AccessControlEnumerable__Harness.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -7,10 +6,9 @@ pragma solidity 0.8.9; import {AccessControlEnumerable} from "contracts/0.8.9/utils/access/AccessControlEnumerable.sol"; contract AccessControlEnumerable__Harness is AccessControlEnumerable { + bytes32 public constant TEST_ROLE = keccak256("TEST_ROLE"); - bytes32 public constant TEST_ROLE = keccak256("TEST_ROLE"); - - constructor() { - _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); - } + constructor() { + _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); + } } diff --git a/test/0.8.9/contracts/AccessControl__Harness.sol b/test/0.8.9/contracts/AccessControl__Harness.sol index 1d8e7188f..e706b3a68 100644 --- a/test/0.8.9/contracts/AccessControl__Harness.sol +++ b/test/0.8.9/contracts/AccessControl__Harness.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -7,18 +6,17 @@ pragma solidity 0.8.9; import {AccessControl} from "contracts/0.8.9/utils/access/AccessControl.sol"; contract AccessControl__Harness is AccessControl { + bytes32 public constant TEST_ADMIN_ROLE = keccak256("TEST_ADMIN_ROLE"); - bytes32 public constant TEST_ADMIN_ROLE = keccak256("TEST_ADMIN_ROLE"); + bytes32 public constant TEST_ROLE = keccak256("TEST_ROLE"); - bytes32 public constant TEST_ROLE = keccak256("TEST_ROLE"); + constructor() { + _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); + } - constructor() { - _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); - } + function modifierOnlyRole(bytes32 role) external view onlyRole(role) {} - function modifierOnlyRole(bytes32 role) external view onlyRole(role) {} - - function exposedSetupAdminRole(bytes32 role, bytes32 adminRole) external { - _setRoleAdmin(role, adminRole); - } + function harness__setupAdminRole(bytes32 role, bytes32 adminRole) external { + _setRoleAdmin(role, adminRole); + } } diff --git a/test/0.8.9/contracts/oracle/AccountingOracleTimeTravellable.sol b/test/0.8.9/contracts/AccountingOracle__Harness.sol similarity index 52% rename from test/0.8.9/contracts/oracle/AccountingOracleTimeTravellable.sol rename to test/0.8.9/contracts/AccountingOracle__Harness.sol index f1ae2279f..aa8f0a415 100644 --- a/test/0.8.9/contracts/oracle/AccountingOracleTimeTravellable.sol +++ b/test/0.8.9/contracts/AccountingOracle__Harness.sol @@ -1,23 +1,25 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.9; - +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only -import { UnstructuredStorage } from "contracts/0.8.9/lib/UnstructuredStorage.sol"; -import { AccountingOracle } from "contracts/0.8.9/oracle/AccountingOracle.sol"; +pragma solidity 0.8.9; +import {UnstructuredStorage} from "contracts/0.8.9/lib/UnstructuredStorage.sol"; +import {AccountingOracle} from "contracts/0.8.9/oracle/AccountingOracle.sol"; interface ITimeProvider { function getTime() external view returns (uint256); } - -contract AccountingOracleTimeTravellable is AccountingOracle, ITimeProvider { +contract AccountingOracle__Harness is AccountingOracle, ITimeProvider { using UnstructuredStorage for bytes32; - constructor(address lidoLocator, address lido, address legacyOracle, uint256 secondsPerSlot, uint256 genesisTime) - AccountingOracle(lidoLocator, lido, legacyOracle, secondsPerSlot, genesisTime) - { + constructor( + address lidoLocator, + address lido, + address legacyOracle, + uint256 secondsPerSlot, + uint256 genesisTime + ) AccountingOracle(lidoLocator, lido, legacyOracle, secondsPerSlot, genesisTime) { // allow usage without a proxy for tests CONTRACT_VERSION_POSITION.setStorageUint256(0); } @@ -26,7 +28,7 @@ contract AccountingOracleTimeTravellable is AccountingOracle, ITimeProvider { return _getTime(); } - function _getTime() internal override view returns (uint256) { + function _getTime() internal view override returns (uint256) { address consensus = CONSENSUS_CONTRACT_POSITION.getStorageAddress(); return ITimeProvider(consensus).getTime(); } diff --git a/test/0.8.9/contracts/BaseOracle__Harness.sol b/test/0.8.9/contracts/BaseOracle__Harness.sol index 92b93da2f..db03d3019 100644 --- a/test/0.8.9/contracts/BaseOracle__Harness.sol +++ b/test/0.8.9/contracts/BaseOracle__Harness.sol @@ -1,15 +1,10 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.9; +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only -import { UnstructuredStorage } from "contracts/0.8.9/lib/UnstructuredStorage.sol"; -import { BaseOracle } from "contracts/0.8.9/oracle/BaseOracle.sol"; +pragma solidity 0.8.9; -struct ConsensusReport { - bytes32 hash; - uint64 refSlot; - uint64 processingDeadlineTime; -} +import {UnstructuredStorage} from "contracts/0.8.9/lib/UnstructuredStorage.sol"; +import {BaseOracle} from "contracts/0.8.9/oracle/BaseOracle.sol"; contract BaseOracle__Harness is BaseOracle { using UnstructuredStorage for bytes32; @@ -18,32 +13,22 @@ contract BaseOracle__Harness is BaseOracle { event MockStartProcessingResult(uint256 prevProcessingRefSlot); struct HandleConsensusReportLastCall { - ConsensusReport report; + BaseOracle.ConsensusReport report; uint256 prevSubmittedRefSlot; uint256 prevProcessingRefSlot; uint256 callCount; } + HandleConsensusReportLastCall internal _handleConsensusReportLastCall; - ConsensusReport public lastDiscardedReport; + BaseOracle.ConsensusReport public lastDiscardedReport; - constructor( - uint256 secondsPerSlot, - uint256 genesisTime, - address admin - ) BaseOracle(secondsPerSlot, genesisTime) { + constructor(uint256 secondsPerSlot, uint256 genesisTime, address admin) BaseOracle(secondsPerSlot, genesisTime) { _setupRole(DEFAULT_ADMIN_ROLE, admin); CONTRACT_VERSION_POSITION.setStorageUint256(0); - require( - genesisTime <= _time, - "GENESIS_TIME_CANNOT_BE_MORE_THAN_MOCK_TIME" - ); + require(genesisTime <= _time, "GENESIS_TIME_CANNOT_BE_MORE_THAN_MOCK_TIME"); } - function initialize( - address consensusContract, - uint256 consensusVersion, - uint256 lastProcessingRefSlot - ) external { + function initialize(address consensusContract, uint256 consensusVersion, uint256 lastProcessingRefSlot) external { _initialize(consensusContract, consensusVersion, lastProcessingRefSlot); } @@ -55,7 +40,7 @@ contract BaseOracle__Harness is BaseOracle { return _time; } - function originalGetTime() external view returns (uint256) { + function harness_getTime() external view returns (uint256) { return BaseOracle._getTime(); } @@ -68,29 +53,21 @@ contract BaseOracle__Harness is BaseOracle { } function _handleConsensusReport( - ConsensusReport memory report, + BaseOracle.ConsensusReport memory report, uint256 prevSubmittedRefSlot, uint256 prevProcessingRefSlot ) internal virtual override { _handleConsensusReportLastCall.report = report; - _handleConsensusReportLastCall - .prevSubmittedRefSlot = prevSubmittedRefSlot; - _handleConsensusReportLastCall - .prevProcessingRefSlot = prevProcessingRefSlot; + _handleConsensusReportLastCall.prevSubmittedRefSlot = prevSubmittedRefSlot; + _handleConsensusReportLastCall.prevProcessingRefSlot = prevProcessingRefSlot; ++_handleConsensusReportLastCall.callCount; } - function _handleConsensusReportDiscarded( - ConsensusReport memory report - ) internal override { + function _handleConsensusReportDiscarded(BaseOracle.ConsensusReport memory report) internal override { lastDiscardedReport = report; } - function getConsensusReportLastCall() - external - view - returns (HandleConsensusReportLastCall memory) - { + function getConsensusReportLastCall() external view returns (HandleConsensusReportLastCall memory) { return _handleConsensusReportLastCall; } @@ -107,11 +84,7 @@ contract BaseOracle__Harness is BaseOracle { return _getCurrentRefSlot(); } - function checkConsensusData( - uint256 refSlot, - uint256 consensusVersion, - bytes32 hash - ) external view { + function checkConsensusData(uint256 refSlot, uint256 consensusVersion, bytes32 hash) external view { _checkConsensusData(refSlot, consensusVersion, hash); } diff --git a/test/0.8.9/contracts/Burner__MockForOracleSanityChecker.sol b/test/0.8.9/contracts/Burner__MockForOracleSanityChecker.sol new file mode 100644 index 000000000..ba7f4c938 --- /dev/null +++ b/test/0.8.9/contracts/Burner__MockForOracleSanityChecker.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +contract Burner__MockForOracleSanityChecker { + uint256 private nonCover; + uint256 private cover; + + function getSharesRequestedToBurn() external view returns (uint256 coverShares, uint256 nonCoverShares) { + coverShares = cover; + nonCoverShares = nonCover; + } + + function setSharesRequestedToBurn(uint256 _cover, uint256 _nonCover) external { + cover = _cover; + nonCover = _nonCover; + } +} diff --git a/test/0.8.9/contracts/MockConsensusContract.sol b/test/0.8.9/contracts/ConsensusContract__Mock.sol similarity index 59% rename from test/0.8.9/contracts/MockConsensusContract.sol rename to test/0.8.9/contracts/ConsensusContract__Mock.sol index 67dc1971b..ed0754369 100644 --- a/test/0.8.9/contracts/MockConsensusContract.sol +++ b/test/0.8.9/contracts/ConsensusContract__Mock.sol @@ -1,15 +1,14 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; -import { SafeCast } from "@openzeppelin/contracts-v4.4/utils/math/SafeCast.sol"; +import {SafeCast} from "@openzeppelin/contracts-v4.4/utils/math/SafeCast.sol"; -import { IConsensusContract } from "../../../contracts/0.8.9/oracle/BaseOracle.sol"; -import { IReportAsyncProcessor } from "../../../contracts/0.8.9/oracle/HashConsensus.sol"; +import {IConsensusContract} from "contracts/0.8.9/oracle/BaseOracle.sol"; +import {IReportAsyncProcessor} from "contracts/0.8.9/oracle/HashConsensus.sol"; -contract MockConsensusContract is IConsensusContract { +contract ConsensusContract__Mock is IConsensusContract { using SafeCast for uint256; uint64 internal immutable SLOTS_PER_EPOCH; @@ -63,26 +62,14 @@ contract MockConsensusContract is IConsensusContract { return _memberIndices1b[addr] != 0; } - function getCurrentFrame() - external - view - returns (uint256 refSlot, uint256 reportProcessingDeadlineSlot) - { - return ( - _consensusFrame.refSlot, - _consensusFrame.reportProcessingDeadlineSlot - ); + function getCurrentFrame() external view returns (uint256 refSlot, uint256 reportProcessingDeadlineSlot) { + return (_consensusFrame.refSlot, _consensusFrame.reportProcessingDeadlineSlot); } - function setCurrentFrame( - uint256 index, - uint256 refSlot, - uint256 reportProcessingDeadlineSlot - ) external { + function setCurrentFrame(uint256 index, uint256 refSlot, uint256 reportProcessingDeadlineSlot) external { _consensusFrame.index = index; _consensusFrame.refSlot = refSlot; - _consensusFrame - .reportProcessingDeadlineSlot = reportProcessingDeadlineSlot; + _consensusFrame.reportProcessingDeadlineSlot = reportProcessingDeadlineSlot; } function setInitialRefSlot(uint256 initialRefSlot) external { @@ -92,20 +79,12 @@ contract MockConsensusContract is IConsensusContract { function getChainConfig() external view - returns ( - uint256 slotsPerEpoch, - uint256 secondsPerSlot, - uint256 genesisTime - ) + returns (uint256 slotsPerEpoch, uint256 secondsPerSlot, uint256 genesisTime) { return (SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME); } - function getFrameConfig() - external - view - returns (uint256 initialEpoch, uint256 epochsPerFrame) - { + function getFrameConfig() external view returns (uint256 initialEpoch, uint256 epochsPerFrame) { return (_frameConfig.initialEpoch, _frameConfig.epochsPerFrame); } @@ -113,16 +92,8 @@ contract MockConsensusContract is IConsensusContract { return _initialRefSlot; } - function _setFrameConfig( - uint256 initialEpoch, - uint256 epochsPerFrame, - uint256 fastLaneLengthSlots - ) internal { - _frameConfig = FrameConfig( - initialEpoch.toUint64(), - epochsPerFrame.toUint64(), - fastLaneLengthSlots.toUint64() - ); + function _setFrameConfig(uint256 initialEpoch, uint256 epochsPerFrame, uint256 fastLaneLengthSlots) internal { + _frameConfig = FrameConfig(initialEpoch.toUint64(), epochsPerFrame.toUint64(), fastLaneLengthSlots.toUint64()); } // @@ -133,16 +104,8 @@ contract MockConsensusContract is IConsensusContract { _reportProcessor = reportProcessor; } - function submitReportAsConsensus( - bytes32 reportHash, - uint256 refSlot, - uint256 deadline - ) external { - IReportAsyncProcessor(_reportProcessor).submitConsensusReport( - reportHash, - refSlot, - deadline - ); + function submitReportAsConsensus(bytes32 reportHash, uint256 refSlot, uint256 deadline) external { + IReportAsyncProcessor(_reportProcessor).submitConsensusReport(reportHash, refSlot, deadline); } function discardReportAsConsensus(uint256 refSlot) external { diff --git a/test/0.8.9/contracts/Counters__GeneralMock.sol b/test/0.8.9/contracts/Counters__GeneralMock.sol deleted file mode 100644 index 783c688d0..000000000 --- a/test/0.8.9/contracts/Counters__GeneralMock.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.8.9; - -library Counters__GeneralMock { - struct Counter { - uint256 _value; // default: 0 - } - - function current(Counter storage counter) internal view returns (uint256) { - return counter._value; - } - - function increment(Counter storage counter) internal { - counter._value += 1; - } - - function decrement(Counter storage counter) internal { - counter._value = counter._value - 1; - } -} diff --git a/test/0.8.9/contracts/Counters__Mock.sol b/test/0.8.9/contracts/Counters__Mock.sol new file mode 100644 index 000000000..8798bb050 --- /dev/null +++ b/test/0.8.9/contracts/Counters__Mock.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +library Counters__Mock { + struct Counter { + uint256 _value; // default: 0 + } + + function current(Counter storage counter) internal view returns (uint256) { + return counter._value; + } + + function increment(Counter storage counter) internal { + counter._value += 1; + } + + function decrement(Counter storage counter) internal { + counter._value = counter._value - 1; + } +} diff --git a/test/0.8.9/contracts/DepositContract__MockForBeaconChainDepositor.sol b/test/0.8.9/contracts/DepositContract__MockForBeaconChainDepositor.sol index 4ba66fddf..4889e6ab0 100644 --- a/test/0.8.9/contracts/DepositContract__MockForBeaconChainDepositor.sol +++ b/test/0.8.9/contracts/DepositContract__MockForBeaconChainDepositor.sol @@ -1,18 +1,17 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; contract DepositContract__MockForBeaconChainDepositor { - event Deposited__MockEvent(); + event Deposited__MockEvent(); - function deposit( - bytes calldata pubkey, // 48 bytes - bytes calldata withdrawal_credentials, // 32 bytes - bytes calldata signature, // 96 bytes - bytes32 deposit_data_root - ) external payable { - emit Deposited__MockEvent(); - } + function deposit( + bytes calldata pubkey, // 48 bytes + bytes calldata withdrawal_credentials, // 32 bytes + bytes calldata signature, // 96 bytes + bytes32 deposit_data_root + ) external payable { + emit Deposited__MockEvent(); + } } diff --git a/test/0.8.9/contracts/DepositContractMockForDepositSecurityModule.sol b/test/0.8.9/contracts/DepositContract__MockForDepositSecurityModule.sol similarity index 66% rename from test/0.8.9/contracts/DepositContractMockForDepositSecurityModule.sol rename to test/0.8.9/contracts/DepositContract__MockForDepositSecurityModule.sol index e2e37ec63..ab1a7b935 100644 --- a/test/0.8.9/contracts/DepositContractMockForDepositSecurityModule.sol +++ b/test/0.8.9/contracts/DepositContract__MockForDepositSecurityModule.sol @@ -1,10 +1,9 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; -contract DepositContractMockForDepositSecurityModule { +contract DepositContract__MockForDepositSecurityModule { bytes32 internal depositRoot; function get_deposit_root() external view returns (bytes32) { diff --git a/test/0.8.9/contracts/ERC20Token__MockForBurner.sol b/test/0.8.9/contracts/ERC20Token__MockForBurner.sol deleted file mode 100644 index 3608d21cf..000000000 --- a/test/0.8.9/contracts/ERC20Token__MockForBurner.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.8.9; - -import {ERC20} from "@openzeppelin/contracts-v4.4/token/ERC20/ERC20.sol"; - -contract ERC20Token__MockForBurner is ERC20 { - constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {} - - function mint(address to, uint256 amount) external { - super._mint(to, amount); - } -} diff --git a/test/0.8.9/contracts/ERC20Token__MockForWithdrawalVault.sol b/test/0.8.9/contracts/ERC20Token__MockForWithdrawalVault.sol deleted file mode 100644 index 4aaf989b3..000000000 --- a/test/0.8.9/contracts/ERC20Token__MockForWithdrawalVault.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.8.9; - -import {ERC20} from "@openzeppelin/contracts-v4.4/token/ERC20/ERC20.sol"; - -contract ERC20Token__MockForWithdrawalVault is ERC20 { - constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {} - - function mint(address _to, uint256 _amount) external { - super._mint(_to, _amount); - } -} diff --git a/test/0.8.9/contracts/ERC20__Harness.sol b/test/0.8.9/contracts/ERC20__Harness.sol new file mode 100644 index 000000000..28346603a --- /dev/null +++ b/test/0.8.9/contracts/ERC20__Harness.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +import {ERC20} from "@openzeppelin/contracts-v4.4/token/ERC20/ERC20.sol"; + +contract ERC20__Harness is ERC20 { + constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {} + + function mint(address to, uint256 amount) external { + super._mint(to, amount); + } +} diff --git a/test/0.8.9/contracts/ERC721ReceiverMock.sol b/test/0.8.9/contracts/ERC721ReceiverMock.sol deleted file mode 100644 index 20f8b1b6f..000000000 --- a/test/0.8.9/contracts/ERC721ReceiverMock.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.8.9; - -import {IERC721Receiver} from "@openzeppelin/contracts-v4.4/token/ERC721/IERC721Receiver.sol"; - -contract ERC721ReceiverMock is IERC721Receiver { - bool public doesAcceptTokens; - string public ERROR_MSG = "ERC721_NOT_ACCEPT_TOKENS"; - - function setDoesAcceptTokens(bool _value) external { - doesAcceptTokens = _value; - } - - function onERC721Received( - address, // operator, - address, // from, - uint256, // tokenId, - bytes calldata // data - ) external view returns (bytes4) { - if (!doesAcceptTokens) { - revert(ERROR_MSG); - } - return - bytes4( - keccak256("onERC721Received(address,address,uint256,bytes)") - ); - } - - receive() external payable { - if (!doesAcceptTokens) { - revert(ERROR_MSG); - } - } -} diff --git a/test/0.8.9/contracts/ERC721Receiver__MockWithdrawalQueueERC721.sol b/test/0.8.9/contracts/ERC721Receiver__Mock.sol similarity index 62% rename from test/0.8.9/contracts/ERC721Receiver__MockWithdrawalQueueERC721.sol rename to test/0.8.9/contracts/ERC721Receiver__Mock.sol index 7a841186b..4ad9e045e 100644 --- a/test/0.8.9/contracts/ERC721Receiver__MockWithdrawalQueueERC721.sol +++ b/test/0.8.9/contracts/ERC721Receiver__Mock.sol @@ -1,19 +1,20 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; -contract ERC721Receiver__MockWithdrawalQueueERC721 { - bool public isReturnValid; +import {IERC721Receiver} from "@openzeppelin/contracts-v4.4/token/ERC721/IERC721Receiver.sol"; + +contract ERC721Receiver__Mock is IERC721Receiver { + bool public isReturnValid = true; bool public doesAcceptTokens; string public ERROR_MSG = "ERC721_NOT_ACCEPT_TOKENS"; - function setDoesAcceptTokens(bool _value) external { + function mock__setDoesAcceptTokens(bool _value) external { doesAcceptTokens = _value; } - function setReturnValid(bool _value) external { + function mock__setReturnValid(bool _value) external { isReturnValid = _value; } @@ -29,10 +30,7 @@ contract ERC721Receiver__MockWithdrawalQueueERC721 { if (!isReturnValid) { return bytes4(keccak256("neverGonnaGiveYouUp()")); } - return - bytes4( - keccak256("onERC721Received(address,address,uint256,bytes)") - ); + return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")); } receive() external payable { diff --git a/test/0.8.9/contracts/ERC721Token_MockForWithdrawalVault.sol b/test/0.8.9/contracts/ERC721Token_MockForWithdrawalVault.sol deleted file mode 100644 index 7bfa6b329..000000000 --- a/test/0.8.9/contracts/ERC721Token_MockForWithdrawalVault.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.8.9; - -import {ERC721} from "@openzeppelin/contracts-v4.4/token/ERC721/ERC721.sol"; - -contract ERC721Token_MockForWithdrawalVault is ERC721 { - constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {} - - function mint(address _account, uint256 _tokenId) public { - super._mint(_account, _tokenId); - } -} diff --git a/test/0.8.9/contracts/ERC721__Harness.sol b/test/0.8.9/contracts/ERC721__Harness.sol new file mode 100644 index 000000000..ca6c3730a --- /dev/null +++ b/test/0.8.9/contracts/ERC721__Harness.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +import {ERC721} from "@openzeppelin/contracts-v4.4/token/ERC721/ERC721.sol"; + +contract ERC721__Harness is ERC721 { + constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {} + + function mint(address to, uint256 id) external { + super._mint(to, id); + } +} diff --git a/test/0.8.9/contracts/oracle/HashConsensusTimeTravellable.sol b/test/0.8.9/contracts/HashConsensus__Harness.sol similarity index 77% rename from test/0.8.9/contracts/oracle/HashConsensusTimeTravellable.sol rename to test/0.8.9/contracts/HashConsensus__Harness.sol index 2736bf64c..aa06b8318 100644 --- a/test/0.8.9/contracts/oracle/HashConsensusTimeTravellable.sol +++ b/test/0.8.9/contracts/HashConsensus__Harness.sol @@ -1,12 +1,11 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.9; - +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only -import { HashConsensus } from "contracts/0.8.9/oracle/HashConsensus.sol"; +pragma solidity 0.8.9; +import {HashConsensus} from "contracts/0.8.9/oracle/HashConsensus.sol"; -contract HashConsensusTimeTravellable is HashConsensus { +contract HashConsensus__Harness is HashConsensus { uint256 internal _time = 2513040315; constructor( @@ -17,19 +16,21 @@ contract HashConsensusTimeTravellable is HashConsensus { uint256 fastLaneLengthSlots, address admin, address reportProcessor - ) HashConsensus( - slotsPerEpoch, - secondsPerSlot, - genesisTime, - epochsPerFrame, - fastLaneLengthSlots, - admin, - reportProcessor - ) { + ) + HashConsensus( + slotsPerEpoch, + secondsPerSlot, + genesisTime, + epochsPerFrame, + fastLaneLengthSlots, + admin, + reportProcessor + ) + { require(genesisTime <= _time, "GENESIS_TIME_CANNOT_BE_MORE_THAN_MOCK_TIME"); } - function _getTime() internal override view returns (uint256) { + function _getTime() internal view override returns (uint256) { return _time; } diff --git a/test/0.8.9/contracts/Initializable__Mock.sol b/test/0.8.9/contracts/Initializable__Mock.sol index 20d1dc07c..391c90663 100644 --- a/test/0.8.9/contracts/Initializable__Mock.sol +++ b/test/0.8.9/contracts/Initializable__Mock.sol @@ -1,27 +1,27 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only -pragma solidity ^0.8.9; +pragma solidity 0.8.9; contract Initializable__Mock { - uint8 private _version; - bool private _initialized; - event Initialized(uint256 version); - event ReceiveCalled(); + uint8 private _version; + bool private _initialized; - function initialize(uint8 _v) public payable { - require(!_initialized, "Contract is already initialized"); - _version = _v; - _initialized = true; - emit Initialized(_v); - } + event Initialized(uint256 version); + event ReceiveCalled(); - function version() public view returns (uint8) { - return _version; - } + function initialize(uint8 _v) public payable { + require(!_initialized, "Contract is already initialized"); + _version = _v; + _initialized = true; + emit Initialized(_v); + } - receive() external payable { - emit ReceiveCalled(); - } + function version() public view returns (uint8) { + return _version; + } + + receive() external payable { + emit ReceiveCalled(); + } } diff --git a/test/0.8.9/contracts/LidoLocator__MockForOracleSanityChecker.sol b/test/0.8.9/contracts/LidoLocator__MockForOracleSanityChecker.sol new file mode 100644 index 000000000..98377b54c --- /dev/null +++ b/test/0.8.9/contracts/LidoLocator__MockForOracleSanityChecker.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +interface ILidoLocator { + function lido() external view returns (address); + + function burner() external view returns (address); + + function withdrawalVault() external view returns (address); + + function withdrawalQueue() external view returns (address); +} + +contract LidoLocator__MockForOracleSanityChecker is ILidoLocator { + address private immutable LIDO; + address private immutable WITHDRAWAL_VAULT; + address private immutable WITHDRAWAL_QUEUE; + address private immutable EL_REWARDS_VAULT; + address private immutable BURNER; + + constructor( + address _lido, + address _withdrawalVault, + address _withdrawalQueue, + address _elRewardsVault, + address _burner + ) { + LIDO = _lido; + WITHDRAWAL_VAULT = _withdrawalVault; + WITHDRAWAL_QUEUE = _withdrawalQueue; + EL_REWARDS_VAULT = _elRewardsVault; + BURNER = _burner; + } + + function lido() external view returns (address) { + return LIDO; + } + + function withdrawalQueue() external view returns (address) { + return WITHDRAWAL_QUEUE; + } + + function withdrawalVault() external view returns (address) { + return WITHDRAWAL_VAULT; + } + + function elRewardsVault() external view returns (address) { + return EL_REWARDS_VAULT; + } + + function burner() external view returns (address) { + return BURNER; + } +} diff --git a/test/0.8.9/contracts/LidoLocator__MockMutable.sol b/test/0.8.9/contracts/LidoLocator__MockMutable.sol new file mode 100644 index 000000000..bc00f97b1 --- /dev/null +++ b/test/0.8.9/contracts/LidoLocator__MockMutable.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +contract LidoLocator__MockMutable { + struct Config { + address accountingOracle; + address depositSecurityModule; + address elRewardsVault; + address legacyOracle; + address lido; + address oracleReportSanityChecker; + address postTokenRebaseReceiver; + address burner; + address stakingRouter; + address treasury; + address validatorsExitBusOracle; + address withdrawalQueue; + address withdrawalVault; + address oracleDaemonConfig; + address wstEth; + } + + error ZeroAddress(); + + address public accountingOracle; + address public immutable depositSecurityModule; + address public immutable elRewardsVault; + address public immutable legacyOracle; + address public immutable lido; + address public immutable oracleReportSanityChecker; + address public postTokenRebaseReceiver; + address public immutable burner; + address public immutable stakingRouter; + address public immutable treasury; + address public immutable validatorsExitBusOracle; + address public immutable withdrawalQueue; + address public immutable withdrawalVault; + address public immutable oracleDaemonConfig; + address public immutable wstEth; + + /** + * @notice declare service locations + * @dev accepts a struct to avoid the "stack-too-deep" error + * @param _config struct of addresses + */ + constructor(Config memory _config) { + accountingOracle = _assertNonZero(_config.accountingOracle); + depositSecurityModule = _assertNonZero(_config.depositSecurityModule); + elRewardsVault = _assertNonZero(_config.elRewardsVault); + legacyOracle = _assertNonZero(_config.legacyOracle); + lido = _assertNonZero(_config.lido); + oracleReportSanityChecker = _assertNonZero(_config.oracleReportSanityChecker); + postTokenRebaseReceiver = _assertNonZero(_config.postTokenRebaseReceiver); + burner = _assertNonZero(_config.burner); + stakingRouter = _assertNonZero(_config.stakingRouter); + treasury = _assertNonZero(_config.treasury); + validatorsExitBusOracle = _assertNonZero(_config.validatorsExitBusOracle); + withdrawalQueue = _assertNonZero(_config.withdrawalQueue); + withdrawalVault = _assertNonZero(_config.withdrawalVault); + oracleDaemonConfig = _assertNonZero(_config.oracleDaemonConfig); + wstEth = _assertNonZero(_config.wstEth); + } + + function coreComponents() external view returns (address, address, address, address, address, address) { + return (elRewardsVault, oracleReportSanityChecker, stakingRouter, treasury, withdrawalQueue, withdrawalVault); + } + + function oracleReportComponentsForLido() + external + view + returns (address, address, address, address, address, address, address) + { + return ( + accountingOracle, + elRewardsVault, + oracleReportSanityChecker, + burner, + withdrawalQueue, + withdrawalVault, + postTokenRebaseReceiver + ); + } + + function _assertNonZero(address _address) internal pure returns (address) { + if (_address == address(0)) revert ZeroAddress(); + return _address; + } + + function mock___updatePostTokenRebaseReceiver(address newAddress) external { + postTokenRebaseReceiver = newAddress; + } + + function mock___updateAccountingOracle(address newAddress) external { + accountingOracle = newAddress; + } +} diff --git a/test/0.8.9/contracts/oracle/MockLidoForAccountingOracle.sol b/test/0.8.9/contracts/Lido__MockForAccountingOracle.sol similarity index 69% rename from test/0.8.9/contracts/oracle/MockLidoForAccountingOracle.sol rename to test/0.8.9/contracts/Lido__MockForAccountingOracle.sol index 869a1dae5..38b3f8915 100644 --- a/test/0.8.9/contracts/oracle/MockLidoForAccountingOracle.sol +++ b/test/0.8.9/contracts/Lido__MockForAccountingOracle.sol @@ -1,8 +1,9 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + pragma solidity 0.8.9; -import { ILido } from "contracts/0.8.9/oracle/AccountingOracle.sol"; +import {ILido} from "contracts/0.8.9/oracle/AccountingOracle.sol"; interface IPostTokenRebaseReceiver { function handlePostTokenRebase( @@ -16,7 +17,7 @@ interface IPostTokenRebaseReceiver { ) external; } -contract MockLidoForAccountingOracle is ILido { +contract Lido__MockForAccountingOracle is ILido { address internal legacyOracle; struct HandleOracleReportLastCall { @@ -34,11 +35,7 @@ contract MockLidoForAccountingOracle is ILido { HandleOracleReportLastCall internal _handleOracleReportLastCall; - function getLastCall_handleOracleReport() - external - view - returns (HandleOracleReportLastCall memory) - { + function getLastCall_handleOracleReport() external view returns (HandleOracleReportLastCall memory) { return _handleOracleReportLastCall; } @@ -61,20 +58,14 @@ contract MockLidoForAccountingOracle is ILido { uint256[] calldata withdrawalFinalizationBatches, uint256 simulatedShareRate ) external { - _handleOracleReportLastCall - .currentReportTimestamp = currentReportTimestamp; - _handleOracleReportLastCall - .secondsElapsedSinceLastReport = secondsElapsedSinceLastReport; + _handleOracleReportLastCall.currentReportTimestamp = currentReportTimestamp; + _handleOracleReportLastCall.secondsElapsedSinceLastReport = secondsElapsedSinceLastReport; _handleOracleReportLastCall.numValidators = numValidators; _handleOracleReportLastCall.clBalance = clBalance; - _handleOracleReportLastCall - .withdrawalVaultBalance = withdrawalVaultBalance; - _handleOracleReportLastCall - .elRewardsVaultBalance = elRewardsVaultBalance; - _handleOracleReportLastCall - .sharesRequestedToBurn = sharesRequestedToBurn; - _handleOracleReportLastCall - .withdrawalFinalizationBatches = withdrawalFinalizationBatches; + _handleOracleReportLastCall.withdrawalVaultBalance = withdrawalVaultBalance; + _handleOracleReportLastCall.elRewardsVaultBalance = elRewardsVaultBalance; + _handleOracleReportLastCall.sharesRequestedToBurn = sharesRequestedToBurn; + _handleOracleReportLastCall.withdrawalFinalizationBatches = withdrawalFinalizationBatches; _handleOracleReportLastCall.simulatedShareRate = simulatedShareRate; ++_handleOracleReportLastCall.callCount; diff --git a/test/0.8.9/contracts/LidoMockForDepositSecurityModule.sol b/test/0.8.9/contracts/Lido__MockForDepositSecurityModule.sol similarity index 75% rename from test/0.8.9/contracts/LidoMockForDepositSecurityModule.sol rename to test/0.8.9/contracts/Lido__MockForDepositSecurityModule.sol index 5ebebb473..f65ceae4f 100644 --- a/test/0.8.9/contracts/LidoMockForDepositSecurityModule.sol +++ b/test/0.8.9/contracts/Lido__MockForDepositSecurityModule.sol @@ -1,10 +1,9 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; -contract LidoMockForDepositSecurityModule { +contract Lido__MockForDepositSecurityModule { bool internal canDepositState; event StakingModuleDeposited(uint256 maxDepositsCount, uint24 stakingModuleId, bytes depositCalldata); @@ -22,12 +21,12 @@ contract LidoMockForDepositSecurityModule { uint256 maxDepositsCount, uint256 stakingModuleId, bytes calldata depositCalldata - ) external returns(uint256 keysCount) { + ) external returns (uint256 keysCount) { emit StakingModuleDeposited(maxDepositsCount, uint24(stakingModuleId), depositCalldata); return maxDepositsCount; } - function canDeposit() external view returns(bool) { + function canDeposit() external view returns (bool) { return canDepositState; } } diff --git a/test/0.8.9/contracts/Lido__MockForElRewardsVault.sol b/test/0.8.9/contracts/Lido__MockForElRewardsVault.sol index 251db80e4..0e0c3d516 100644 --- a/test/0.8.9/contracts/Lido__MockForElRewardsVault.sol +++ b/test/0.8.9/contracts/Lido__MockForElRewardsVault.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -10,4 +9,4 @@ contract Lido__MockForElRewardsVault { function receiveELRewards() external payable { emit ELRewardsReceived(msg.value); } -} \ No newline at end of file +} diff --git a/test/0.8.9/contracts/Lido__MockForOracleSanityChecker.sol b/test/0.8.9/contracts/Lido__MockForOracleSanityChecker.sol new file mode 100644 index 000000000..ad5fdc734 --- /dev/null +++ b/test/0.8.9/contracts/Lido__MockForOracleSanityChecker.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +contract Lido__MockForOracleSanityChecker { + uint256 private _shareRate = 1 ether; + + function getSharesByPooledEth(uint256 _sharesAmount) external view returns (uint256) { + return (_shareRate * _sharesAmount) / 1 ether; + } + + function setShareRate(uint256 _value) external { + _shareRate = _value; + } +} diff --git a/test/0.8.9/contracts/Lido__MockForWithdrawalVault.sol b/test/0.8.9/contracts/Lido__MockForWithdrawalVault.sol index ade12d3bf..0da47f3e7 100644 --- a/test/0.8.9/contracts/Lido__MockForWithdrawalVault.sol +++ b/test/0.8.9/contracts/Lido__MockForWithdrawalVault.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; diff --git a/test/0.8.9/contracts/Math__Harness.sol b/test/0.8.9/contracts/Math__Harness.sol index 8cc04f1d1..c07b5e6bc 100644 --- a/test/0.8.9/contracts/Math__Harness.sol +++ b/test/0.8.9/contracts/Math__Harness.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -15,15 +14,11 @@ contract Math__Harness { return Math.min(a, b); } - function pointInHalfOpenIntervalModN(uint256 x, uint256 a, uint256 b, uint256 n) - public pure returns (bool) - { + function pointInHalfOpenIntervalModN(uint256 x, uint256 a, uint256 b, uint256 n) public pure returns (bool) { return Math.pointInHalfOpenIntervalModN(x, a, b, n); } - function pointInClosedIntervalModN(uint256 x, uint256 a, uint256 b, uint256 n) - public pure returns (bool) - { + function pointInClosedIntervalModN(uint256 x, uint256 a, uint256 b, uint256 n) public pure returns (bool) { return Math.pointInClosedIntervalModN(x, a, b, n); } } diff --git a/test/0.8.9/contracts/NFTDescriptor__MockForWithdrawalQueue.sol b/test/0.8.9/contracts/NFTDescriptor__MockForWithdrawalQueue.sol index fd06f330e..76d7af268 100644 --- a/test/0.8.9/contracts/NFTDescriptor__MockForWithdrawalQueue.sol +++ b/test/0.8.9/contracts/NFTDescriptor__MockForWithdrawalQueue.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -16,9 +15,7 @@ contract NFTDescriptor__MockForWithdrawalQueue is INFTDescriptor { BASE_TOKEN_URI = _toBytes32(_baseURI); } - function constructTokenURI( - uint256 _requestId - ) external view returns (string memory) { + function constructTokenURI(uint256 _requestId) external view returns (string memory) { string memory baseURI = _toString(BASE_TOKEN_URI); return string(abi.encodePacked(baseURI, _requestId.toString())); } diff --git a/test/0.8.9/contracts/NFT__GeneralMock.sol b/test/0.8.9/contracts/NFT__GeneralMock.sol deleted file mode 100644 index 767428241..000000000 --- a/test/0.8.9/contracts/NFT__GeneralMock.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.8.9; - -import {ERC721} from "@openzeppelin/contracts-v4.4/token/ERC721/ERC721.sol"; - -contract NFT__GeneralMock is ERC721 { - constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {} - - function mint(address to, uint256 id) external { - super._mint(to, id); - } -} diff --git a/test/0.8.9/contracts/OracleReportSanityChecker__Mock.sol b/test/0.8.9/contracts/OracleReportSanityChecker__Mock.sol new file mode 100644 index 000000000..a3ff27f95 --- /dev/null +++ b/test/0.8.9/contracts/OracleReportSanityChecker__Mock.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +contract OracleReportSanityChecker__Mock { + error SelectorNotFound(bytes4 sig, uint256 value, bytes data); + + fallback() external payable { + revert SelectorNotFound(msg.sig, msg.value, msg.data); + } + + function checkAccountingOracleReport( + uint256 _timeElapsed, + uint256 _preCLBalance, + uint256 _postCLBalance, + uint256 _withdrawalVaultBalance, + uint256 _elRewardsVaultBalance, + uint256 _sharesRequestedToBurn, + uint256 _preCLValidators, + uint256 _postCLValidators + ) external view {} + + function checkWithdrawalQueueOracleReport( + uint256[] calldata _withdrawalFinalizationBatches, + uint256 _reportTimestamp + ) external view {} + + function checkSimulatedShareRate( + uint256 _postTotalPooledEther, + uint256 _postTotalShares, + uint256 _etherLockedOnWithdrawalQueue, + uint256 _sharesBurntDueToWithdrawals, + uint256 _simulatedShareRate + ) external view {} + + function smoothenTokenRebase( + uint256, + uint256, + uint256, + uint256, + uint256 _withdrawalVaultBalance, + uint256 _elRewardsVaultBalance, + uint256, + uint256 _etherToLockForWithdrawals, + uint256 + ) + external + view + returns (uint256 withdrawals, uint256 elRewards, uint256 simulatedSharesToBurn, uint256 sharesToBurn) + { + withdrawals = _withdrawalVaultBalance; + elRewards = _elRewardsVaultBalance; + + simulatedSharesToBurn = 0; + sharesToBurn = _etherToLockForWithdrawals; + } + + function checkAccountingExtraDataListItemsCount(uint256 _extraDataListItemsCount) external view {} +} diff --git a/test/0.8.9/contracts/PausableUntil__Harness.sol b/test/0.8.9/contracts/PausableUntil__Harness.sol index fe3d05d84..a2e8f5fb0 100644 --- a/test/0.8.9/contracts/PausableUntil__Harness.sol +++ b/test/0.8.9/contracts/PausableUntil__Harness.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -7,23 +6,23 @@ pragma solidity 0.8.9; import "contracts/0.8.9/utils/PausableUntil.sol"; contract PausableUntil__Harness is PausableUntil { - function modifierWhenPaused() external view whenPaused {} + function modifierWhenPaused() external view whenPaused {} - function modifierWhenResumed() external view whenResumed {} + function modifierWhenResumed() external view whenResumed {} - function exposedPauseFor(uint256 _duration) external { - _pauseFor(_duration); - } + function harness__pauseFor(uint256 _duration) external { + _pauseFor(_duration); + } - function exposedPauseUntil(uint256 _pauseUntilInclusive) external { - _pauseUntil(_pauseUntilInclusive); - } + function harness__pauseUntil(uint256 _pauseUntilInclusive) external { + _pauseUntil(_pauseUntilInclusive); + } - function exposedResume() external { - _resume(); - } + function harness__resume() external { + _resume(); + } - function exposedSetPauseState(uint256 _resumeSince) external { - _setPausedState(_resumeSince); - } + function harness__setPauseState(uint256 _resumeSince) external { + _setPausedState(_resumeSince); + } } diff --git a/test/0.8.9/contracts/Receiver__MockForWithdrawalQueueBase.sol b/test/0.8.9/contracts/Receiver__MockForWithdrawalQueueBase.sol index 8c8ed8a1f..f316d0c60 100644 --- a/test/0.8.9/contracts/Receiver__MockForWithdrawalQueueBase.sol +++ b/test/0.8.9/contracts/Receiver__MockForWithdrawalQueueBase.sol @@ -1,20 +1,18 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; contract Receiver__MockForWithdrawalQueueBase { + bool public canReceive; - bool public canReceive; - - function setCanReceive(bool _value) external { - canReceive = _value; - } + function mock__setCanReceive(bool _value) external { + canReceive = _value; + } - receive() external payable { - if (!canReceive) { - revert("RECEIVER_NOT_ACCEPT_TOKENS"); + receive() external payable { + if (!canReceive) { + revert("RECEIVER_NOT_ACCEPT_TOKENS"); + } } - } } diff --git a/test/0.8.9/contracts/oracle/MockReportProcessor.sol b/test/0.8.9/contracts/ReportProcessor__Mock.sol similarity index 89% rename from test/0.8.9/contracts/oracle/MockReportProcessor.sol rename to test/0.8.9/contracts/ReportProcessor__Mock.sol index df0a9cd60..9a2887902 100644 --- a/test/0.8.9/contracts/oracle/MockReportProcessor.sol +++ b/test/0.8.9/contracts/ReportProcessor__Mock.sol @@ -1,10 +1,11 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + pragma solidity 0.8.9; -import { IReportAsyncProcessor } from "contracts/0.8.9/oracle/HashConsensus.sol"; +import {IReportAsyncProcessor} from "contracts/0.8.9/oracle/HashConsensus.sol"; -contract MockReportProcessor is IReportAsyncProcessor { +contract ReportProcessor__Mock is IReportAsyncProcessor { uint256 internal _consensusVersion; struct SubmitReportCall { diff --git a/test/0.8.9/contracts/StETH__HarnessForWithdrawalQueue.sol b/test/0.8.9/contracts/StETH__HarnessForWithdrawalQueue.sol new file mode 100644 index 000000000..0d263f1e3 --- /dev/null +++ b/test/0.8.9/contracts/StETH__HarnessForWithdrawalQueue.sol @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +import {UnstructuredStorage} from "contracts/0.8.9/lib/UnstructuredStorage.sol"; + +interface IStETH { + function approve(address _spender, uint256 _amount) external returns (bool); + + function transferFrom(address _sender, address _recipient, uint256 _amount) external returns (bool); + + function transfer(address _recipient, uint256 _amount) external returns (bool); + + function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256); + + function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); + + function permit( + address _owner, + address _spender, + uint256 _value, + uint256 _deadline, + uint8 _v, + bytes32 _r, + bytes32 _s + ) external; +} + +contract StETH__HarnessForWithdrawalQueue is IStETH { + using UnstructuredStorage for bytes32; + + uint256 internal constant INFINITE_ALLOWANCE = ~uint256(0); + + uint256 public totalPooledEther; + uint256 public totalShares; + + bytes32 internal constant TOTAL_SHARES_POSITION = + 0xe3b4b636e601189b5f4c6742edf2538ac12bb61ed03e6da26949d69838fa447e; + + mapping(address => uint256) private shares; + + mapping(address => mapping(address => uint256)) private allowances; + + bool internal isSignatureValid = true; + + // StETH::TransferShares + event TransferShares(address indexed from, address indexed to, uint256 sharesValue); + + // openzeppelin-solidity/contracts/token/ERC20/IERC20.sol (0.4.24) + event Approval(address indexed owner, address indexed spender, uint256 value); + + // openzeppelin-solidity/contracts/token/ERC20/IERC20.sol (0.4.24) + event Transfer(address indexed from, address indexed to, uint256 value); + + constructor() {} + + // StETH interface implementation + + // StETH::getSharesByPooledEth + function getSharesByPooledEth(uint256 _ethAmount) public view returns (uint256) { + return (_ethAmount * _getTotalShares()) / totalPooledEther; + } + + // StETH::getPooledEthByShares + function getPooledEthByShares(uint256 _sharesAmount) public view returns (uint256) { + return (_sharesAmount * totalPooledEther) / _getTotalShares(); + } + + // StETH::transfer + function transfer(address _recipient, uint256 _amount) external returns (bool) { + _transfer(msg.sender, _recipient, _amount); + return true; + } + + // StETH::transferFrom + function transferFrom(address _sender, address _recipient, uint256 _amount) external returns (bool) { + _spendAllowance(_sender, msg.sender, _amount); + _transfer(_sender, _recipient, _amount); + return true; + } + + // StETH::approve + function approve(address _spender, uint256 _amount) external returns (bool) { + _approve(msg.sender, _spender, _amount); + return true; + } + + // StETHPermit interface implementation + + // @dev Overrides the actual permit function to allow testing without signatures based on `isSignatureValid` flag. + // StETHPermit::permit + function permit( + address _owner, + address _spender, + uint256 _value, + uint256 _deadline, + uint8 _v, + bytes32 _r, + bytes32 _s + ) external { + require(block.timestamp <= _deadline, "DEADLINE_EXPIRED"); + require(isSignatureValid, "INVALID_SIGNATURE"); + + _approve(_owner, _spender, _value); + } + + // Exposed functions + + // StETH::_mintShares + function harness__mintShares(address _to, uint256 _sharesAmount) public returns (uint256 newTotalShares) { + require(_to != address(0), "MINT_TO_ZERO_ADDR"); + + newTotalShares = _getTotalShares() + _sharesAmount; + TOTAL_SHARES_POSITION.setStorageUint256(newTotalShares); + + shares[_to] = shares[_to] + _sharesAmount; + } + + // Mock functions + + function mock__setTotalPooledEther(uint256 _totalPooledEther) external { + totalPooledEther = _totalPooledEther; + } + + function mock__setIsSignatureValid(bool _validSignature) external { + isSignatureValid = _validSignature; + } + + // Internal functions + + // StETH::_approve + function _approve(address _owner, address _spender, uint256 _amount) internal { + require(_owner != address(0), "APPROVE_FROM_ZERO_ADDR"); + require(_spender != address(0), "APPROVE_TO_ZERO_ADDR"); + + allowances[_owner][_spender] = _amount; + emit Approval(_owner, _spender, _amount); + } + + // StETH::_getTotalShares + function _getTotalShares() internal view returns (uint256) { + return TOTAL_SHARES_POSITION.getStorageUint256(); + } + + // StETH::_transfer + function _transfer(address _sender, address _recipient, uint256 _amount) internal { + uint256 _sharesToTransfer = getSharesByPooledEth(_amount); + _transferShares(_sender, _recipient, _sharesToTransfer); + _emitTransferEvents(_sender, _recipient, _amount, _sharesToTransfer); + } + + // StETH::_transferShares + function _transferShares(address _sender, address _recipient, uint256 _sharesAmount) internal { + require(_sender != address(0), "TRANSFER_FROM_ZERO_ADDR"); + require(_recipient != address(0), "TRANSFER_TO_ZERO_ADDR"); + require(_recipient != address(this), "TRANSFER_TO_STETH_CONTRACT"); + // _whenNotStopped(); + + uint256 currentSenderShares = shares[_sender]; + require(_sharesAmount <= currentSenderShares, "BALANCE_EXCEEDED"); + + shares[_sender] = currentSenderShares - _sharesAmount; + shares[_recipient] = shares[_recipient] + _sharesAmount; + } + + // StETH::_spendAllowance + function _spendAllowance(address _owner, address _spender, uint256 _amount) internal { + uint256 currentAllowance = allowances[_owner][_spender]; + if (currentAllowance != INFINITE_ALLOWANCE) { + require(currentAllowance >= _amount, "ALLOWANCE_EXCEEDED"); + _approve(_owner, _spender, currentAllowance - _amount); + } + } + + // StETH::_emitTransferEvents + function _emitTransferEvents(address _from, address _to, uint _tokenAmount, uint256 _sharesAmount) internal { + emit Transfer(_from, _to, _tokenAmount); + emit TransferShares(_from, _to, _sharesAmount); + } +} diff --git a/test/0.8.9/contracts/StETH__MockForWithdrawalQueue.sol b/test/0.8.9/contracts/StETH__MockForWithdrawalQueue.sol deleted file mode 100644 index 23026cf5b..000000000 --- a/test/0.8.9/contracts/StETH__MockForWithdrawalQueue.sol +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.8.9; - -import {UnstructuredStorage} from "contracts/0.8.9/lib/UnstructuredStorage.sol"; - -interface IStETH { - function approve(address _spender, uint256 _amount) external returns (bool); - function transferFrom(address _sender, address _recipient, uint256 _amount) external returns (bool); - function transfer(address _recipient, uint256 _amount) external returns (bool); - - function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256); - function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); - - function permit( - address _owner, address _spender, uint256 _value, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s - ) external; -} - -contract StETH__MockForWithdrawalQueue is IStETH { - using UnstructuredStorage for bytes32; - - uint256 constant internal INFINITE_ALLOWANCE = ~uint256(0); - - uint256 public totalPooledEther; - uint256 public totalShares; - - bytes32 internal constant TOTAL_SHARES_POSITION = 0xe3b4b636e601189b5f4c6742edf2538ac12bb61ed03e6da26949d69838fa447e; - - mapping(address => uint256) private shares; - - mapping(address => mapping(address => uint256)) private allowances; - - bool internal isSignatureValid = true; - - // StETH::TransferShares - event TransferShares( - address indexed from, - address indexed to, - uint256 sharesValue - ); - - // openzeppelin-solidity/contracts/token/ERC20/IERC20.sol (0.4.24) - event Approval( - address indexed owner, - address indexed spender, - uint256 value - ); - - // openzeppelin-solidity/contracts/token/ERC20/IERC20.sol (0.4.24) - event Transfer( - address indexed from, - address indexed to, - uint256 value - ); - - constructor() {} - - // StETH interface implementation - - // StETH::getSharesByPooledEth - function getSharesByPooledEth(uint256 _ethAmount) public view returns (uint256) { - return _ethAmount * _getTotalShares() / totalPooledEther; - } - - // StETH::getPooledEthByShares - function getPooledEthByShares(uint256 _sharesAmount) public view returns (uint256) { - return _sharesAmount * totalPooledEther / _getTotalShares(); - } - - // StETH::transfer - function transfer(address _recipient, uint256 _amount) external returns (bool) { - _transfer(msg.sender, _recipient, _amount); - return true; - } - - // StETH::transferFrom - function transferFrom(address _sender, address _recipient, uint256 _amount) external returns (bool) { - _spendAllowance(_sender, msg.sender, _amount); - _transfer(_sender, _recipient, _amount); - return true; - } - - // StETH::approve - function approve(address _spender, uint256 _amount) external returns (bool) { - _approve(msg.sender, _spender, _amount); - return true; - } - - // StETHPermit interface implementation - - // @dev Overrides the actual permit function to allow testing without signatures based on `isSignatureValid` flag. - // StETHPermit::permit - function permit( - address _owner, address _spender, uint256 _value, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s - ) external { - require(block.timestamp <= _deadline, "DEADLINE_EXPIRED"); - require(isSignatureValid, "INVALID_SIGNATURE"); - - _approve(_owner, _spender, _value); - } - - // Exposed functions - - // StETH::_mintShares - function exposedMintShares(address _to, uint256 _sharesAmount) public returns (uint256 newTotalShares) { - require(_to != address(0), "MINT_TO_ZERO_ADDR"); - - newTotalShares = _getTotalShares() + _sharesAmount; - TOTAL_SHARES_POSITION.setStorageUint256(newTotalShares); - - shares[_to] = shares[_to] + _sharesAmount; - } - - // Mock functions - - function mockSetTotalPooledEther(uint256 _totalPooledEther) external { - totalPooledEther = _totalPooledEther; - } - - // Workarounds - - function workaroundSetIsSignatureValid(bool _validSignature) external { - isSignatureValid = _validSignature; - } - - // Internal functions - - // StETH::_approve - function _approve(address _owner, address _spender, uint256 _amount) internal { - require(_owner != address(0), "APPROVE_FROM_ZERO_ADDR"); - require(_spender != address(0), "APPROVE_TO_ZERO_ADDR"); - - allowances[_owner][_spender] = _amount; - emit Approval(_owner, _spender, _amount); - } - - // StETH::_getTotalShares - function _getTotalShares() internal view returns (uint256) { - return TOTAL_SHARES_POSITION.getStorageUint256(); - } - - // StETH::_transfer - function _transfer(address _sender, address _recipient, uint256 _amount) internal { - uint256 _sharesToTransfer = getSharesByPooledEth(_amount); - _transferShares(_sender, _recipient, _sharesToTransfer); - _emitTransferEvents(_sender, _recipient, _amount, _sharesToTransfer); - } - - // StETH::_transferShares - function _transferShares(address _sender, address _recipient, uint256 _sharesAmount) internal { - require(_sender != address(0), "TRANSFER_FROM_ZERO_ADDR"); - require(_recipient != address(0), "TRANSFER_TO_ZERO_ADDR"); - require(_recipient != address(this), "TRANSFER_TO_STETH_CONTRACT"); - // _whenNotStopped(); - - uint256 currentSenderShares = shares[_sender]; - require(_sharesAmount <= currentSenderShares, "BALANCE_EXCEEDED"); - - shares[_sender] = currentSenderShares - _sharesAmount; - shares[_recipient] = shares[_recipient] + _sharesAmount; - } - - // StETH::_spendAllowance - function _spendAllowance(address _owner, address _spender, uint256 _amount) internal { - uint256 currentAllowance = allowances[_owner][_spender]; - if (currentAllowance != INFINITE_ALLOWANCE) { - require(currentAllowance >= _amount, "ALLOWANCE_EXCEEDED"); - _approve(_owner, _spender, currentAllowance - _amount); - } - } - - // StETH::_emitTransferEvents - function _emitTransferEvents(address _from, address _to, uint _tokenAmount, uint256 _sharesAmount) internal { - emit Transfer(_from, _to, _tokenAmount); - emit TransferShares(_from, _to, _sharesAmount); - } -} diff --git a/test/0.8.9/contracts/StakingModule__Mock.sol b/test/0.8.9/contracts/StakingModule__Mock.sol index d870a7422..07589c5f5 100644 --- a/test/0.8.9/contracts/StakingModule__Mock.sol +++ b/test/0.8.9/contracts/StakingModule__Mock.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -7,239 +6,242 @@ pragma solidity 0.8.9; import {IStakingModule} from "contracts/0.8.9/interfaces/IStakingModule.sol"; contract StakingModule__Mock is IStakingModule { - event Mock__TargetValidatorsLimitsUpdated(uint256 _nodeOperatorId, bool _isTargetLimitActive, uint256 _targetLimit); - event Mock__RefundedValidatorsCountUpdated(uint256 _nodeOperatorId, uint256 _refundedValidatorsCount); - event Mock__OnRewardsMinted(uint256 _totalShares); - event Mock__ExitedValidatorsCountUpdated(bytes _nodeOperatorIds, bytes _stuckValidatorsCounts); - - function getType() external view returns (bytes32) { - return keccak256(abi.encodePacked("staking.module")); - } - - uint256 private totalExitedValidators__mocked; - uint256 private totalDepositedValidators__mocked; - uint256 private depositableValidatorsCount__mocked; - - function getStakingModuleSummary() - external - view - returns (uint256 totalExitedValidators, uint256 totalDepositedValidators, uint256 depositableValidatorsCount) - { - totalExitedValidators = totalExitedValidators__mocked; - totalDepositedValidators = totalDepositedValidators__mocked; - depositableValidatorsCount = depositableValidatorsCount__mocked; - } - - function mock__getStakingModuleSummary( - uint256 totalExitedValidators, - uint256 totalDepositedValidators, - uint256 depositableValidatorsCount - ) external { - totalExitedValidators__mocked = totalExitedValidators; - totalDepositedValidators__mocked = totalDepositedValidators; - depositableValidatorsCount__mocked = depositableValidatorsCount; - } - - bool private nodeOperatorIsTargetLimitActive__mocked; - uint256 private nodeOperatorTargetValidatorsCount__mocked; - uint256 private nodeOperatorStuckValidatorsCount__mocked; - uint256 private nodeOperatorRefundedValidatorsCount__mocked; - uint256 private nodeOperatorStuckPenaltyEndTimestamp__mocked; - uint256 private nodeOperatorNodeOperatorTotalExitedValidators__mocked; - uint256 private nodeOperatorNodeOperatorTotalDepositedValidators__mocked; - uint256 private nodeOperatorNodeOperatorDepositableValidatorsCount__mocked; - - function getNodeOperatorSummary( - uint256 _nodeOperatorId - ) - external - view - returns ( - bool isTargetLimitActive, - uint256 targetValidatorsCount, - uint256 stuckValidatorsCount, - uint256 refundedValidatorsCount, - uint256 stuckPenaltyEndTimestamp, - uint256 totalExitedValidators, - uint256 totalDepositedValidators, - uint256 depositableValidatorsCount + event Mock__TargetValidatorsLimitsUpdated(uint256 _nodeOperatorId, bool _isTargetLimitActive, uint256 _targetLimit); + event Mock__RefundedValidatorsCountUpdated(uint256 _nodeOperatorId, uint256 _refundedValidatorsCount); + event Mock__OnRewardsMinted(uint256 _totalShares); + event Mock__ExitedValidatorsCountUpdated(bytes _nodeOperatorIds, bytes _stuckValidatorsCounts); + + function getType() external view returns (bytes32) { + return keccak256(abi.encodePacked("staking.module")); + } + + uint256 private totalExitedValidators__mocked; + uint256 private totalDepositedValidators__mocked; + uint256 private depositableValidatorsCount__mocked; + + function getStakingModuleSummary() + external + view + returns (uint256 totalExitedValidators, uint256 totalDepositedValidators, uint256 depositableValidatorsCount) + { + totalExitedValidators = totalExitedValidators__mocked; + totalDepositedValidators = totalDepositedValidators__mocked; + depositableValidatorsCount = depositableValidatorsCount__mocked; + } + + function mock__getStakingModuleSummary( + uint256 totalExitedValidators, + uint256 totalDepositedValidators, + uint256 depositableValidatorsCount + ) external { + totalExitedValidators__mocked = totalExitedValidators; + totalDepositedValidators__mocked = totalDepositedValidators; + depositableValidatorsCount__mocked = depositableValidatorsCount; + } + + bool private nodeOperatorIsTargetLimitActive__mocked; + uint256 private nodeOperatorTargetValidatorsCount__mocked; + uint256 private nodeOperatorStuckValidatorsCount__mocked; + uint256 private nodeOperatorRefundedValidatorsCount__mocked; + uint256 private nodeOperatorStuckPenaltyEndTimestamp__mocked; + uint256 private nodeOperatorNodeOperatorTotalExitedValidators__mocked; + uint256 private nodeOperatorNodeOperatorTotalDepositedValidators__mocked; + uint256 private nodeOperatorNodeOperatorDepositableValidatorsCount__mocked; + + function getNodeOperatorSummary( + uint256 _nodeOperatorId ) - { - isTargetLimitActive = nodeOperatorIsTargetLimitActive__mocked; - targetValidatorsCount = nodeOperatorTargetValidatorsCount__mocked; - stuckValidatorsCount = nodeOperatorStuckValidatorsCount__mocked; - refundedValidatorsCount = nodeOperatorRefundedValidatorsCount__mocked; - stuckPenaltyEndTimestamp = nodeOperatorStuckPenaltyEndTimestamp__mocked; - totalExitedValidators = nodeOperatorNodeOperatorTotalExitedValidators__mocked; - totalDepositedValidators = nodeOperatorNodeOperatorTotalDepositedValidators__mocked; - depositableValidatorsCount = nodeOperatorNodeOperatorDepositableValidatorsCount__mocked; - } - - function mock__getNodeOperatorSummary( - bool isTargetLimitActive, - uint256 targetValidatorsCount, - uint256 stuckValidatorsCount, - uint256 refundedValidatorsCount, - uint256 stuckPenaltyEndTimestamp, - uint256 totalExitedValidators, - uint256 totalDepositedValidators, - uint256 depositableValidatorsCount - ) external { - nodeOperatorIsTargetLimitActive__mocked = isTargetLimitActive; - nodeOperatorTargetValidatorsCount__mocked = targetValidatorsCount; - nodeOperatorStuckValidatorsCount__mocked = stuckValidatorsCount; - nodeOperatorRefundedValidatorsCount__mocked = refundedValidatorsCount; - nodeOperatorStuckPenaltyEndTimestamp__mocked = stuckPenaltyEndTimestamp; - nodeOperatorNodeOperatorTotalExitedValidators__mocked = totalExitedValidators; - nodeOperatorNodeOperatorTotalDepositedValidators__mocked = totalDepositedValidators; - nodeOperatorNodeOperatorDepositableValidatorsCount__mocked = depositableValidatorsCount; - } - - uint256 private nonce; - - function getNonce() external view returns (uint256) { - return nonce; - } - - function mock__getNonce(uint256 newNonce) external { - nonce = newNonce; - } - - uint256 private nodeOperatorsCount__mocked; - uint256 private activeNodeOperatorsCount__mocked; - - function getNodeOperatorsCount() external view returns (uint256) { - return nodeOperatorsCount__mocked; - } - - function getActiveNodeOperatorsCount() external view returns (uint256) { - return activeNodeOperatorsCount__mocked; - } - - function mock__nodeOperatorsCount(uint256 total, uint256 active) external { - nodeOperatorsCount__mocked = total; - activeNodeOperatorsCount__mocked = active; - } - - function getNodeOperatorIsActive(uint256 _nodeOperatorId) external view returns (bool) { - return true; - } - - uint256[] private nodeOperatorsIds__mocked; - - function getNodeOperatorIds( - uint256 _offset, - uint256 _limit - ) external view returns (uint256[] memory nodeOperatorIds) { - return nodeOperatorsIds__mocked; - } - - function mock__getNodeOperatorIds(uint256[] calldata nodeOperatorsIds) external { - nodeOperatorsIds__mocked = nodeOperatorsIds; - } - - bool private onRewardsMintedShouldRevert = false; - bool private onRewardsMintedShouldRunOutGas = false; - - function onRewardsMinted(uint256 _totalShares) external { - require(!onRewardsMintedShouldRevert, "revert reason"); - - if (onRewardsMintedShouldRunOutGas) { - revert(); - } - - emit Mock__OnRewardsMinted(_totalShares); - } - - function mock__revertOnRewardsMinted(bool shouldRevert, bool shoudRunOutOfGas) external { - onRewardsMintedShouldRevert = shouldRevert; - onRewardsMintedShouldRunOutGas = shoudRunOutOfGas; - } - - event Mock__StuckValidatorsCountUpdated(bytes _nodeOperatorIds, bytes _stuckValidatorsCounts); - - function updateStuckValidatorsCount(bytes calldata _nodeOperatorIds, bytes calldata _stuckValidatorsCounts) external { - emit Mock__StuckValidatorsCountUpdated(_nodeOperatorIds, _stuckValidatorsCounts); - } - - function updateExitedValidatorsCount( - bytes calldata _nodeOperatorIds, - bytes calldata _stuckValidatorsCounts - ) external { - emit Mock__ExitedValidatorsCountUpdated(_nodeOperatorIds, _stuckValidatorsCounts); - } - - function updateRefundedValidatorsCount(uint256 _nodeOperatorId, uint256 _refundedValidatorsCount) external { - emit Mock__RefundedValidatorsCountUpdated(_nodeOperatorId, _refundedValidatorsCount); - } - - function updateTargetValidatorsLimits( - uint256 _nodeOperatorId, - bool _isTargetLimitActive, - uint256 _targetLimit - ) external { - emit Mock__TargetValidatorsLimitsUpdated(_nodeOperatorId, _isTargetLimitActive, _targetLimit); - } - - event Mock__ValidatorsCountUnsafelyUpdated( - uint256 _nodeOperatorId, - uint256 _exitedValidatorsCount, - uint256 _stuckValidatorsCoun - ); + external + view + returns ( + bool isTargetLimitActive, + uint256 targetValidatorsCount, + uint256 stuckValidatorsCount, + uint256 refundedValidatorsCount, + uint256 stuckPenaltyEndTimestamp, + uint256 totalExitedValidators, + uint256 totalDepositedValidators, + uint256 depositableValidatorsCount + ) + { + isTargetLimitActive = nodeOperatorIsTargetLimitActive__mocked; + targetValidatorsCount = nodeOperatorTargetValidatorsCount__mocked; + stuckValidatorsCount = nodeOperatorStuckValidatorsCount__mocked; + refundedValidatorsCount = nodeOperatorRefundedValidatorsCount__mocked; + stuckPenaltyEndTimestamp = nodeOperatorStuckPenaltyEndTimestamp__mocked; + totalExitedValidators = nodeOperatorNodeOperatorTotalExitedValidators__mocked; + totalDepositedValidators = nodeOperatorNodeOperatorTotalDepositedValidators__mocked; + depositableValidatorsCount = nodeOperatorNodeOperatorDepositableValidatorsCount__mocked; + } - function unsafeUpdateValidatorsCount( - uint256 _nodeOperatorId, - uint256 _exitedValidatorsCount, - uint256 _stuckValidatorsCount - ) external { - emit Mock__ValidatorsCountUnsafelyUpdated(_nodeOperatorId, _exitedValidatorsCount, _stuckValidatorsCount); - } + function mock__getNodeOperatorSummary( + bool isTargetLimitActive, + uint256 targetValidatorsCount, + uint256 stuckValidatorsCount, + uint256 refundedValidatorsCount, + uint256 stuckPenaltyEndTimestamp, + uint256 totalExitedValidators, + uint256 totalDepositedValidators, + uint256 depositableValidatorsCount + ) external { + nodeOperatorIsTargetLimitActive__mocked = isTargetLimitActive; + nodeOperatorTargetValidatorsCount__mocked = targetValidatorsCount; + nodeOperatorStuckValidatorsCount__mocked = stuckValidatorsCount; + nodeOperatorRefundedValidatorsCount__mocked = refundedValidatorsCount; + nodeOperatorStuckPenaltyEndTimestamp__mocked = stuckPenaltyEndTimestamp; + nodeOperatorNodeOperatorTotalExitedValidators__mocked = totalExitedValidators; + nodeOperatorNodeOperatorTotalDepositedValidators__mocked = totalDepositedValidators; + nodeOperatorNodeOperatorDepositableValidatorsCount__mocked = depositableValidatorsCount; + } - function obtainDepositData( - uint256 _depositsCount, - bytes calldata _depositCalldata - ) external returns (bytes memory publicKeys, bytes memory signatures) { - publicKeys = new bytes(48 * _depositsCount); - signatures = new bytes(96 * _depositsCount); - } + uint256 private nonce; - event Mock__onExitedAndStuckValidatorsCountsUpdated(); + function getNonce() external view returns (uint256) { + return nonce; + } - bool private onExitedAndStuckValidatorsCountsUpdatedShouldRevert = false; - bool private onExitedAndStuckValidatorsCountsUpdatedShouldRunOutGas = false; + function mock__getNonce(uint256 newNonce) external { + nonce = newNonce; + } - function onExitedAndStuckValidatorsCountsUpdated() external { - require(!onExitedAndStuckValidatorsCountsUpdatedShouldRevert, "revert reason"); + uint256 private nodeOperatorsCount__mocked; + uint256 private activeNodeOperatorsCount__mocked; - if (onExitedAndStuckValidatorsCountsUpdatedShouldRunOutGas) { - revert(); + function getNodeOperatorsCount() external view returns (uint256) { + return nodeOperatorsCount__mocked; } - emit Mock__onExitedAndStuckValidatorsCountsUpdated(); - } + function getActiveNodeOperatorsCount() external view returns (uint256) { + return activeNodeOperatorsCount__mocked; + } - function mock__onExitedAndStuckValidatorsCountsUpdated(bool shouldRevert, bool shouldRunOutGas) external { - onExitedAndStuckValidatorsCountsUpdatedShouldRevert = shouldRevert; - onExitedAndStuckValidatorsCountsUpdatedShouldRunOutGas = shouldRunOutGas; - } + function mock__nodeOperatorsCount(uint256 total, uint256 active) external { + nodeOperatorsCount__mocked = total; + activeNodeOperatorsCount__mocked = active; + } - event Mock__WithdrawalCredentialsChanged(); + function getNodeOperatorIsActive(uint256 _nodeOperatorId) external view returns (bool) { + return true; + } + + uint256[] private nodeOperatorsIds__mocked; + + function getNodeOperatorIds( + uint256 _offset, + uint256 _limit + ) external view returns (uint256[] memory nodeOperatorIds) { + return nodeOperatorsIds__mocked; + } + + function mock__getNodeOperatorIds(uint256[] calldata nodeOperatorsIds) external { + nodeOperatorsIds__mocked = nodeOperatorsIds; + } - bool private onWithdrawalCredentialsChangedShouldRevert = false; - bool private onWithdrawalCredentialsChangedShouldRunOutGas = false; + bool private onRewardsMintedShouldRevert = false; + bool private onRewardsMintedShouldRunOutGas = false; - function onWithdrawalCredentialsChanged() external { - require(!onWithdrawalCredentialsChangedShouldRevert, "revert reason"); + function onRewardsMinted(uint256 _totalShares) external { + require(!onRewardsMintedShouldRevert, "revert reason"); - if (onWithdrawalCredentialsChangedShouldRunOutGas) { - revert(); + if (onRewardsMintedShouldRunOutGas) { + revert(); + } + + emit Mock__OnRewardsMinted(_totalShares); + } + + function mock__revertOnRewardsMinted(bool shouldRevert, bool shoudRunOutOfGas) external { + onRewardsMintedShouldRevert = shouldRevert; + onRewardsMintedShouldRunOutGas = shoudRunOutOfGas; } - emit Mock__WithdrawalCredentialsChanged(); - } + event Mock__StuckValidatorsCountUpdated(bytes _nodeOperatorIds, bytes _stuckValidatorsCounts); - function mock__onWithdrawalCredentialsChanged(bool shouldRevert, bool shouldRunOutGas) external { - onWithdrawalCredentialsChangedShouldRevert = shouldRevert; - onWithdrawalCredentialsChangedShouldRunOutGas = shouldRunOutGas; - } + function updateStuckValidatorsCount( + bytes calldata _nodeOperatorIds, + bytes calldata _stuckValidatorsCounts + ) external { + emit Mock__StuckValidatorsCountUpdated(_nodeOperatorIds, _stuckValidatorsCounts); + } + + function updateExitedValidatorsCount( + bytes calldata _nodeOperatorIds, + bytes calldata _stuckValidatorsCounts + ) external { + emit Mock__ExitedValidatorsCountUpdated(_nodeOperatorIds, _stuckValidatorsCounts); + } + + function updateRefundedValidatorsCount(uint256 _nodeOperatorId, uint256 _refundedValidatorsCount) external { + emit Mock__RefundedValidatorsCountUpdated(_nodeOperatorId, _refundedValidatorsCount); + } + + function updateTargetValidatorsLimits( + uint256 _nodeOperatorId, + bool _isTargetLimitActive, + uint256 _targetLimit + ) external { + emit Mock__TargetValidatorsLimitsUpdated(_nodeOperatorId, _isTargetLimitActive, _targetLimit); + } + + event Mock__ValidatorsCountUnsafelyUpdated( + uint256 _nodeOperatorId, + uint256 _exitedValidatorsCount, + uint256 _stuckValidatorsCoun + ); + + function unsafeUpdateValidatorsCount( + uint256 _nodeOperatorId, + uint256 _exitedValidatorsCount, + uint256 _stuckValidatorsCount + ) external { + emit Mock__ValidatorsCountUnsafelyUpdated(_nodeOperatorId, _exitedValidatorsCount, _stuckValidatorsCount); + } + + function obtainDepositData( + uint256 _depositsCount, + bytes calldata _depositCalldata + ) external returns (bytes memory publicKeys, bytes memory signatures) { + publicKeys = new bytes(48 * _depositsCount); + signatures = new bytes(96 * _depositsCount); + } + + event Mock__onExitedAndStuckValidatorsCountsUpdated(); + + bool private onExitedAndStuckValidatorsCountsUpdatedShouldRevert = false; + bool private onExitedAndStuckValidatorsCountsUpdatedShouldRunOutGas = false; + + function onExitedAndStuckValidatorsCountsUpdated() external { + require(!onExitedAndStuckValidatorsCountsUpdatedShouldRevert, "revert reason"); + + if (onExitedAndStuckValidatorsCountsUpdatedShouldRunOutGas) { + revert(); + } + + emit Mock__onExitedAndStuckValidatorsCountsUpdated(); + } + + function mock__onExitedAndStuckValidatorsCountsUpdated(bool shouldRevert, bool shouldRunOutGas) external { + onExitedAndStuckValidatorsCountsUpdatedShouldRevert = shouldRevert; + onExitedAndStuckValidatorsCountsUpdatedShouldRunOutGas = shouldRunOutGas; + } + + event Mock__WithdrawalCredentialsChanged(); + + bool private onWithdrawalCredentialsChangedShouldRevert = false; + bool private onWithdrawalCredentialsChangedShouldRunOutGas = false; + + function onWithdrawalCredentialsChanged() external { + require(!onWithdrawalCredentialsChangedShouldRevert, "revert reason"); + + if (onWithdrawalCredentialsChangedShouldRunOutGas) { + revert(); + } + + emit Mock__WithdrawalCredentialsChanged(); + } + + function mock__onWithdrawalCredentialsChanged(bool shouldRevert, bool shouldRunOutGas) external { + onWithdrawalCredentialsChangedShouldRevert = shouldRevert; + onWithdrawalCredentialsChangedShouldRunOutGas = shouldRunOutGas; + } } diff --git a/test/0.8.9/contracts/oracle/MockStakingRouterForAccountingOracle.sol b/test/0.8.9/contracts/StakingRouter__MockForAccountingOracle.sol similarity index 78% rename from test/0.8.9/contracts/oracle/MockStakingRouterForAccountingOracle.sol rename to test/0.8.9/contracts/StakingRouter__MockForAccountingOracle.sol index ef5f5f5c1..b2233b6f5 100644 --- a/test/0.8.9/contracts/oracle/MockStakingRouterForAccountingOracle.sol +++ b/test/0.8.9/contracts/StakingRouter__MockForAccountingOracle.sol @@ -1,12 +1,11 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.9; - -import { IStakingRouter } from "contracts/0.8.9/oracle/AccountingOracle.sol"; +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only +pragma solidity 0.8.9; -contract MockStakingRouterForAccountingOracle is IStakingRouter { +import {IStakingRouter} from "contracts/0.8.9/oracle/AccountingOracle.sol"; +contract StakingRouter__MockForAccountingOracle is IStakingRouter { struct UpdateExitedKeysByModuleCallData { uint256[] moduleIds; uint256[] exitedKeysCounts; @@ -28,10 +27,7 @@ contract MockStakingRouterForAccountingOracle is IStakingRouter { uint256 public totalCalls_onValidatorsCountsByNodeOperatorReportingFinished; - - function lastCall_updateExitedKeysByModule() - external view returns (UpdateExitedKeysByModuleCallData memory) - { + function lastCall_updateExitedKeysByModule() external view returns (UpdateExitedKeysByModuleCallData memory) { return _lastCall_updateExitedKeysByModule; } @@ -71,9 +67,9 @@ contract MockStakingRouterForAccountingOracle is IStakingRouter { bytes calldata nodeOperatorIds, bytes calldata exitedKeysCounts ) external { - calls_reportExitedKeysByNodeOperator.push(ReportKeysByNodeOperatorCallData( - stakingModuleId, nodeOperatorIds, exitedKeysCounts - )); + calls_reportExitedKeysByNodeOperator.push( + ReportKeysByNodeOperatorCallData(stakingModuleId, nodeOperatorIds, exitedKeysCounts) + ); } function reportStakingModuleStuckValidatorsCountByNodeOperator( @@ -81,9 +77,9 @@ contract MockStakingRouterForAccountingOracle is IStakingRouter { bytes calldata nodeOperatorIds, bytes calldata stuckKeysCounts ) external { - calls_reportStuckKeysByNodeOperator.push(ReportKeysByNodeOperatorCallData( - stakingModuleId, nodeOperatorIds, stuckKeysCounts - )); + calls_reportStuckKeysByNodeOperator.push( + ReportKeysByNodeOperatorCallData(stakingModuleId, nodeOperatorIds, stuckKeysCounts) + ); } function onValidatorsCountsByNodeOperatorReportingFinished() external { diff --git a/test/0.8.9/contracts/StakingRouterMockForDepositSecurityModule.sol b/test/0.8.9/contracts/StakingRouter__MockForDepositSecurityModule.sol similarity index 81% rename from test/0.8.9/contracts/StakingRouterMockForDepositSecurityModule.sol rename to test/0.8.9/contracts/StakingRouter__MockForDepositSecurityModule.sol index f1d1b7466..5501f79ec 100644 --- a/test/0.8.9/contracts/StakingRouterMockForDepositSecurityModule.sol +++ b/test/0.8.9/contracts/StakingRouter__MockForDepositSecurityModule.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -7,12 +6,15 @@ pragma solidity 0.8.9; import {IStakingRouter} from "contracts/0.8.9/DepositSecurityModule.sol"; import {StakingRouter} from "contracts/0.8.9/StakingRouter.sol"; - -contract StakingRouterMockForDepositSecurityModule is IStakingRouter { +contract StakingRouter__MockForDepositSecurityModule is IStakingRouter { error StakingModuleUnregistered(); event StakingModuleDeposited(uint256 maxDepositsCount, uint24 stakingModuleId, bytes depositCalldata); - event StakingModuleStatusSet(uint24 indexed stakingModuleId, StakingRouter.StakingModuleStatus status, address setBy); + event StakingModuleStatusSet( + uint24 indexed stakingModuleId, + StakingRouter.StakingModuleStatus status, + address setBy + ); StakingRouter.StakingModuleStatus private status; uint256 private stakingModuleNonce; @@ -27,7 +29,7 @@ contract StakingRouterMockForDepositSecurityModule is IStakingRouter { uint256 maxDepositsCount, uint256 stakingModuleId, bytes calldata depositCalldata - ) external whenModuleIsRegistered(stakingModuleId) payable returns (uint256 keysCount) { + ) external payable whenModuleIsRegistered(stakingModuleId) returns (uint256 keysCount) { emit StakingModuleDeposited(maxDepositsCount, uint24(stakingModuleId), depositCalldata); return maxDepositsCount; } @@ -36,19 +38,26 @@ contract StakingRouterMockForDepositSecurityModule is IStakingRouter { return _stakingModuleId == registeredStakingModuleId; } - function getStakingModuleStatus(uint256 stakingModuleId) external view whenModuleIsRegistered(stakingModuleId) returns (StakingRouter.StakingModuleStatus) { + function getStakingModuleStatus( + uint256 stakingModuleId + ) external view whenModuleIsRegistered(stakingModuleId) returns (StakingRouter.StakingModuleStatus) { return status; } function setStakingModuleStatus( - uint256 _stakingModuleId, StakingRouter.StakingModuleStatus _status + uint256 _stakingModuleId, + StakingRouter.StakingModuleStatus _status ) external whenModuleIsRegistered(_stakingModuleId) { emit StakingModuleStatusSet(uint24(_stakingModuleId), _status, msg.sender); status = _status; } function pauseStakingModule(uint256 stakingModuleId) external whenModuleIsRegistered(stakingModuleId) { - emit StakingModuleStatusSet(uint24(stakingModuleId), StakingRouter.StakingModuleStatus.DepositsPaused, msg.sender); + emit StakingModuleStatusSet( + uint24(stakingModuleId), + StakingRouter.StakingModuleStatus.DepositsPaused, + msg.sender + ); status = StakingRouter.StakingModuleStatus.DepositsPaused; } diff --git a/test/0.8.9/contracts/oracle/ValidatorsExitBusTimeTravellable.sol b/test/0.8.9/contracts/ValidatorsExitBus__Harness.sol similarity index 52% rename from test/0.8.9/contracts/oracle/ValidatorsExitBusTimeTravellable.sol rename to test/0.8.9/contracts/ValidatorsExitBus__Harness.sol index 8df9212a1..87e6cd541 100644 --- a/test/0.8.9/contracts/oracle/ValidatorsExitBusTimeTravellable.sol +++ b/test/0.8.9/contracts/ValidatorsExitBus__Harness.sol @@ -1,23 +1,23 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.9; - +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only -import { UnstructuredStorage } from "contracts/0.8.9/lib/UnstructuredStorage.sol"; -import { ValidatorsExitBusOracle } from "contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol"; +pragma solidity 0.8.9; +import {UnstructuredStorage} from "contracts/0.8.9/lib/UnstructuredStorage.sol"; +import {ValidatorsExitBusOracle} from "contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol"; interface ITimeProvider { function getTime() external view returns (uint256); } - -contract ValidatorsExitBusTimeTravellable is ValidatorsExitBusOracle, ITimeProvider { +contract ValidatorsExitBus__Harness is ValidatorsExitBusOracle, ITimeProvider { using UnstructuredStorage for bytes32; - constructor(uint256 secondsPerSlot, uint256 genesisTime, address lidoLocator) - ValidatorsExitBusOracle(secondsPerSlot, genesisTime, lidoLocator) - { + constructor( + uint256 secondsPerSlot, + uint256 genesisTime, + address lidoLocator + ) ValidatorsExitBusOracle(secondsPerSlot, genesisTime, lidoLocator) { // allow usage without a proxy for tests CONTRACT_VERSION_POSITION.setStorageUint256(0); } @@ -26,7 +26,7 @@ contract ValidatorsExitBusTimeTravellable is ValidatorsExitBusOracle, ITimeProvi return _getTime(); } - function _getTime() internal override view returns (uint256) { + function _getTime() internal view override returns (uint256) { address consensus = CONSENSUS_CONTRACT_POSITION.getStorageAddress(); return ITimeProvider(consensus).getTime(); } diff --git a/test/0.8.9/contracts/Versioned__Harness089.sol b/test/0.8.9/contracts/Versioned__Harness089.sol index 7762b1eed..ce9720e6f 100644 --- a/test/0.8.9/contracts/Versioned__Harness089.sol +++ b/test/0.8.9/contracts/Versioned__Harness089.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; diff --git a/test/0.8.9/contracts/oracle/MockWithdrawalQueueForAccoutingOracle.sol b/test/0.8.9/contracts/WithdrawalQueue__MockForAccountingOracle.sol similarity index 73% rename from test/0.8.9/contracts/oracle/MockWithdrawalQueueForAccoutingOracle.sol rename to test/0.8.9/contracts/WithdrawalQueue__MockForAccountingOracle.sol index ea257a649..71b92cc4c 100644 --- a/test/0.8.9/contracts/oracle/MockWithdrawalQueueForAccoutingOracle.sol +++ b/test/0.8.9/contracts/WithdrawalQueue__MockForAccountingOracle.sol @@ -1,10 +1,11 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + pragma solidity 0.8.9; -import { IWithdrawalQueue } from "contracts/0.8.9/oracle/AccountingOracle.sol"; +import {IWithdrawalQueue} from "contracts/0.8.9/oracle/AccountingOracle.sol"; -contract MockWithdrawalQueueForAccountingOracle is IWithdrawalQueue { +contract WithdrawalQueue__MockForAccountingOracle is IWithdrawalQueue { struct OnOracleReportCallData { bool isBunkerMode; uint256 prevReportTimestamp; diff --git a/test/0.8.9/contracts/WithdrawalQueue__MockForOracleSanityChecker.sol b/test/0.8.9/contracts/WithdrawalQueue__MockForOracleSanityChecker.sol new file mode 100644 index 000000000..92f3585d0 --- /dev/null +++ b/test/0.8.9/contracts/WithdrawalQueue__MockForOracleSanityChecker.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + +pragma solidity 0.8.9; + +import {IWithdrawalQueue} from "contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol"; + +contract WithdrawalQueue__MockForOracleSanityChecker is IWithdrawalQueue { + mapping(uint256 => uint256) private _timestamps; + + function setRequestTimestamp(uint256 _requestId, uint256 _timestamp) external { + _timestamps[_requestId] = _timestamp; + } + + function getWithdrawalStatus( + uint256[] calldata _requestIds + ) external view returns (WithdrawalRequestStatus[] memory statuses) { + statuses = new WithdrawalRequestStatus[](_requestIds.length); + for (uint256 i; i < _requestIds.length; ++i) { + statuses[i].timestamp = _timestamps[_requestIds[i]]; + } + } +} diff --git a/test/0.8.9/contracts/WithdrawalsQueueBase__Harness.sol b/test/0.8.9/contracts/WithdrawalsQueueBase__Harness.sol index 08d224145..fa17a1e11 100644 --- a/test/0.8.9/contracts/WithdrawalsQueueBase__Harness.sol +++ b/test/0.8.9/contracts/WithdrawalsQueueBase__Harness.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -7,73 +6,86 @@ pragma solidity 0.8.9; import {WithdrawalQueueBase} from "contracts/0.8.9/WithdrawalQueueBase.sol"; contract WithdrawalsQueueBase__Harness is WithdrawalQueueBase { - - constructor() { - _initializeQueue(); - } - - function exposedEnqueue(uint128 _amountOfStETH, uint128 _amountOfShares, address _owner) external returns (uint256 requestId) { - return _enqueue(_amountOfStETH, _amountOfShares, _owner); - } - - function exposedFinalize(uint256 _lastRequestIdToBeFinalized, uint256 _amountOfETH, uint256 _maxShareRate) external { - _finalize(_lastRequestIdToBeFinalized, _amountOfETH, _maxShareRate); - } - - function exposedGetStatus(uint256 _requestId) external view returns (WithdrawalRequestStatus memory status) { - return _getStatus(_requestId); - } - - function exposedFindCheckpointHint(uint256 _requestId, uint256 _start, uint256 _end) external view returns (uint256) { - return _findCheckpointHint(_requestId, _start, _end); - } - - function exposedSendValue(address _recipient, uint256 _amount) external { - return _sendValue(_recipient, _amount); - } - - function exposedCalcBatch(WithdrawalRequest memory _preStartRequest, WithdrawalRequest memory _endRequest) external pure returns (uint256 shareRate, uint256 stETH, uint256 shares) - { - return _calcBatch(_preStartRequest, _endRequest); - } - - function exposedClaim(uint256 _requestId, uint256 _hint, address _recipient) external { - return _claim(_requestId, _hint, _recipient); - } - - function exposedCalculateClaimableEther(uint256 _requestId, uint256 _hint) external view returns (uint256) { - WithdrawalRequest storage request = _getQueue()[_requestId]; - - return _calculateClaimableEther(request, _requestId, _hint); - } - - function exposedInitializeQueue() external { - _initializeQueue(); - } - - // Internal functions - - function exposedGetLastReportTimestamp() external view returns (uint256) { - return _getLastReportTimestamp(); - } - - function exposedSetLastRequestId(uint256 _requestId) external { - _setLastRequestId(_requestId); - } - - function exposedSetLastFinalizedRequestId(uint256 _requestId) external { - _setLastFinalizedRequestId(_requestId); - } - - function exposedSetLastCheckpointIndex(uint256 _index) external { - _setLastCheckpointIndex(_index); - } - - function exposedSetLockedEtherAmount(uint256 _lockedEtherAmount) external { - _setLockedEtherAmount(_lockedEtherAmount); - } - - function exposedSetLastReportTimestamp(uint256 _timestamp) external { - _setLastReportTimestamp(_timestamp); - } + constructor() { + _initializeQueue(); + } + + function harness__enqueue( + uint128 _amountOfStETH, + uint128 _amountOfShares, + address _owner + ) external returns (uint256 requestId) { + return _enqueue(_amountOfStETH, _amountOfShares, _owner); + } + + function harness__finalize( + uint256 _lastRequestIdToBeFinalized, + uint256 _amountOfETH, + uint256 _maxShareRate + ) external { + _finalize(_lastRequestIdToBeFinalized, _amountOfETH, _maxShareRate); + } + + function harness__getStatus(uint256 _requestId) external view returns (WithdrawalRequestStatus memory status) { + return _getStatus(_requestId); + } + + function harness__findCheckpointHint( + uint256 _requestId, + uint256 _start, + uint256 _end + ) external view returns (uint256) { + return _findCheckpointHint(_requestId, _start, _end); + } + + function harness__sendValue(address _recipient, uint256 _amount) external { + return _sendValue(_recipient, _amount); + } + + function harness__calcBatch( + WithdrawalRequest memory _preStartRequest, + WithdrawalRequest memory _endRequest + ) external pure returns (uint256 shareRate, uint256 stETH, uint256 shares) { + return _calcBatch(_preStartRequest, _endRequest); + } + + function harness__claim(uint256 _requestId, uint256 _hint, address _recipient) external { + return _claim(_requestId, _hint, _recipient); + } + + function harness__calculateClaimableEther(uint256 _requestId, uint256 _hint) external view returns (uint256) { + WithdrawalRequest storage request = _getQueue()[_requestId]; + + return _calculateClaimableEther(request, _requestId, _hint); + } + + function harness__initializeQueue() external { + _initializeQueue(); + } + + // Internal functions + + function harness__getLastReportTimestamp() external view returns (uint256) { + return _getLastReportTimestamp(); + } + + function harness__setLastRequestId(uint256 _requestId) external { + _setLastRequestId(_requestId); + } + + function harness__setLastFinalizedRequestId(uint256 _requestId) external { + _setLastFinalizedRequestId(_requestId); + } + + function harness__setLastCheckpointIndex(uint256 _index) external { + _setLastCheckpointIndex(_index); + } + + function harness__setLockedEtherAmount(uint256 _lockedEtherAmount) external { + _setLockedEtherAmount(_lockedEtherAmount); + } + + function harness__setLastReportTimestamp(uint256 _timestamp) external { + _setLastReportTimestamp(_timestamp); + } } diff --git a/test/0.8.9/contracts/WithdrawalsQueue__Harness.sol b/test/0.8.9/contracts/WithdrawalsQueue__Harness.sol index 31650ec5f..fbe24dd79 100644 --- a/test/0.8.9/contracts/WithdrawalsQueue__Harness.sol +++ b/test/0.8.9/contracts/WithdrawalsQueue__Harness.sol @@ -1,35 +1,37 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; -import "contracts/0.8.9/WithdrawalQueue.sol"; +import {WithdrawalQueue, IWstETH} from "contracts/0.8.9/WithdrawalQueue.sol"; contract WithdrawalsQueue__Harness is WithdrawalQueue { - - event Mock__Transfer(address indexed from, address indexed to, uint256 requestId); - - constructor(address _wstETH) WithdrawalQueue(IWstETH(_wstETH)) {} - - function exposedEnqueue(uint128 _amountOfStETH, uint128 _amountOfShares, address _owner) external returns (uint256 requestId) { - return _enqueue(_amountOfStETH, _amountOfShares, _owner); - } - - function exposedClaim(uint256 _requestId, uint256 _hint, address _recipient) external { - return _claim(_requestId, _hint, _recipient); - } - - function exposedGetClaimableEther(uint256 _requestId, uint256 _hint) external view returns (uint256) { - return _getClaimableEther(_requestId, _hint); - } - - function exposedFinalize(uint256 _lastRequestIdToBeFinalized, uint256 _maxShareRate) external payable { - _finalize(_lastRequestIdToBeFinalized, msg.value, _maxShareRate); - } - - // Implementing the virtual function from WithdrawalQueue - function _emitTransfer(address _from, address _to, uint256 _requestId) internal override { - emit Mock__Transfer(_from, _to, _requestId); - } + event Mock__Transfer(address indexed from, address indexed to, uint256 requestId); + + constructor(address _wstETH) WithdrawalQueue(IWstETH(_wstETH)) {} + + function harness__enqueue( + uint128 _amountOfStETH, + uint128 _amountOfShares, + address _owner + ) external returns (uint256 requestId) { + return _enqueue(_amountOfStETH, _amountOfShares, _owner); + } + + function harness__claim(uint256 _requestId, uint256 _hint, address _recipient) external { + return _claim(_requestId, _hint, _recipient); + } + + function harness__getClaimableEther(uint256 _requestId, uint256 _hint) external view returns (uint256) { + return _getClaimableEther(_requestId, _hint); + } + + function harness__finalize(uint256 _lastRequestIdToBeFinalized, uint256 _maxShareRate) external payable { + _finalize(_lastRequestIdToBeFinalized, msg.value, _maxShareRate); + } + + // Implementing the virtual function from WithdrawalQueue + function _emitTransfer(address _from, address _to, uint256 _requestId) internal override { + emit Mock__Transfer(_from, _to, _requestId); + } } diff --git a/test/0.6.12/contracts/WstETH__MockForWithdrawalQueueDeploy.sol b/test/0.8.9/contracts/WstETH__HarnessForWithdrawalQueueDeploy.sol similarity index 55% rename from test/0.6.12/contracts/WstETH__MockForWithdrawalQueueDeploy.sol rename to test/0.8.9/contracts/WstETH__HarnessForWithdrawalQueueDeploy.sol index c6b0a6fc2..329d93f5b 100644 --- a/test/0.6.12/contracts/WstETH__MockForWithdrawalQueueDeploy.sol +++ b/test/0.8.9/contracts/WstETH__HarnessForWithdrawalQueueDeploy.sol @@ -1,21 +1,19 @@ -// SPDX-FileCopyrightText: 2021 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.6.12; // latest available for using OZ -import "contracts/0.6.12/WstETH.sol"; -import "contracts/0.6.12/interfaces/IStETH.sol"; +import {WstETH} from "contracts/0.6.12/WstETH.sol"; +import {IStETH} from "contracts/0.6.12/interfaces/IStETH.sol"; - -contract WstETH__MockForWithdrawalQueueDeploy is WstETH { +contract WstETH__HarnessForWithdrawalQueueDeploy is WstETH { constructor(IStETH _StETH) public WstETH(_StETH) {} - function mint(address recipient, uint256 amount) public { + function harness__mint(address recipient, uint256 amount) public { _mint(recipient, amount); } - function getChainId() external view returns (uint256 chainId) { + function mock__getChainId() external view returns (uint256 chainId) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 // solhint-disable-next-line no-inline-assembly assembly { diff --git a/test/0.8.9/contracts/WstETH__MockForWithdrawalQueue.sol b/test/0.8.9/contracts/WstETH__MockForWithdrawalQueue.sol index f16283244..7f7823ffa 100644 --- a/test/0.8.9/contracts/WstETH__MockForWithdrawalQueue.sol +++ b/test/0.8.9/contracts/WstETH__MockForWithdrawalQueue.sol @@ -1,135 +1,142 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; -import {Counters__GeneralMock} from "test/0.8.9/contracts/Counters__GeneralMock.sol"; -import {IStETH} from "test/0.8.9/contracts/StETH__MockForWithdrawalQueue.sol"; +import {Counters__Mock} from "test/0.8.9/contracts/Counters__Mock.sol"; +import {IStETH} from "test/0.8.9/contracts/StETH__HarnessForWithdrawalQueue.sol"; contract WstETH__MockForWithdrawalQueue { - using Counters__GeneralMock for Counters__GeneralMock.Counter; + using Counters__Mock for Counters__Mock.Counter; - IStETH public stETH; + IStETH public stETH; - mapping (address => uint256) private _balances; + mapping(address => uint256) private _balances; - mapping (address => mapping (address => uint256)) private _allowances; + mapping(address => mapping(address => uint256)) private _allowances; - uint256 private _totalSupply; + uint256 private _totalSupply; - mapping (address => Counters__GeneralMock.Counter) private _nonces; + mapping(address => Counters__Mock.Counter) private _nonces; - bool internal isSignatureValid = true; + bool internal isSignatureValid = true; - constructor(IStETH _stETH) { - stETH = _stETH; - } + constructor(IStETH _stETH) { + stETH = _stETH; + } - // openzeppelin/contracts/token/ERC20/IERC20.sol - event Transfer(address indexed from, address indexed to, uint256 value); + // openzeppelin/contracts/token/ERC20/IERC20.sol + event Transfer(address indexed from, address indexed to, uint256 value); - // openzeppelin/contracts/token/ERC20/IERC20.sol - event Approval(address indexed owner, address indexed spender, uint256 value); + // openzeppelin/contracts/token/ERC20/IERC20.sol + event Approval(address indexed owner, address indexed spender, uint256 value); - // WstEth interface implementations + // WstEth interface implementations - // WstETH::getStETHByWstETH - function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256) { - return stETH.getPooledEthByShares(_wstETHAmount); - } + // WstETH::getStETHByWstETH + function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256) { + return stETH.getPooledEthByShares(_wstETHAmount); + } - // WstETH::unwrap - function unwrap(uint256 _wstETHAmount) external returns (uint256) { - require(_wstETHAmount > 0, "wstETH: zero amount unwrap not allowed"); - uint256 stETHAmount = stETH.getPooledEthByShares(_wstETHAmount); - _burn(msg.sender, _wstETHAmount); - stETH.transfer(msg.sender, stETHAmount); - return stETHAmount; - } - - // openzeppelin/contracts/token/ERC20/ERC20.sol - function approve(address spender, uint256 amount) public returns (bool) { - _approve(msg.sender, spender, amount); - return true; - } - - // openzeppelin/contracts/token/ERC20/ERC20.sol - function transferFrom(address sender, address recipient, uint256 amount) public virtual returns (bool) { - _transfer(sender, recipient, amount); - require(amount <= _allowances[sender][msg.sender], "ERC20: transfer amount exceeds allowance"); - _approve(sender, msg.sender, _allowances[sender][msg.sender] - amount); - return true; - } - - // @dev Overrides the actual permit function to allow for testing without signatures based on `isSignatureValid` flag. - // openzeppelin/contracts/drafts/ERC20Permit.sol - function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external { - require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); - require(isSignatureValid, "ERC20Permit: invalid signature"); - - _nonces[owner].increment(); - _approve(owner, spender, value); - } - - // Exposed functions - - // openzeppelin/contracts/token/ERC20/ERC20.sol - function exposedMint(address _recipient, uint256 _amount) public { - _mint(_recipient, _amount); - } - - // Workarounds - - function workaroundSetIsSignatureValid(bool _validSignature) external { - isSignatureValid = _validSignature; - } - - // Internal functions - - // openzeppelin/contracts/token/ERC20/ERC20.sol - function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } - - // openzeppelin/contracts/token/ERC20/ERC20.sol - function _mint(address account, uint256 amount) internal virtual { - require(account != address(0), "ERC20: mint to the zero address"); - - _beforeTokenTransfer(address(0), account, amount); - - _totalSupply = _totalSupply + amount; - _balances[account] = _balances[account] + amount; - emit Transfer(address(0), account, amount); - } - - // openzeppelin/contracts/token/ERC20/ERC20.sol - function _approve(address owner, address spender, uint256 amount) internal virtual { - require(owner != address(0), "ERC20: approve from the zero address"); - require(spender != address(0), "ERC20: approve to the zero address"); - - _allowances[owner][spender] = amount; - emit Approval(owner, spender, amount); - } - - // openzeppelin/contracts/token/ERC20/ERC20.sol - function _transfer(address sender, address recipient, uint256 amount) internal virtual { - require(sender != address(0), "ERC20: transfer from the zero address"); - require(recipient != address(0), "ERC20: transfer to the zero address"); - - _beforeTokenTransfer(sender, recipient, amount); - - require(_balances[sender] >= amount, "ERC20: transfer amount exceeds balance"); - _balances[sender] = _balances[sender] - amount; - _balances[recipient] = _balances[recipient] + amount; - emit Transfer(sender, recipient, amount); - } - - // openzeppelin/contracts/token/ERC20/ERC20.sol - function _burn(address account, uint256 value) internal { - require(account != address(0)); - require(value <= _balances[account]); - - _totalSupply = _totalSupply - value; - _balances[account] = _balances[account] - value; - emit Transfer(account, address(0), value); - } + // WstETH::unwrap + function unwrap(uint256 _wstETHAmount) external returns (uint256) { + require(_wstETHAmount > 0, "wstETH: zero amount unwrap not allowed"); + uint256 stETHAmount = stETH.getPooledEthByShares(_wstETHAmount); + _burn(msg.sender, _wstETHAmount); + stETH.transfer(msg.sender, stETHAmount); + return stETHAmount; + } + + // openzeppelin/contracts/token/ERC20/ERC20.sol + function approve(address spender, uint256 amount) public returns (bool) { + _approve(msg.sender, spender, amount); + return true; + } + + // openzeppelin/contracts/token/ERC20/ERC20.sol + function transferFrom(address sender, address recipient, uint256 amount) public virtual returns (bool) { + _transfer(sender, recipient, amount); + require(amount <= _allowances[sender][msg.sender], "ERC20: transfer amount exceeds allowance"); + _approve(sender, msg.sender, _allowances[sender][msg.sender] - amount); + return true; + } + + // @dev Overrides the actual permit function to allow for testing without signatures based on `isSignatureValid` flag. + // openzeppelin/contracts/drafts/ERC20Permit.sol + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external { + require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); + require(isSignatureValid, "ERC20Permit: invalid signature"); + + _nonces[owner].increment(); + _approve(owner, spender, value); + } + + // Exposed functions + + // openzeppelin/contracts/token/ERC20/ERC20.sol + function mock__mint(address _recipient, uint256 _amount) public { + _mint(_recipient, _amount); + } + + // Workarounds + + function mock__setIsSignatureValid(bool _validSignature) external { + isSignatureValid = _validSignature; + } + + // Internal functions + + // openzeppelin/contracts/token/ERC20/ERC20.sol + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} + + // openzeppelin/contracts/token/ERC20/ERC20.sol + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: mint to the zero address"); + + _beforeTokenTransfer(address(0), account, amount); + + _totalSupply = _totalSupply + amount; + _balances[account] = _balances[account] + amount; + emit Transfer(address(0), account, amount); + } + + // openzeppelin/contracts/token/ERC20/ERC20.sol + function _approve(address owner, address spender, uint256 amount) internal virtual { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + // openzeppelin/contracts/token/ERC20/ERC20.sol + function _transfer(address sender, address recipient, uint256 amount) internal virtual { + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); + + _beforeTokenTransfer(sender, recipient, amount); + + require(_balances[sender] >= amount, "ERC20: transfer amount exceeds balance"); + _balances[sender] = _balances[sender] - amount; + _balances[recipient] = _balances[recipient] + amount; + emit Transfer(sender, recipient, amount); + } + + // openzeppelin/contracts/token/ERC20/ERC20.sol + function _burn(address account, uint256 value) internal { + require(account != address(0)); + require(value <= _balances[account]); + + _totalSupply = _totalSupply - value; + _balances[account] = _balances[account] - value; + emit Transfer(account, address(0), value); + } } diff --git a/test/0.8.9/contracts/oracle/OracleReportSanityCheckerMocks.sol b/test/0.8.9/contracts/oracle/OracleReportSanityCheckerMocks.sol deleted file mode 100644 index f3dc6682b..000000000 --- a/test/0.8.9/contracts/oracle/OracleReportSanityCheckerMocks.sol +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 -// for testing purposes only - -pragma solidity 0.8.9; - -import {IWithdrawalQueue} from "contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol"; - -contract LidoStub { - uint256 private _shareRate = 1 ether; - - function getSharesByPooledEth(uint256 _sharesAmount) external view returns (uint256) { - return (_shareRate * _sharesAmount) / 1 ether; - } - - function setShareRate(uint256 _value) external { - _shareRate = _value; - } -} - -contract WithdrawalQueueStub is IWithdrawalQueue { - mapping(uint256 => uint256) private _timestamps; - - function setRequestTimestamp(uint256 _requestId, uint256 _timestamp) external { - _timestamps[_requestId] = _timestamp; - } - - function getWithdrawalStatus( - uint256[] calldata _requestIds - ) external view returns ( - WithdrawalRequestStatus[] memory statuses - ) { - statuses = new WithdrawalRequestStatus[](_requestIds.length); - for (uint256 i; i < _requestIds.length; ++i) { - statuses[i].timestamp = _timestamps[_requestIds[i]]; - } - } -} - -contract BurnerStub { - uint256 private nonCover; - uint256 private cover; - - function getSharesRequestedToBurn() external view returns ( - uint256 coverShares, uint256 nonCoverShares - ) { - coverShares = cover; - nonCoverShares = nonCover; - } - - function setSharesRequestedToBurn(uint256 _cover, uint256 _nonCover) external { - cover = _cover; - nonCover = _nonCover; - } -} - -interface ILidoLocator { - function lido() external view returns (address); - - function burner() external view returns (address); - - function withdrawalVault() external view returns (address); - - function withdrawalQueue() external view returns (address); -} - -contract LidoLocatorStub is ILidoLocator { - address private immutable LIDO; - address private immutable WITHDRAWAL_VAULT; - address private immutable WITHDRAWAL_QUEUE; - address private immutable EL_REWARDS_VAULT; - address private immutable BURNER; - - constructor( - address _lido, - address _withdrawalVault, - address _withdrawalQueue, - address _elRewardsVault, - address _burner - ) { - LIDO = _lido; - WITHDRAWAL_VAULT = _withdrawalVault; - WITHDRAWAL_QUEUE = _withdrawalQueue; - EL_REWARDS_VAULT = _elRewardsVault; - BURNER = _burner; - } - - function lido() external view returns (address) { - return LIDO; - } - - function withdrawalQueue() external view returns (address) { - return WITHDRAWAL_QUEUE; - } - - function withdrawalVault() external view returns (address) { - return WITHDRAWAL_VAULT; - } - - function elRewardsVault() external view returns (address) { - return EL_REWARDS_VAULT; - } - - function burner() external view returns (address) { - return BURNER; - } -} - -contract OracleReportSanityCheckerStub { - error SelectorNotFound(bytes4 sig, uint256 value, bytes data); - - fallback() external payable {revert SelectorNotFound(msg.sig, msg.value, msg.data);} - - function checkAccountingOracleReport( - uint256 _timeElapsed, - uint256 _preCLBalance, - uint256 _postCLBalance, - uint256 _withdrawalVaultBalance, - uint256 _elRewardsVaultBalance, - uint256 _sharesRequestedToBurn, - uint256 _preCLValidators, - uint256 _postCLValidators - ) external view {} - - function checkWithdrawalQueueOracleReport( - uint256[] calldata _withdrawalFinalizationBatches, - uint256 _reportTimestamp - ) external view {} - - function checkSimulatedShareRate( - uint256 _postTotalPooledEther, - uint256 _postTotalShares, - uint256 _etherLockedOnWithdrawalQueue, - uint256 _sharesBurntDueToWithdrawals, - uint256 _simulatedShareRate - ) external view {} - - function smoothenTokenRebase( - uint256, - uint256, - uint256, - uint256, - uint256 _withdrawalVaultBalance, - uint256 _elRewardsVaultBalance, - uint256, - uint256 _etherToLockForWithdrawals, - uint256 - ) external view returns ( - uint256 withdrawals, - uint256 elRewards, - uint256 simulatedSharesToBurn, - uint256 sharesToBurn - ) { - withdrawals = _withdrawalVaultBalance; - elRewards = _elRewardsVaultBalance; - - simulatedSharesToBurn = 0; - sharesToBurn = _etherToLockForWithdrawals; - } - - function checkAccountingExtraDataListItemsCount(uint256 _extraDataListItemsCount) external view {} -} diff --git a/test/0.8.9/depositSecurityModule.test.ts b/test/0.8.9/depositSecurityModule.test.ts index 47f5a36f8..130980a6f 100644 --- a/test/0.8.9/depositSecurityModule.test.ts +++ b/test/0.8.9/depositSecurityModule.test.ts @@ -8,10 +8,10 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { mineUpTo, setBalance, time } from "@nomicfoundation/hardhat-network-helpers"; import { - DepositContractMockForDepositSecurityModule, + DepositContract__MockForDepositSecurityModule, DepositSecurityModule, - LidoMockForDepositSecurityModule, - StakingRouterMockForDepositSecurityModule, + Lido__MockForDepositSecurityModule, + StakingRouter__MockForDepositSecurityModule, } from "typechain-types"; import { certainAddress, DSMAttestMessage, DSMPauseMessage, ether, streccak } from "lib"; @@ -62,9 +62,9 @@ describe("DepositSecurityModule.sol", () => { const config = initialParams(); let dsm: DepositSecurityModule; - let lido: LidoMockForDepositSecurityModule; - let stakingRouter: StakingRouterMockForDepositSecurityModule; - let depositContract: DepositContractMockForDepositSecurityModule; + let lido: Lido__MockForDepositSecurityModule; + let stakingRouter: StakingRouter__MockForDepositSecurityModule; + let depositContract: DepositContract__MockForDepositSecurityModule; let admin: HardhatEthersSigner; let stranger: HardhatEthersSigner; @@ -100,9 +100,9 @@ describe("DepositSecurityModule.sol", () => { await setBalance(unrelatedGuardian1.address, ether("100")); await setBalance(unrelatedGuardian2.address, ether("100")); - lido = await ethers.deployContract("LidoMockForDepositSecurityModule"); - stakingRouter = await ethers.deployContract("StakingRouterMockForDepositSecurityModule", [STAKING_MODULE_ID]); - depositContract = await ethers.deployContract("DepositContractMockForDepositSecurityModule"); + lido = await ethers.deployContract("Lido__MockForDepositSecurityModule"); + stakingRouter = await ethers.deployContract("StakingRouter__MockForDepositSecurityModule", [STAKING_MODULE_ID]); + depositContract = await ethers.deployContract("DepositContract__MockForDepositSecurityModule"); config.lido = await lido.getAddress(); config.stakingRouter = await stakingRouter.getAddress(); @@ -120,20 +120,11 @@ describe("DepositSecurityModule.sol", () => { originalState = await Snapshot.take(); }); - after(async () => { - await Snapshot.restore(originalState); - }); + beforeEach(async () => (originalState = await Snapshot.take())); - context("constructor", () => { - let originalContextState: string; - - beforeEach(async () => { - originalContextState = await Snapshot.take(); - }); - afterEach(async () => { - await Snapshot.restore(originalContextState); - }); + afterEach(async () => await Snapshot.restore(originalState)); + context("constructor", () => { it("Reverts if the `lido` is zero address", async () => { const cfg = { ...config }; cfg.lido = ZeroAddress; @@ -208,16 +199,6 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `setOwner`", () => { - let originalContextState: string; - - before(async () => { - originalContextState = await Snapshot.take(); - }); - - after(async () => { - await Snapshot.restore(originalContextState); - }); - it("Reverts if the `newValue` is zero address", async () => { await expect(dsm.setOwner(ZeroAddress)).to.be.revertedWithCustomError(dsm, "ZeroAddress"); }); @@ -249,16 +230,6 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `setPauseIntentValidityPeriodBlocks`", () => { - let originalContextState: string; - - before(async () => { - originalContextState = await Snapshot.take(); - }); - - after(async () => { - await Snapshot.restore(originalContextState); - }); - it("Reverts if the `newValue` is zero parameter", async () => { await expect(dsm.setPauseIntentValidityPeriodBlocks(0)).to.be.revertedWithCustomError(dsm, "ZeroParameter"); }); @@ -289,16 +260,6 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `setMaxDeposits`", () => { - let originalContextState: string; - - before(async () => { - originalContextState = await Snapshot.take(); - }); - - after(async () => { - await Snapshot.restore(originalContextState); - }); - it("Reverts if the `setMaxDeposits` called by not an owner", async () => { await expect( dsm.connect(stranger).setMaxDeposits(config.maxDepositsPerBlock + 1), @@ -325,16 +286,6 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `setMinDepositBlockDistance`", () => { - let originalContextState: string; - - before(async () => { - originalContextState = await Snapshot.take(); - }); - - after(async () => { - await Snapshot.restore(originalContextState); - }); - it("Reverts if the `setMinDepositBlockDistance` called by not an owner", async () => { await expect( dsm.connect(stranger).setMinDepositBlockDistance(config.minDepositBlockDistance + 1), @@ -374,17 +325,8 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `setGuardianQuorum`", () => { - let originalContextState: string; const guardianQuorum = 1; - beforeEach(async () => { - originalContextState = await Snapshot.take(); - }); - - afterEach(async () => { - await Snapshot.restore(originalContextState); - }); - it("Reverts if the `setGuardianQuorum` called by not an owner", async () => { await expect(dsm.connect(stranger).setGuardianQuorum(guardianQuorum)).to.be.revertedWithCustomError( dsm, @@ -427,16 +369,6 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `isGuardian`", () => { - let originalContextState: string; - - beforeEach(async () => { - originalContextState = await Snapshot.take(); - }); - - afterEach(async () => { - await Snapshot.restore(originalContextState); - }); - it("Returns false if list of guardians is empty", async () => { expect(await dsm.isGuardian(guardian1)).to.equal(false); }); @@ -460,16 +392,6 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `getGuardianIndex`", () => { - let originalContextState: string; - - beforeEach(async () => { - originalContextState = await Snapshot.take(); - }); - - afterEach(async () => { - await Snapshot.restore(originalContextState); - }); - it("Returns -1 if list of guardians is empty", async () => { expect(await dsm.getGuardianIndex(guardian1)).to.equal(-1); }); @@ -492,16 +414,6 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `addGuardian`", () => { - let originalContextState: string; - - beforeEach(async () => { - originalContextState = await Snapshot.take(); - }); - - afterEach(async () => { - await Snapshot.restore(originalContextState); - }); - it("Reverts if the `addGuardian` called by not an owner", async () => { await expect(dsm.connect(stranger).addGuardian(guardian1, 0)).to.be.revertedWithCustomError(dsm, "NotAnOwner"); }); @@ -555,16 +467,6 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `addGuardians`", () => { - let originalContextState: string; - - beforeEach(async () => { - originalContextState = await Snapshot.take(); - }); - - afterEach(async () => { - await Snapshot.restore(originalContextState); - }); - it("Reverts if the `addGuardians` called by not an owner", async () => { await expect(dsm.connect(stranger).addGuardians([guardian1, guardian2], 0)).to.be.revertedWithCustomError( dsm, @@ -604,16 +506,6 @@ describe("DepositSecurityModule.sol", () => { }); context("Function `removeGuardian`", () => { - let originalContextState: string; - - beforeEach(async () => { - originalContextState = await Snapshot.take(); - }); - - afterEach(async () => { - await Snapshot.restore(originalContextState); - }); - it("Reverts if the `removeGuardian` called by not an owner", async () => { await expect(dsm.connect(stranger).removeGuardian(guardian1, 0)).to.be.revertedWithCustomError( dsm, diff --git a/test/0.8.9/eip712.test.ts b/test/0.8.9/eip712.test.ts index 356138e28..3d5103b4a 100644 --- a/test/0.8.9/eip712.test.ts +++ b/test/0.8.9/eip712.test.ts @@ -2,16 +2,20 @@ import { expect } from "chai"; import { MaxUint256, TypedDataDomain, TypedDataEncoder, ZeroAddress } from "ethers"; import { ethers } from "hardhat"; -import { EIP712StETH, EIP712StETH__factory } from "typechain-types"; +import { EIP712StETH } from "typechain-types"; import { certainAddress } from "lib"; +import { Snapshot } from "test/suite"; + describe("EIP712StETH.sol", () => { let domain: TypedDataDomain; let eip712steth: EIP712StETH; - beforeEach(async () => { + let originalState: string; + + before(async () => { domain = { name: "Liquid staked Ether 2.0", version: "2", @@ -20,16 +24,21 @@ describe("EIP712StETH.sol", () => { }; const [deployer] = await ethers.getSigners(); - const factory = new EIP712StETH__factory(deployer); - eip712steth = await factory.deploy(domain.verifyingContract!); + eip712steth = await ethers.deployContract("EIP712StETH", [domain.verifyingContract!], deployer); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("constructor", () => { it("Reverts if the verifying contract is zero address", async () => { const [deployer] = await ethers.getSigners(); - const factory = new EIP712StETH__factory(deployer); - await expect(factory.deploy(ZeroAddress)).to.be.revertedWithCustomError(eip712steth, "ZeroStETHAddress"); + await expect(ethers.deployContract("EIP712StETH", [ZeroAddress], deployer)).to.be.revertedWithCustomError( + eip712steth, + "ZeroStETHAddress", + ); }); }); diff --git a/test/0.8.9/lidoExecutionLayerRewardsVault.test.ts b/test/0.8.9/lidoExecutionLayerRewardsVault.test.ts index 004971e5d..2d31a08ad 100644 --- a/test/0.8.9/lidoExecutionLayerRewardsVault.test.ts +++ b/test/0.8.9/lidoExecutionLayerRewardsVault.test.ts @@ -5,47 +5,52 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { + ERC721__Harness, Lido__MockForElRewardsVault, - Lido__MockForElRewardsVault__factory, LidoExecutionLayerRewardsVault, - LidoExecutionLayerRewardsVault__factory, - NFT__GeneralMock, - NFT__GeneralMock__factory, - Steth__MinimalMock, - Steth__MinimalMock__factory, + StETH__Harness, } from "typechain-types"; import { batch, certainAddress, ether, impersonate } from "lib"; -describe("LidoExecutionLayerRewardsVault", () => { +import { Snapshot } from "test/suite"; + +describe("LidoExecutionLayerRewardsVault.sol", () => { let deployer: HardhatEthersSigner; let anyone: HardhatEthersSigner; let lidoAsSigner: HardhatEthersSigner; let vault: LidoExecutionLayerRewardsVault; let lido: Lido__MockForElRewardsVault; + + let originalState: string; + const treasury = certainAddress("test:elRewardsVault:treasury"); - beforeEach(async () => { + before(async () => { [deployer, anyone] = await ethers.getSigners(); - lido = await new Lido__MockForElRewardsVault__factory(deployer).deploy(); - vault = await new LidoExecutionLayerRewardsVault__factory(deployer).deploy(lido, treasury); + lido = await ethers.deployContract("Lido__MockForElRewardsVault", deployer); + vault = await ethers.deployContract("LidoExecutionLayerRewardsVault", [lido, treasury], deployer); lidoAsSigner = await impersonate(await lido.getAddress(), ether("100.0")); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("constructor", () => { it("Reverts if Lido is zero address", async () => { await expect( - new LidoExecutionLayerRewardsVault__factory(deployer).deploy(ZeroAddress, treasury), + ethers.deployContract("LidoExecutionLayerRewardsVault", [ZeroAddress, treasury], deployer), ).to.be.revertedWith("LIDO_ZERO_ADDRESS"); }); it("Reverts if Treasury is zero address", async () => { - await expect(new LidoExecutionLayerRewardsVault__factory(deployer).deploy(lido, ZeroAddress)).to.be.revertedWith( - "TREASURY_ZERO_ADDRESS", - ); + await expect( + ethers.deployContract("LidoExecutionLayerRewardsVault", [lido, ZeroAddress], deployer), + ).to.be.revertedWith("TREASURY_ZERO_ADDRESS"); }); it("Sets Lido and Treasury addresses", async () => { @@ -224,11 +229,11 @@ describe("LidoExecutionLayerRewardsVault", () => { }); context("recoverERC20", () => { - let token: Steth__MinimalMock; + let token: StETH__Harness; beforeEach(async () => { const tokensToMint = ether("10.0"); - token = await new Steth__MinimalMock__factory(deployer).deploy(vault, { value: tokensToMint }); + token = await ethers.deployContract("StETH__Harness", [vault], { value: tokensToMint, from: deployer }); expect(await token.balanceOf(vault)).to.equal(tokensToMint); @@ -262,11 +267,11 @@ describe("LidoExecutionLayerRewardsVault", () => { }); context("recoverERC721", () => { - let nft: NFT__GeneralMock; + let nft: ERC721__Harness; const tokenId = 1n; beforeEach(async () => { - nft = await new NFT__GeneralMock__factory(deployer).deploy("NFTMock", "NFT"); + nft = await ethers.deployContract("ERC721__Harness", ["NFTMock", "NFT"], deployer); await nft.mint(vault, tokenId); expect(await nft.ownerOf(tokenId)).to.equal(await vault.getAddress()); diff --git a/test/0.8.9/lidoLocator.test.ts b/test/0.8.9/lidoLocator.test.ts index f970de0c0..caa601c8d 100644 --- a/test/0.8.9/lidoLocator.test.ts +++ b/test/0.8.9/lidoLocator.test.ts @@ -21,6 +21,7 @@ const services = [ "withdrawalQueue", "withdrawalVault", "oracleDaemonConfig", + "wstEth", ] as const; type Service = ArrayToUnion; diff --git a/test/0.8.9/oracle/accountingOracle.accessControl.test.ts b/test/0.8.9/oracle/accountingOracle.accessControl.test.ts index 0e16917a2..8f993d090 100644 --- a/test/0.8.9/oracle/accountingOracle.accessControl.test.ts +++ b/test/0.8.9/oracle/accountingOracle.accessControl.test.ts @@ -5,11 +5,7 @@ import { ethers } from "hardhat"; import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - AccountingOracleTimeTravellable, - HashConsensusTimeTravellable, - MockLidoForAccountingOracle, -} from "typechain-types"; +import { AccountingOracle__Harness, HashConsensus__Harness, Lido__MockForAccountingOracle } from "typechain-types"; import { calcExtraDataListHash, @@ -28,11 +24,12 @@ import { } from "lib"; import { deployAndConfigureAccountingOracle } from "test/deploy"; +import { Snapshot } from "test/suite"; describe("AccountingOracle.sol:accessControl", () => { - let consensus: HashConsensusTimeTravellable; - let oracle: AccountingOracleTimeTravellable; - let mockLido: MockLidoForAccountingOracle; + let consensus: HashConsensus__Harness; + let oracle: AccountingOracle__Harness; + let mockLido: Lido__MockForAccountingOracle; let reportItems: ReportAsArray; let reportFields: OracleReport; let extraDataList: string; @@ -42,9 +39,7 @@ describe("AccountingOracle.sol:accessControl", () => { let member: HardhatEthersSigner; let stranger: HardhatEthersSigner; - before(async () => { - [admin, account, member, stranger] = await ethers.getSigners(); - }); + let originalState: string; const deploy = async ({ emptyExtraData = false } = {}) => { const deployed = await deployAndConfigureAccountingOracle(admin.address); @@ -92,7 +87,15 @@ describe("AccountingOracle.sol:accessControl", () => { mockLido = deployed.lido; }; - beforeEach(deploy); + before(async () => { + [admin, account, member, stranger] = await ethers.getSigners(); + + await deploy(); + }); + + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); context("deploying", () => { it("deploying accounting oracle", async () => { @@ -160,7 +163,7 @@ describe("AccountingOracle.sol:accessControl", () => { }); context("submitReportExtraDataEmpty", () => { - beforeEach(() => deploy({ emptyExtraData: true })); + before(async () => await deploy({ emptyExtraData: true })); it("reverts when sender is not allowed", async () => { await expect(oracle.connect(account).submitReportExtraDataEmpty()).to.be.revertedWithCustomError( diff --git a/test/0.8.9/oracle/accountingOracle.deploy.test.ts b/test/0.8.9/oracle/accountingOracle.deploy.test.ts index e35b0689d..37a09ffcc 100644 --- a/test/0.8.9/oracle/accountingOracle.deploy.test.ts +++ b/test/0.8.9/oracle/accountingOracle.deploy.test.ts @@ -6,12 +6,12 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { AccountingOracle, - AccountingOracleTimeTravellable, - HashConsensusTimeTravellable, + AccountingOracle__Harness, + HashConsensus__Harness, LegacyOracle, - MockLidoForAccountingOracle, - MockStakingRouterForAccountingOracle, - MockWithdrawalQueueForAccountingOracle, + Lido__MockForAccountingOracle, + StakingRouter__MockForAccountingOracle, + WithdrawalQueue__MockForAccountingOracle, } from "typechain-types"; import { CONSENSUS_VERSION, EPOCHS_PER_FRAME, GENESIS_TIME, SECONDS_PER_SLOT, SLOTS_PER_EPOCH } from "lib"; @@ -34,7 +34,8 @@ describe("AccountingOracle.sol:deploy", () => { [admin] = await ethers.getSigners(); defaultOracle = (await deployAccountingOracleSetup(admin.address)).oracle; }); - const updateInitialEpoch = async (consensus: HashConsensusTimeTravellable) => { + + const updateInitialEpoch = async (consensus: HashConsensus__Harness) => { // pretend we're after the legacy oracle's last proc epoch but before the new oracle's initial epoch const voteExecTime = GENESIS_TIME + (V1_ORACLE_LAST_COMPLETED_EPOCH + 1n) * SLOTS_PER_EPOCH * SECONDS_PER_SLOT; await consensus.setTime(voteExecTime); @@ -127,11 +128,11 @@ describe("AccountingOracle.sol:deploy", () => { }); describe("deployment and init finishes successfully (default setup)", async () => { - let consensus: HashConsensusTimeTravellable; - let oracle: AccountingOracleTimeTravellable; - let mockLido: MockLidoForAccountingOracle; - let mockStakingRouter: MockStakingRouterForAccountingOracle; - let mockWithdrawalQueue: MockWithdrawalQueueForAccountingOracle; + let consensus: HashConsensus__Harness; + let oracle: AccountingOracle__Harness; + let mockLido: Lido__MockForAccountingOracle; + let mockStakingRouter: StakingRouter__MockForAccountingOracle; + let mockWithdrawalQueue: WithdrawalQueue__MockForAccountingOracle; let legacyOracle: LegacyOracle; before(async () => { diff --git a/test/0.8.9/oracle/accountingOracle.happyPath.test.ts b/test/0.8.9/oracle/accountingOracle.happyPath.test.ts index 8652bee8a..907c7b952 100644 --- a/test/0.8.9/oracle/accountingOracle.happyPath.test.ts +++ b/test/0.8.9/oracle/accountingOracle.happyPath.test.ts @@ -6,12 +6,12 @@ import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { - AccountingOracleTimeTravellable, - HashConsensusTimeTravellable, + AccountingOracle__Harness, + HashConsensus__Harness, LegacyOracle__MockForAccountingOracle, - MockLidoForAccountingOracle, - MockStakingRouterForAccountingOracle, - MockWithdrawalQueueForAccountingOracle, + Lido__MockForAccountingOracle, + StakingRouter__MockForAccountingOracle, + WithdrawalQueue__MockForAccountingOracle, } from "typechain-types"; import { @@ -45,12 +45,12 @@ import { describe("AccountingOracle.sol:happyPath", () => { context("Happy path", () => { - let consensus: HashConsensusTimeTravellable; - let oracle: AccountingOracleTimeTravellable; + let consensus: HashConsensus__Harness; + let oracle: AccountingOracle__Harness; let oracleVersion: number; - let mockLido: MockLidoForAccountingOracle; - let mockWithdrawalQueue: MockWithdrawalQueueForAccountingOracle; - let mockStakingRouter: MockStakingRouterForAccountingOracle; + let mockLido: Lido__MockForAccountingOracle; + let mockWithdrawalQueue: WithdrawalQueue__MockForAccountingOracle; + let mockStakingRouter: StakingRouter__MockForAccountingOracle; let mockLegacyOracle: LegacyOracle__MockForAccountingOracle; let extraData: ExtraDataType; diff --git a/test/0.8.9/oracle/accountingOracle.submitReport.test.ts b/test/0.8.9/oracle/accountingOracle.submitReport.test.ts index aec45b239..a7cd8bbdf 100644 --- a/test/0.8.9/oracle/accountingOracle.submitReport.test.ts +++ b/test/0.8.9/oracle/accountingOracle.submitReport.test.ts @@ -7,13 +7,13 @@ import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { - AccountingOracleTimeTravellable, - HashConsensusTimeTravellable, + AccountingOracle__Harness, + HashConsensus__Harness, LegacyOracle__MockForAccountingOracle, - MockLidoForAccountingOracle, - MockStakingRouterForAccountingOracle, - MockWithdrawalQueueForAccountingOracle, + Lido__MockForAccountingOracle, OracleReportSanityChecker, + StakingRouter__MockForAccountingOracle, + WithdrawalQueue__MockForAccountingOracle, } from "typechain-types"; import { @@ -39,8 +39,8 @@ import { deployAndConfigureAccountingOracle, HASH_1, SLOTS_PER_FRAME } from "tes import { Snapshot } from "test/suite"; describe("AccountingOracle.sol:submitReport", () => { - let consensus: HashConsensusTimeTravellable; - let oracle: AccountingOracleTimeTravellable; + let consensus: HashConsensus__Harness; + let oracle: AccountingOracle__Harness; let reportItems: ReportAsArray; let reportFields: OracleReport & { refSlot: bigint }; let reportHash: string; @@ -49,12 +49,12 @@ describe("AccountingOracle.sol:submitReport", () => { let extraDataItems: string[]; let oracleVersion: bigint; let deadline: BigNumberish; - let mockStakingRouter: MockStakingRouterForAccountingOracle; + let mockStakingRouter: StakingRouter__MockForAccountingOracle; let extraData: ExtraDataType; - let mockLido: MockLidoForAccountingOracle; + let mockLido: Lido__MockForAccountingOracle; let sanityChecker: OracleReportSanityChecker; let mockLegacyOracle: LegacyOracle__MockForAccountingOracle; - let mockWithdrawalQueue: MockWithdrawalQueueForAccountingOracle; + let mockWithdrawalQueue: WithdrawalQueue__MockForAccountingOracle; let snapshot: string; let admin: HardhatEthersSigner; @@ -144,11 +144,11 @@ describe("AccountingOracle.sol:submitReport", () => { async function prepareNextReportInNextFrame(newReportFields: OracleReport) { const { refSlot } = await consensus.getCurrentFrame(); - const next = await prepareNextReport({ + + return await prepareNextReport({ ...newReportFields, refSlot: refSlot + SLOTS_PER_FRAME, }); - return next; } before(deploy); diff --git a/test/0.8.9/oracle/accountingOracle.submitReportExtraData.test.ts b/test/0.8.9/oracle/accountingOracle.submitReportExtraData.test.ts index 25d70a636..a5e2872fb 100644 --- a/test/0.8.9/oracle/accountingOracle.submitReportExtraData.test.ts +++ b/test/0.8.9/oracle/accountingOracle.submitReportExtraData.test.ts @@ -6,10 +6,10 @@ import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { - AccountingOracleTimeTravellable, - HashConsensusTimeTravellable, - MockStakingRouterForAccountingOracle, + AccountingOracle__Harness, + HashConsensus__Harness, OracleReportSanityChecker, + StakingRouter__MockForAccountingOracle, } from "typechain-types"; import { @@ -66,10 +66,10 @@ const getDefaultReportFields = (override = {}) => ({ }); describe("AccountingOracle.sol:submitReportExtraData", () => { - let consensus: HashConsensusTimeTravellable; - let oracle: AccountingOracleTimeTravellable; + let consensus: HashConsensus__Harness; + let oracle: AccountingOracle__Harness; let oracleVersion: bigint; - let stakingRouter: MockStakingRouterForAccountingOracle; + let stakingRouter: StakingRouter__MockForAccountingOracle; let sanityChecker: OracleReportSanityChecker; let snapshot: string; diff --git a/test/0.8.9/oracle/baseOracle.accessControl.test.ts b/test/0.8.9/oracle/baseOracle.accessControl.test.ts index 7ea44f6bc..dbd605850 100644 --- a/test/0.8.9/oracle/baseOracle.accessControl.test.ts +++ b/test/0.8.9/oracle/baseOracle.accessControl.test.ts @@ -3,7 +3,7 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { BaseOracle__Harness, MockConsensusContract } from "typechain-types"; +import { BaseOracle__Harness, ConsensusContract__Mock } from "typechain-types"; import { CONSENSUS_VERSION, @@ -17,12 +17,12 @@ import { import { deployBaseOracle, HASH_1, SECONDS_PER_EPOCH, SLOTS_PER_FRAME } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("BaseOracle:accessControl", () => { +describe("BaseOracle.sol:accessControl", () => { let admin: HardhatEthersSigner; let stranger: HardhatEthersSigner; let manager: HardhatEthersSigner; let oracle: BaseOracle__Harness; - let consensus: MockConsensusContract; + let consensus: ConsensusContract__Mock; let originalState: string; before(async () => { @@ -56,7 +56,7 @@ describe("BaseOracle:accessControl", () => { }); it("Updates consensus contract with MANAGE_CONSENSUS_CONTRACT_ROLE", async () => { - const newConsensusContract = await ethers.deployContract("MockConsensusContract", [ + const newConsensusContract = await ethers.deployContract("ConsensusContract__Mock", [ SECONDS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME, diff --git a/test/0.8.9/oracle/baseOracle.consensus.test.ts b/test/0.8.9/oracle/baseOracle.consensus.test.ts index 56e1c4d69..7354ea261 100644 --- a/test/0.8.9/oracle/baseOracle.consensus.test.ts +++ b/test/0.8.9/oracle/baseOracle.consensus.test.ts @@ -4,28 +4,25 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { BaseOracle__Harness, MockConsensusContract } from "typechain-types"; +import { BaseOracle__Harness, ConsensusContract__Mock } from "typechain-types"; import { CONSENSUS_VERSION, EPOCHS_PER_FRAME, GENESIS_TIME, SECONDS_PER_SLOT, SLOTS_PER_EPOCH } from "lib"; import { deadlineFromRefSlot, deployBaseOracle, epochFirstSlotAt, HASH_1, HASH_2 } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("BaseOracle:consensus", () => { +describe("BaseOracle.sol:consensus", () => { let admin: HardhatEthersSigner; let member: HardhatEthersSigner; let notMember: HardhatEthersSigner; - let consensus: MockConsensusContract; + let consensus: ConsensusContract__Mock; let originalState: string; let baseOracle: BaseOracle__Harness; let initialRefSlot: bigint; before(async () => { [admin, member, notMember] = await ethers.getSigners(); - await deployContract(); - }); - const deployContract = async () => { const deployed = await deployBaseOracle(admin, { initialEpoch: 1n, mockMember: member, @@ -39,7 +36,7 @@ describe("BaseOracle:consensus", () => { const time = await baseOracle.getTime(); initialRefSlot = epochFirstSlotAt(time); - }; + }); beforeEach(async () => (originalState = await Snapshot.take())); @@ -66,7 +63,7 @@ describe("BaseOracle:consensus", () => { }); it("on mismatched config", async () => { - const wrongConsensusContract = await ethers.deployContract("MockConsensusContract", [ + const wrongConsensusContract = await ethers.deployContract("ConsensusContract__Mock", [ SLOTS_PER_EPOCH, SECONDS_PER_SLOT + 1n, GENESIS_TIME + 1n, @@ -90,7 +87,7 @@ describe("BaseOracle:consensus", () => { await consensus.submitReportAsConsensus(HASH_1, processingRefSlot, Number(await baseOracle.getTime()) + 1); await baseOracle.startProcessing(); - const wrongConsensusContract = await ethers.deployContract("MockConsensusContract", [ + const wrongConsensusContract = await ethers.deployContract("ConsensusContract__Mock", [ SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME, @@ -109,7 +106,7 @@ describe("BaseOracle:consensus", () => { }); it("Updates consensus contract", async () => { - const newConsensusContract = await ethers.deployContract("MockConsensusContract", [ + const newConsensusContract = await ethers.deployContract("ConsensusContract__Mock", [ SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME, diff --git a/test/0.8.9/oracle/baseOracle.submitReport.test.ts b/test/0.8.9/oracle/baseOracle.submitReport.test.ts index 6d118fda7..dcb32f24d 100644 --- a/test/0.8.9/oracle/baseOracle.submitReport.test.ts +++ b/test/0.8.9/oracle/baseOracle.submitReport.test.ts @@ -3,7 +3,7 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { BaseOracle__Harness, MockConsensusContract } from "typechain-types"; +import { BaseOracle__Harness, ConsensusContract__Mock } from "typechain-types"; import { SECONDS_PER_SLOT } from "lib"; @@ -19,13 +19,13 @@ import { } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("BaseOracle:submitReport", () => { +describe("BaseOracle.sol:submitReport", () => { let admin: HardhatEthersSigner; let originalState: string; let baseOracle: BaseOracle__Harness; let initialRefSlot: bigint; - let consensus: MockConsensusContract; + let consensus: ConsensusContract__Mock; before(async () => { [admin] = await ethers.getSigners(); diff --git a/test/0.8.9/oracle/hashConsensus.accessControl.test.ts b/test/0.8.9/oracle/hashConsensus.accessControl.test.ts index 40cbddf55..efb3bb243 100644 --- a/test/0.8.9/oracle/hashConsensus.accessControl.test.ts +++ b/test/0.8.9/oracle/hashConsensus.accessControl.test.ts @@ -2,17 +2,17 @@ import { expect } from "chai"; import { MaxUint256, Signer } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensus, MockReportProcessor, MockReportProcessor__factory } from "typechain-types"; +import { HashConsensus, ReportProcessor__Mock } from "typechain-types"; import { CONSENSUS_VERSION, DEFAULT_ADMIN_ROLE, EPOCHS_PER_FRAME, streccak } from "lib"; import { deployHashConsensus, DeployHashConsensusParams } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("HashConsensus:AccessControl", function () { +describe("HashConsensus.sol:accessControl", function () { let consensus: HashConsensus; - let reportProcessor: MockReportProcessor; - let reportProcessor2: MockReportProcessor; + let reportProcessor: ReportProcessor__Mock; + let reportProcessor2: ReportProcessor__Mock; let baseSnapshot: string; let snapshot: string; @@ -41,7 +41,7 @@ describe("HashConsensus:AccessControl", function () { consensus = deployed.consensus; reportProcessor = deployed.reportProcessor; - reportProcessor2 = await new MockReportProcessor__factory(admin).deploy(CONSENSUS_VERSION); + reportProcessor2 = await ethers.deployContract("ReportProcessor__Mock", [CONSENSUS_VERSION], admin); snapshot = await Snapshot.take(); }; @@ -55,7 +55,7 @@ describe("HashConsensus:AccessControl", function () { await deploy({ initialEpoch: null }); }); - afterEach(refresh); + beforeEach(refresh); context("updateInitialEpoch", () => { it("reverts when called without DEFAULT_ADMIN_ROLE", async () => { @@ -83,7 +83,7 @@ describe("HashConsensus:AccessControl", function () { await deploy({}); }); - beforeEach(async () => (snapshot = await Snapshot.refresh(snapshot))); + beforeEach(refresh); context("deploying", () => { it("deploying hash consensus", async () => { diff --git a/test/0.8.9/oracle/hashConsensus.deploy.test.ts b/test/0.8.9/oracle/hashConsensus.deploy.test.ts index fbacfa066..0a29ef6f9 100644 --- a/test/0.8.9/oracle/hashConsensus.deploy.test.ts +++ b/test/0.8.9/oracle/hashConsensus.deploy.test.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { Signer, ZeroAddress } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensus, MockReportProcessor, MockReportProcessor__factory } from "typechain-types"; +import { HashConsensus, ReportProcessor__Mock } from "typechain-types"; import { CONSENSUS_VERSION, @@ -15,14 +15,14 @@ import { import { deployHashConsensus } from "test/deploy"; -describe("HashConsensus:deploy", function () { +describe("HashConsensus.sol:deploy", function () { let admin: Signer; let consensus: HashConsensus; - let mockReportProcessor: MockReportProcessor; + let mockReportProcessor: ReportProcessor__Mock; before(async () => { [admin] = await ethers.getSigners(); - mockReportProcessor = await new MockReportProcessor__factory(admin).deploy(CONSENSUS_VERSION); + mockReportProcessor = await ethers.deployContract("ReportProcessor__Mock", [CONSENSUS_VERSION], admin); }); context("Deployment and initial configuration", () => { @@ -48,7 +48,7 @@ describe("HashConsensus:deploy", function () { it("reverts if report processor address is zero", async () => { await expect( - ethers.deployContract("HashConsensusTimeTravellable", [ + ethers.deployContract("HashConsensus__Harness", [ SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME, @@ -62,7 +62,7 @@ describe("HashConsensus:deploy", function () { it("reverts if admin address is zero", async () => { await expect( - ethers.deployContract("HashConsensusTimeTravellable", [ + ethers.deployContract("HashConsensus__Harness", [ SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME, diff --git a/test/0.8.9/oracle/hashConsensus.fastLaneLength.test.ts b/test/0.8.9/oracle/hashConsensus.fastLaneLength.test.ts index 61e2d17a9..7e7382360 100644 --- a/test/0.8.9/oracle/hashConsensus.fastLaneLength.test.ts +++ b/test/0.8.9/oracle/hashConsensus.fastLaneLength.test.ts @@ -2,13 +2,16 @@ import { expect } from "chai"; import { Signer } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensusTimeTravellable } from "typechain-types"; +import { HashConsensus__Harness } from "typechain-types"; import { deployHashConsensus, DeployHashConsensusParams } from "test/deploy"; +import { Snapshot } from "test/suite"; -describe("HashConsensus:fastLaneLength", function () { +describe("HashConsensus.sol:fastLaneLength", function () { let admin: Signer; - let consensus: HashConsensusTimeTravellable; + let consensus: HashConsensus__Harness; + + let originalState: string; const deploy = async (options?: DeployHashConsensusParams) => { [admin] = await ethers.getSigners(); @@ -16,6 +19,10 @@ describe("HashConsensus:fastLaneLength", function () { consensus = deployed.consensus; }; + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("initial data", () => { it("sets properly", async () => { await deploy({ fastLaneLengthSlots: 0n }); @@ -26,7 +33,7 @@ describe("HashConsensus:fastLaneLength", function () { }); context("setFastLaneLengthSlots", () => { - beforeEach(() => deploy()); + before(() => deploy()); const getFastLaneLengthSlotsLimit = async () => { const { slotsPerEpoch } = await consensus.getChainConfig(); diff --git a/test/0.8.9/oracle/hashConsensus.fastLaneMembers.test.ts b/test/0.8.9/oracle/hashConsensus.fastLaneMembers.test.ts index 52a52db20..3407cd3d0 100644 --- a/test/0.8.9/oracle/hashConsensus.fastLaneMembers.test.ts +++ b/test/0.8.9/oracle/hashConsensus.fastLaneMembers.test.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { Signer } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensusTimeTravellable } from "typechain-types"; +import { HashConsensus__Harness } from "typechain-types"; import { CONSENSUS_VERSION, MAX_UINT256 } from "lib"; @@ -22,7 +22,7 @@ const prepareFrameData = async ({ }; }; -describe("HashConsensus:Fastlane members", () => { +describe("HashConsensus.sol:fastlaneMembers", () => { let admin: Signer; let member1: Signer; let member2: Signer; @@ -30,7 +30,7 @@ describe("HashConsensus:Fastlane members", () => { let member4: Signer; let member5: Signer; let stranger: Signer; - let consensus: HashConsensusTimeTravellable; + let consensus: HashConsensus__Harness; const deploy = async (options?: DeployHashConsensusParams) => { [admin, member1, member2, member3, member4, member5, stranger] = await ethers.getSigners(); @@ -60,6 +60,7 @@ describe("HashConsensus:Fastlane members", () => { expect(fastLaneMembers.addresses).to.be.empty; }); }); + context("Basic scenario", () => { const fastLaneLengthSlots = 10n; @@ -175,6 +176,7 @@ describe("HashConsensus:Fastlane members", () => { }); }); }); + const testAllInFastLane = ({ quorumSize }: { quorumSize: bigint }) => { before(async () => { await deploy({ fastLaneLengthSlots: 10n }); diff --git a/test/0.8.9/oracle/hashConsensus.frames.test.ts b/test/0.8.9/oracle/hashConsensus.frames.test.ts index 0e3d13766..475954865 100644 --- a/test/0.8.9/oracle/hashConsensus.frames.test.ts +++ b/test/0.8.9/oracle/hashConsensus.frames.test.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { Signer } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensusTimeTravellable, MockReportProcessor } from "typechain-types"; +import { HashConsensus__Harness, ReportProcessor__Mock } from "typechain-types"; import { CONSENSUS_VERSION, @@ -22,8 +22,9 @@ import { SLOTS_PER_FRAME, ZERO_HASH, } from "test/deploy"; +import { Snapshot } from "test/suite"; -describe("HashConsensus:frames", function() { +describe("HashConsensus.sol:frames", function () { const TEST_INITIAL_EPOCH = 3n; let admin: Signer; @@ -32,19 +33,21 @@ describe("HashConsensus:frames", function() { let member2: Signer; let member3: Signer; + let originalState: string; + before(async () => { [admin, member1, member2, member3] = await ethers.getSigners(); }); - describe("Frame methods", () => { - let consensus: HashConsensusTimeTravellable; + context("Frame methods", () => { + let consensus: HashConsensus__Harness; const deploy = async () => { const deployed = await deployHashConsensus(await admin.getAddress()); consensus = deployed.consensus; }; - describe("getFrameConfig", () => { + context("getFrameConfig", () => { before(deploy); it("should return initial data", async () => { @@ -63,8 +66,12 @@ describe("HashConsensus:frames", function() { }); }); - describe("setFrameConfig", () => { - beforeEach(deploy); + context("setFrameConfig", () => { + before(deploy); + + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); it("should set data", async () => { await consensus.setFrameConfig(100, 50); @@ -118,9 +125,10 @@ describe("HashConsensus:frames", function() { }); }); }); + context("State before initial epoch", () => { - let consensus: HashConsensusTimeTravellable; - let reportProcessor: MockReportProcessor; + let consensus: HashConsensus__Harness; + let reportProcessor: ReportProcessor__Mock; before(async () => { const deployed = await deployHashConsensus(await admin.getAddress(), { initialEpoch: null }); @@ -269,14 +277,18 @@ describe("HashConsensus:frames", function() { }); context("Reporting interval manipulation", () => { - let consensus: HashConsensusTimeTravellable; + let consensus: HashConsensus__Harness; - beforeEach(async () => { + before(async () => { const deployed = await deployHashConsensus(await admin.getAddress(), { initialEpoch: 1n }); consensus = deployed.consensus; await consensus.connect(admin).addMember(await member1.getAddress(), 1); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + it("crossing frame boundary time advances reference and deadline slots by the frame size", async () => { expect(await consensus.getTime()).to.equal(computeTimestampAtEpoch(1n)); diff --git a/test/0.8.9/oracle/hashConsensus.getTime.test.ts b/test/0.8.9/oracle/hashConsensus.getTime.test.ts index edfa1db83..82bb91c69 100644 --- a/test/0.8.9/oracle/hashConsensus.getTime.test.ts +++ b/test/0.8.9/oracle/hashConsensus.getTime.test.ts @@ -25,7 +25,7 @@ async function deployOriginalHashConsensus( fastLaneLengthSlots = INITIAL_FAST_LANE_LENGTH_SLOTS, }: DeployHashConsensusParams = {}, ) { - const reportProcessor = await ethers.deployContract("MockReportProcessor", [CONSENSUS_VERSION]); + const reportProcessor = await ethers.deployContract("ReportProcessor__Mock", [CONSENSUS_VERSION]); const consensus = await ethers.deployContract("HashConsensus", [ slotsPerEpoch, @@ -46,17 +46,15 @@ async function deployOriginalHashConsensus( return { reportProcessor, consensus }; } -describe("HashConsensus:getTime", function () { +describe("HashConsensus.sol:getTime", function () { let admin: Signer; let consensus: HashConsensus; - const deploy = async () => { + before(async () => { [admin] = await ethers.getSigners(); const deployed = await deployOriginalHashConsensus(await admin.getAddress()); consensus = deployed.consensus; - }; - - before(deploy); + }); it("call original _getTime by updateInitialEpoch method", async () => { await consensus.updateInitialEpoch(10); diff --git a/test/0.8.9/oracle/hashConsensus.happyPath.test.ts b/test/0.8.9/oracle/hashConsensus.happyPath.test.ts index 4c30d72c0..b62cd8360 100644 --- a/test/0.8.9/oracle/hashConsensus.happyPath.test.ts +++ b/test/0.8.9/oracle/hashConsensus.happyPath.test.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { Signer } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensusTimeTravellable, MockReportProcessor } from "typechain-types"; +import { HashConsensus__Harness, ReportProcessor__Mock } from "typechain-types"; import { CONSENSUS_VERSION, EPOCHS_PER_FRAME, SECONDS_PER_SLOT, SLOTS_PER_EPOCH } from "lib"; @@ -22,22 +22,20 @@ import { const INITIAL_EPOCH = 3n; -describe("HashConsensus:happyPath", function () { +describe("HashConsensus.sol:happyPath", function () { let admin: Signer; let member1: Signer; let member2: Signer; let member3: Signer; - let consensus: HashConsensusTimeTravellable; - let reportProcessor: MockReportProcessor; + let consensus: HashConsensus__Harness; + let reportProcessor: ReportProcessor__Mock; - const deploy = async () => { + before(async () => { [admin, member1, member2, member3] = await ethers.getSigners(); const deployed = await deployHashConsensus(await admin.getAddress(), { initialEpoch: INITIAL_EPOCH }); consensus = deployed.consensus; reportProcessor = deployed.reportProcessor; - }; - - before(deploy); + }); it("adding members", async () => { await consensus.connect(admin).addMember(await member1.getAddress(), 1); @@ -102,8 +100,8 @@ describe("HashConsensus:happyPath", function () { const consensusState = await consensus.getConsensusState(); expect(consensusState.consensusReport).to.equal(ZERO_HASH); expect(consensusState.isReportProcessing).to.be.false; - expect(await (await reportProcessor.getLastCall_submitReport()).callCount).to.equal(0); - expect(await (await reportProcessor.getLastCall_discardReport()).callCount).to.equal(0); + expect((await reportProcessor.getLastCall_submitReport()).callCount).to.equal(0); + expect((await reportProcessor.getLastCall_discardReport()).callCount).to.equal(0); const memberInfo = await consensus.getConsensusStateForMember(await member1.getAddress()); expect(memberInfo.currentFrameConsensusReport).to.equal(ZERO_HASH); @@ -370,7 +368,7 @@ describe("HashConsensus:happyPath", function () { expect(memberInfo.canReport).to.be.true; }); - it('consensus is not reached', async () => { + it("consensus is not reached", async () => { const consensusState = await consensus.getConsensusState(); expect(consensusState.consensusReport).to.equal(ZERO_HASH); expect(consensusState.isReportProcessing).to.be.false; diff --git a/test/0.8.9/oracle/hashConsensus.members.test.ts b/test/0.8.9/oracle/hashConsensus.members.test.ts index 0ac1b0128..d17c0118a 100644 --- a/test/0.8.9/oracle/hashConsensus.members.test.ts +++ b/test/0.8.9/oracle/hashConsensus.members.test.ts @@ -2,13 +2,14 @@ import { expect } from "chai"; import { Signer, ZeroAddress } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensusTimeTravellable } from "typechain-types"; +import { HashConsensus__Harness } from "typechain-types"; import { CONSENSUS_VERSION } from "lib"; import { deployHashConsensus, HASH_1, HASH_2, ZERO_HASH } from "test/deploy"; -describe("HashConsensus:members", function() { +// TODO: This is a very heavy test, need to speed it up using proper Snapshot strategy +describe("HashConsensus.sol:members", function () { let admin: Signer; let member1: Signer; let member2: Signer; @@ -18,7 +19,7 @@ describe("HashConsensus:members", function() { let member6: Signer; let stranger: Signer; - let consensus: HashConsensusTimeTravellable; + let consensus: HashConsensus__Harness; const deploy = async () => { const deployed = await deployHashConsensus(await admin.getAddress()); diff --git a/test/0.8.9/oracle/hashConsensus.reportProcessor.test.ts b/test/0.8.9/oracle/hashConsensus.reportProcessor.test.ts index 0c9ec672e..e435023ee 100644 --- a/test/0.8.9/oracle/hashConsensus.reportProcessor.test.ts +++ b/test/0.8.9/oracle/hashConsensus.reportProcessor.test.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { Signer, ZeroAddress } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensusTimeTravellable, MockReportProcessor, MockReportProcessor__factory } from "typechain-types"; +import { HashConsensus__Harness, ReportProcessor__Mock } from "typechain-types"; import { CONSENSUS_VERSION, streccak } from "lib"; @@ -11,15 +11,15 @@ import { Snapshot } from "test/suite"; const manageReportProcessorRoleKeccak256 = streccak("MANAGE_REPORT_PROCESSOR_ROLE"); -describe("HashConsensus:reportProcessor", function() { +describe("HashConsensus.sol:reportProcessor", function () { let admin: Signer; let member1: Signer; let member2: Signer; let stranger: Signer; - let consensus: HashConsensusTimeTravellable; - let reportProcessor1: MockReportProcessor; - let reportProcessor2: MockReportProcessor; + let consensus: HashConsensus__Harness; + let reportProcessor1: ReportProcessor__Mock; + let reportProcessor2: ReportProcessor__Mock; let snapshot: string; @@ -29,7 +29,7 @@ describe("HashConsensus:reportProcessor", function() { consensus = deployed.consensus; reportProcessor1 = deployed.reportProcessor; - reportProcessor2 = await new MockReportProcessor__factory(admin).deploy(CONSENSUS_VERSION); + reportProcessor2 = await ethers.deployContract("ReportProcessor__Mock", [CONSENSUS_VERSION], admin); snapshot = await Snapshot.take(); }; @@ -167,7 +167,7 @@ describe("HashConsensus:reportProcessor", function() { it("equals to new processor version after it was changed", async () => { const CONSENSUS_VERSION_2 = 2; - const reportProcessor_v2 = await new MockReportProcessor__factory(admin).deploy(CONSENSUS_VERSION_2); + const reportProcessor_v2 = await ethers.deployContract("ReportProcessor__Mock", [CONSENSUS_VERSION_2], admin); await consensus.setReportProcessor(await reportProcessor_v2.getAddress()); expect(await consensus.getConsensusVersion()).to.equal(CONSENSUS_VERSION_2); diff --git a/test/0.8.9/oracle/hashConsensus.setQuorum.test.ts b/test/0.8.9/oracle/hashConsensus.setQuorum.test.ts index b014e7388..bd86688c1 100644 --- a/test/0.8.9/oracle/hashConsensus.setQuorum.test.ts +++ b/test/0.8.9/oracle/hashConsensus.setQuorum.test.ts @@ -2,14 +2,14 @@ import { expect } from "chai"; import { MaxUint256, Signer } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensus, HashConsensus__factory, MockReportProcessor } from "typechain-types"; +import { HashConsensus, ReportProcessor__Mock } from "typechain-types"; import { CONSENSUS_VERSION, findEventsWithAbi } from "lib"; import { deployHashConsensus, DeployHashConsensusParams, HASH_1, ZERO_HASH } from "test/deploy"; import { Snapshot } from "test/suite"; -describe("HashConsensus:setQuorum", function () { +describe("HashConsensus.sol:setQuorum", function () { let admin: Signer; let member1: Signer; let member2: Signer; @@ -113,7 +113,7 @@ describe("HashConsensus:setQuorum", function () { describe("setQuorum changes the effective quorum", () => { let consensus: HashConsensus; let snapshot: string; - let reportProcessor: MockReportProcessor; + let reportProcessor: ReportProcessor__Mock; let frame: Awaited>; const deployContractWithMembers = async () => { @@ -191,8 +191,8 @@ describe("HashConsensus:setQuorum", function () { const tx3 = await consensus.setQuorum(2); await expect(tx3).to.emit(consensus, "ConsensusReached"); - const receipt = await tx3.wait()!; - const consensusReachedEvents = findEventsWithAbi(receipt!, "ConsensusReached", HashConsensus__factory.abi); + const receipt = (await tx3.wait())!; + const consensusReachedEvents = findEventsWithAbi(receipt!, "ConsensusReached", consensus.interface.fragments); expect(consensusReachedEvents.length).to.equal(1); const consensusState = await consensus.getConsensusState(); @@ -200,29 +200,33 @@ describe("HashConsensus:setQuorum", function () { }); }); - describe('setQuorum can lead to consensus loss on quorum increase', () => { + describe("setQuorum can lead to consensus loss on quorum increase", () => { after(rollback); - it('2/3 members reach consensus with quorum of 2', async () => { + it("2/3 members reach consensus with quorum of 2", async () => { await consensus.setQuorum(2); const tx1 = await consensus.connect(member1).submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION); - await expect(tx1).to.emit(consensus, 'ReportReceived').withArgs(frame.refSlot, await member1.getAddress(), HASH_1); - await expect(tx1).not.to.emit(consensus, 'ConsensusReached'); + await expect(tx1) + .to.emit(consensus, "ReportReceived") + .withArgs(frame.refSlot, await member1.getAddress(), HASH_1); + await expect(tx1).not.to.emit(consensus, "ConsensusReached"); const tx2 = await consensus.connect(member2).submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION); - await expect(tx2).to.emit(consensus, 'ReportReceived').withArgs(frame.refSlot, await member2.getAddress(), HASH_1); - await expect(tx2).to.emit(consensus, 'ConsensusReached'); + await expect(tx2) + .to.emit(consensus, "ReportReceived") + .withArgs(frame.refSlot, await member2.getAddress(), HASH_1); + await expect(tx2).to.emit(consensus, "ConsensusReached"); - const receipt = await tx2.wait()!; - const consensusReachedEvents = findEventsWithAbi(receipt!, "ConsensusReached", HashConsensus__factory.abi); + const receipt = (await tx2.wait())!; + const consensusReachedEvents = findEventsWithAbi(receipt!, "ConsensusReached", consensus.interface.fragments); expect(consensusReachedEvents.length).to.equal(1); expect((await reportProcessor.getLastCall_submitReport()).callCount).to.equal(1); }); - it('quorum goes up to 3 and consensus is lost', async () => { + it("quorum goes up to 3 and consensus is lost", async () => { const tx = await consensus.setQuorum(3); - await expect(tx).to.emit(consensus, 'ConsensusLost').withArgs(frame.refSlot); + await expect(tx).to.emit(consensus, "ConsensusLost").withArgs(frame.refSlot); const consensusState = await consensus.getConsensusState(); expect(consensusState.consensusReport).to.equal(ZERO_HASH); @@ -230,9 +234,9 @@ describe("HashConsensus:setQuorum", function () { expect((await reportProcessor.getLastCall_discardReport()).callCount).to.equal(1); }); - it('quorum goes down, the consensus is reached again', async () => { + it("quorum goes down, the consensus is reached again", async () => { const tx = await consensus.setQuorum(2); - await expect(tx).to.emit(consensus, 'ConsensusReached').withArgs(frame.refSlot, HASH_1, 2); + await expect(tx).to.emit(consensus, "ConsensusReached").withArgs(frame.refSlot, HASH_1, 2); const consensusState = await consensus.getConsensusState(); expect(consensusState.consensusReport).to.equal(HASH_1); @@ -241,44 +245,48 @@ describe("HashConsensus:setQuorum", function () { }); }); - describe('setQuorum does not re-trigger consensus if hash is already being processed', () => { + describe("setQuorum does not re-trigger consensus if hash is already being processed", () => { after(rollback); - it('2/3 members reach consensus with Quorum of 2', async () => { + it("2/3 members reach consensus with Quorum of 2", async () => { await consensus.setQuorum(2); const tx1 = await consensus.connect(member1).submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION); - await expect(tx1).to.emit(consensus, 'ReportReceived').withArgs(frame.refSlot, await member1.getAddress(), HASH_1); - await expect(tx1).not.to.emit(consensus, 'ConsensusReached'); + await expect(tx1) + .to.emit(consensus, "ReportReceived") + .withArgs(frame.refSlot, await member1.getAddress(), HASH_1); + await expect(tx1).not.to.emit(consensus, "ConsensusReached"); const tx2 = await consensus.connect(member2).submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION); - await expect(tx2).to.emit(consensus, 'ReportReceived').withArgs(frame.refSlot, await member2.getAddress(), HASH_1); + await expect(tx2) + .to.emit(consensus, "ReportReceived") + .withArgs(frame.refSlot, await member2.getAddress(), HASH_1); - const receipt = await tx2.wait()!; - const consensusReachedEvents = findEventsWithAbi(receipt!, "ConsensusReached", HashConsensus__factory.abi); + const receipt = (await tx2.wait())!; + const consensusReachedEvents = findEventsWithAbi(receipt!, "ConsensusReached", consensus.interface.fragments); expect(consensusReachedEvents.length).to.equal(1); }); - it('reportProcessor starts processing', async () => { + it("reportProcessor starts processing", async () => { await reportProcessor.startReportProcessing(); const consensusState = await consensus.getConsensusState(); expect(consensusState.consensusReport).to.equal(HASH_1); expect(consensusState.isReportProcessing).to.be.true; }); - it('quorum increases while report is processing', async () => { + it("quorum increases while report is processing", async () => { const tx = await consensus.setQuorum(3); - await expect(tx).not.to.emit(consensus, 'ConsensusReached'); - await expect(tx).not.to.emit(consensus, 'ConsensusLost'); + await expect(tx).not.to.emit(consensus, "ConsensusReached"); + await expect(tx).not.to.emit(consensus, "ConsensusLost"); const consensusState = await consensus.getConsensusState(); expect(consensusState.isReportProcessing).to.be.true; expect((await reportProcessor.getLastCall_discardReport()).callCount).to.equal(0); }); - it('quorum decreases but no consensus is triggered', async () => { + it("quorum decreases but no consensus is triggered", async () => { const tx = await consensus.setQuorum(2); - await expect(tx).not.to.emit(consensus, 'ConsensusReached'); - await expect(tx).not.to.emit(consensus, 'ConsensusLost'); + await expect(tx).not.to.emit(consensus, "ConsensusReached"); + await expect(tx).not.to.emit(consensus, "ConsensusLost"); expect((await reportProcessor.getLastCall_submitReport()).callCount).to.equal(1); expect((await reportProcessor.getLastCall_discardReport()).callCount).to.equal(0); }); diff --git a/test/0.8.9/oracle/hashConsensus.submitReport.test.ts b/test/0.8.9/oracle/hashConsensus.submitReport.test.ts index d087c17e5..090dc1d05 100644 --- a/test/0.8.9/oracle/hashConsensus.submitReport.test.ts +++ b/test/0.8.9/oracle/hashConsensus.submitReport.test.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { Signer } from "ethers"; import { ethers } from "hardhat"; -import { HashConsensusTimeTravellable, MockReportProcessor } from "typechain-types"; +import { HashConsensus__Harness, ReportProcessor__Mock } from "typechain-types"; import { CONSENSUS_VERSION } from "lib"; @@ -11,12 +11,12 @@ import { Snapshot } from "test/suite"; const CONSENSUS_VERSION_2 = 2n; -describe("HashConsensus:submitReport", function () { +describe("HashConsensus.sol:submitReport", function () { let admin: Signer; let member1: Signer; let member2: Signer; - let consensus: HashConsensusTimeTravellable; - let reportProcessor: MockReportProcessor; + let consensus: HashConsensus__Harness; + let reportProcessor: ReportProcessor__Mock; let frame: Awaited>; let originalState: string; diff --git a/test/0.8.9/oracleDaemonConfig.test.ts b/test/0.8.9/oracleDaemonConfig.test.ts index b67b25635..a38d510cf 100644 --- a/test/0.8.9/oracleDaemonConfig.test.ts +++ b/test/0.8.9/oracleDaemonConfig.test.ts @@ -7,7 +7,9 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { OracleDaemonConfig, OracleDaemonConfig__factory } from "typechain-types"; -describe("OracleDaemonConfig", () => { +import { Snapshot } from "test/suite"; + +describe("OracleDaemonConfig.sol", () => { let deployer: HardhatEthersSigner; let admin: HardhatEthersSigner; let stranger: HardhatEthersSigner; @@ -16,10 +18,12 @@ describe("OracleDaemonConfig", () => { let oracleDaemonConfig: OracleDaemonConfig; + let originalState: string; + const defaultKey: string = "key1"; const defaultValue: HexString = "0xbec001"; - beforeEach(async () => { + before(async () => { [deployer, admin, stranger, configPrimaryManager, configSecondaryManager] = await ethers.getSigners(); oracleDaemonConfig = await new OracleDaemonConfig__factory(deployer).deploy(admin, [ @@ -29,6 +33,10 @@ describe("OracleDaemonConfig", () => { oracleDaemonConfig = oracleDaemonConfig.connect(stranger); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("constructor", () => { context("Reverts", () => { it("if admin is zero address", async () => { diff --git a/test/0.8.9/sanityChecks/baseOracleReportSanityChecker.test.ts b/test/0.8.9/oracleReportSanityChecker.test.ts similarity index 97% rename from test/0.8.9/sanityChecks/baseOracleReportSanityChecker.test.ts rename to test/0.8.9/oracleReportSanityChecker.test.ts index bab8baf5b..516e600d0 100644 --- a/test/0.8.9/sanityChecks/baseOracleReportSanityChecker.test.ts +++ b/test/0.8.9/oracleReportSanityChecker.test.ts @@ -5,7 +5,13 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { setBalance } from "@nomicfoundation/hardhat-network-helpers"; -import { BurnerStub, LidoLocatorStub, LidoStub, OracleReportSanityChecker, WithdrawalQueueStub } from "typechain-types"; +import { + Burner__MockForOracleSanityChecker, + Lido__MockForOracleSanityChecker, + LidoLocator__MockForOracleSanityChecker, + OracleReportSanityChecker, + WithdrawalQueue__MockForOracleSanityChecker, +} from "typechain-types"; import { ether, getCurrentBlockTimestamp, randomAddress } from "lib"; @@ -13,10 +19,10 @@ import { Snapshot } from "test/suite"; describe("OracleReportSanityChecker.sol", () => { let oracleReportSanityChecker: OracleReportSanityChecker; - let lidoLocatorMock: LidoLocatorStub; - let lidoMock: LidoStub; - let burnerMock: BurnerStub; - let withdrawalQueueMock: WithdrawalQueueStub; + let lidoLocatorMock: LidoLocator__MockForOracleSanityChecker; + let lidoMock: Lido__MockForOracleSanityChecker; + let burnerMock: Burner__MockForOracleSanityChecker; + let withdrawalQueueMock: WithdrawalQueue__MockForOracleSanityChecker; let originalState: string; let managersRoster: Record; @@ -57,15 +63,15 @@ describe("OracleReportSanityChecker.sol", () => { // mine 1024 blocks with block duration 12 seconds await ethers.provider.send("hardhat_mine", ["0x" + Number(1024).toString(16), "0x" + Number(12).toString(16)]); - lidoMock = await ethers.deployContract("LidoStub", []); - withdrawalQueueMock = await ethers.deployContract("WithdrawalQueueStub"); - burnerMock = await ethers.deployContract("BurnerStub"); - lidoLocatorMock = await ethers.deployContract("LidoLocatorStub", [ - await lidoMock.getAddress(), + lidoMock = await ethers.deployContract("Lido__MockForOracleSanityChecker"); + withdrawalQueueMock = await ethers.deployContract("WithdrawalQueue__MockForOracleSanityChecker"); + burnerMock = await ethers.deployContract("Burner__MockForOracleSanityChecker"); + lidoLocatorMock = await ethers.deployContract("LidoLocator__MockForOracleSanityChecker", [ + lidoMock, withdrawalVault, - await withdrawalQueueMock.getAddress(), - elRewardsVault.address, - await burnerMock.getAddress(), + withdrawalQueueMock, + elRewardsVault, + burnerMock, ]); // const accounts = signers.map(s => s.address); @@ -82,7 +88,7 @@ describe("OracleReportSanityChecker.sol", () => { maxPositiveTokenRebaseManagers: accounts.slice(18, 20), }; oracleReportSanityChecker = await ethers.deployContract("OracleReportSanityChecker", [ - await lidoLocatorMock.getAddress(), + lidoLocatorMock, admin, Object.values(defaultLimitsList), Object.values(managersRoster).map((m) => m.map((s) => s.address)), @@ -96,7 +102,7 @@ describe("OracleReportSanityChecker.sol", () => { it("constructor reverts if admin address is zero", async () => { await expect( ethers.deployContract("OracleReportSanityChecker", [ - await lidoLocatorMock.getAddress(), + lidoLocatorMock, ZeroAddress, Object.values(defaultLimitsList), Object.values(managersRoster), @@ -1163,9 +1169,9 @@ describe("OracleReportSanityChecker.sol", () => { const tx = await oracleReportSanityChecker .connect(managersRoster.maxNodeOperatorsPerExtraDataItemCountManagers[0]) .setMaxNodeOperatorsPerExtraDataItemCount(newValue); - expect( - (await oracleReportSanityChecker.getOracleReportLimits()).maxNodeOperatorsPerExtraDataItemCount, - ).to.equal(newValue); + expect((await oracleReportSanityChecker.getOracleReportLimits()).maxNodeOperatorsPerExtraDataItemCount).to.equal( + newValue, + ); await expect(tx) .to.emit(oracleReportSanityChecker, "MaxNodeOperatorsPerExtraDataItemCountSet") .withArgs(newValue); @@ -1185,9 +1191,9 @@ describe("OracleReportSanityChecker.sol", () => { const tx = await oracleReportSanityChecker .connect(managersRoster.maxAccountingExtraDataListItemsCountManagers[0]) .setMaxAccountingExtraDataListItemsCount(newValue); - expect( - (await oracleReportSanityChecker.getOracleReportLimits()).maxAccountingExtraDataListItemsCount, - ).to.equal(newValue); + expect((await oracleReportSanityChecker.getOracleReportLimits()).maxAccountingExtraDataListItemsCount).to.equal( + newValue, + ); await expect(tx).to.emit(oracleReportSanityChecker, "MaxAccountingExtraDataListItemsCountSet").withArgs(newValue); }); diff --git a/test/0.8.9/ossifiableProxy.test.ts b/test/0.8.9/ossifiableProxy.test.ts index 7eec47291..86bdc0681 100644 --- a/test/0.8.9/ossifiableProxy.test.ts +++ b/test/0.8.9/ossifiableProxy.test.ts @@ -2,72 +2,57 @@ import { expect } from "chai"; import { Signer, ZeroAddress } from "ethers"; import { ethers } from "hardhat"; -import { - Initializable__Mock, - Initializable__Mock__factory, - OssifiableProxy, - OssifiableProxy__factory, -} from "typechain-types"; +import { Initializable__Mock, OssifiableProxy } from "typechain-types"; import { Snapshot } from "test/suite"; -describe("OssifiableProxy", () => { +describe("OssifiableProxy.sol", () => { let admin: Signer; let stranger: Signer; let currentImpl: Initializable__Mock; let proxy: OssifiableProxy; - let snapshot: string; let initPayload: string; - let initializableContract: Initializable__Mock__factory; - let ossifiableProxy: OssifiableProxy__factory; - async function takeSnapshot() { - snapshot = await Snapshot.take(); - } + let originalState: string; - async function rollback() { - await Snapshot.restore(snapshot); - } - - beforeEach(async () => { + before(async () => { [admin, stranger] = await ethers.getSigners(); - initializableContract = await ethers.getContractFactory("Initializable__Mock"); - ossifiableProxy = await ethers.getContractFactory("OssifiableProxy"); - currentImpl = await initializableContract.deploy(); - proxy = await ossifiableProxy.deploy(await currentImpl.getAddress(), await admin.getAddress(), "0x"); + currentImpl = await ethers.deployContract("Initializable__Mock"); + proxy = await ethers.deployContract("OssifiableProxy", [currentImpl, admin, "0x"]); initPayload = currentImpl.interface.encodeFunctionData("initialize", [1]); }); - before(takeSnapshot); - after(rollback); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); describe("deploy", () => { it("with empty calldata", async () => { - currentImpl = await initializableContract.deploy(); - proxy = await ossifiableProxy.deploy(await currentImpl.getAddress(), await admin.getAddress(), "0x"); + const impl = await ethers.deployContract("Initializable__Mock"); + const newProxy = await ethers.deployContract("OssifiableProxy", [impl, admin, "0x"]); - const tx = proxy.deploymentTransaction(); - const implInterfaceOnProxyAddr = currentImpl.attach(await proxy.getAddress()) as Initializable__Mock; + const tx = newProxy.deploymentTransaction(); + const implInterfaceOnProxyAddr = impl.attach(await newProxy.getAddress()) as Initializable__Mock; await expect(tx) - .to.emit(proxy, "Upgraded") - .withArgs(await currentImpl.getAddress()); + .to.emit(newProxy, "Upgraded") + .withArgs(await impl.getAddress()); expect(await implInterfaceOnProxyAddr.version()).to.equal(0); }); it("with calldata", async () => { - currentImpl = await initializableContract.deploy(); - proxy = await ossifiableProxy.deploy(await currentImpl.getAddress(), await admin.getAddress(), initPayload); + const impl = await ethers.deployContract("Initializable__Mock"); + const badProxy = await ethers.deployContract("OssifiableProxy", [impl, admin, initPayload]); - const tx = proxy.deploymentTransaction(); - const implInterfaceOnProxyAddr = currentImpl.attach(await proxy.getAddress()) as Initializable__Mock; + const tx = badProxy.deploymentTransaction(); + const implInterfaceOnProxyAddr = impl.attach(await badProxy.getAddress()) as Initializable__Mock; await expect(tx) - .to.emit(proxy, "Upgraded") - .withArgs(await currentImpl.getAddress()) + .to.emit(badProxy, "Upgraded") + .withArgs(await impl.getAddress()) .and.to.emit(implInterfaceOnProxyAddr, "Initialized") .withArgs(1); @@ -112,28 +97,25 @@ describe("OssifiableProxy", () => { describe("proxy__changeAdmin()", () => { it("should fail to change admin when called by a stranger", async () => { - const newAdmin = stranger; await expect( - proxy.connect(stranger).proxy__changeAdmin(await newAdmin.getAddress()), + proxy.connect(stranger).proxy__changeAdmin(await stranger.getAddress()), ).to.be.revertedWithCustomError(proxy, "NotAdmin()"); }); it("should fail to change admin if proxy is ossified", async () => { await proxy.connect(admin).proxy__ossify(); - const newAdmin = stranger; - await expect(proxy.connect(admin).proxy__changeAdmin(await newAdmin.getAddress())).to.be.revertedWithCustomError( + await expect(proxy.connect(admin).proxy__changeAdmin(await stranger.getAddress())).to.be.revertedWithCustomError( proxy, "ProxyIsOssified()", ); }); it("should change admin when called by current admin", async () => { - const newAdmin = stranger; - await expect(proxy.connect(admin).proxy__changeAdmin(await newAdmin.getAddress())) + await expect(proxy.connect(admin).proxy__changeAdmin(await stranger.getAddress())) .to.emit(proxy, "AdminChanged") - .withArgs(await admin.getAddress(), await newAdmin.getAddress()); + .withArgs(await admin.getAddress(), await stranger.getAddress()); - expect(await proxy.proxy__getAdmin()).to.equal(await newAdmin.getAddress()); + expect(await proxy.proxy__getAdmin()).to.equal(await stranger.getAddress()); await expect(proxy.connect(admin).proxy__changeAdmin(admin.getAddress())).to.be.revertedWithCustomError( proxy, @@ -142,21 +124,20 @@ describe("OssifiableProxy", () => { }); it("should fail to change admin to zero address", async () => { - const newAdmin = ZeroAddress; - await expect(proxy.connect(admin).proxy__changeAdmin(newAdmin)).to.be.revertedWith( + await expect(proxy.connect(admin).proxy__changeAdmin(ZeroAddress)).to.be.revertedWith( "ERC1967: new admin is the zero address", ); }); }); describe("proxy__upgradeTo()", () => { - it("reverts with error \"NotAdmin()\" called by stranger", async () => { + it('reverts with error "NotAdmin()" called by stranger', async () => { await expect( proxy.connect(stranger).proxy__upgradeTo(await currentImpl.getAddress()), ).to.be.revertedWithCustomError(proxy, "NotAdmin()"); }); - it("reverts with error \"ProxyIsOssified()\" when called on ossified proxy", async () => { + it('reverts with error "ProxyIsOssified()" when called on ossified proxy', async () => { await proxy.connect(admin).proxy__ossify(); expect(await proxy.proxy__getIsOssified()).to.be.true; @@ -168,8 +149,7 @@ describe("OssifiableProxy", () => { }); it("upgrades proxy to new implementation", async () => { - const NewImplementation = await ethers.getContractFactory("Initializable__Mock", admin); - const newImpl = await NewImplementation.deploy(); + const newImpl = await ethers.deployContract("Initializable__Mock", admin); const tx = await proxy.connect(admin).proxy__upgradeTo(await newImpl.getAddress()); @@ -182,13 +162,13 @@ describe("OssifiableProxy", () => { }); describe("proxy__upgradeToAndCall()", () => { - it("reverts with error \"NotAdmin()\" when called by stranger", async () => { + it('reverts with error "NotAdmin()" when called by stranger', async () => { await expect( proxy.connect(stranger).proxy__upgradeToAndCall(await currentImpl.getAddress(), initPayload, false), ).to.be.revertedWithCustomError(proxy, "NotAdmin()"); }); - it("reverts with error \"ProxyIsOssified()\" when called on ossified proxy", async () => { + it('reverts with error "ProxyIsOssified()" when called on ossified proxy', async () => { await proxy.connect(admin).proxy__ossify(); expect(await proxy.proxy__getIsOssified()).to.be.true; @@ -199,8 +179,7 @@ describe("OssifiableProxy", () => { }); it("upgrades proxy to new implementation when forceCall is false", async () => { - const NewImplementation = await ethers.getContractFactory("Initializable__Mock", admin); - const newImpl = await NewImplementation.deploy(); + const newImpl = await ethers.deployContract("Initializable__Mock", admin); await newImpl.waitForDeployment(); const tx = await proxy.connect(admin).proxy__upgradeToAndCall(await newImpl.getAddress(), initPayload, false); @@ -219,9 +198,7 @@ describe("OssifiableProxy", () => { }); it("upgrades proxy to new implementation when forceCall is true", async () => { - const NewImplementation = await ethers.getContractFactory("Initializable__Mock", admin); - const newImpl = await NewImplementation.deploy(); - + const newImpl = await ethers.deployContract("Initializable__Mock", admin); await newImpl.waitForDeployment(); const tx = await proxy.connect(admin).proxy__upgradeToAndCall(await newImpl.getAddress(), "0x", true); diff --git a/test/0.8.9/positiveTokenRebaseLimiter.t.sol b/test/0.8.9/positiveTokenRebaseLimiter.t.sol index cb739231a..c30089b69 100644 --- a/test/0.8.9/positiveTokenRebaseLimiter.t.sol +++ b/test/0.8.9/positiveTokenRebaseLimiter.t.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -9,358 +8,360 @@ import {Test} from "forge-std/Test.sol"; import {PositiveTokenRebaseLimiter, TokenRebaseLimiterData} from "contracts/0.8.9/lib/PositiveTokenRebaseLimiter.sol"; contract PositiveTokenRebaseLimiterTest is Test { - PositiveTokenRebaseLimiter__Harness public rebaseLimiter; - - // general purpose fuzz test constants - uint256 private constant MAX_PROJECTED_ETH = 200_000_000 * 1 ether; - uint256 private constant MAX_SHARE_RATE_COEF = 1_000; - uint256 private constant MIN_PROTOCOL_ETH = 1 ether; - - // constants for `getSharesToBurnLimit` fuzz cases - uint256 private constant MAX_ETHER_DECREASE_COEF = 1e3; - uint256 private constant REBASE_COMPARISON_TOLERANCE = 1e5; - uint256 private constant SHARE_RATE_PRECISION = 1e27; - - function setUp() public { - rebaseLimiter = new PositiveTokenRebaseLimiter__Harness(); - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_initLimiterStateTooLowLimit(TokenRebaseLimiterData calldata _fuzzData) external { - vm.expectRevert(PositiveTokenRebaseLimiter.TooLowTokenRebaseLimit.selector); - rebaseLimiter.initLimiterState(0, _fuzzData.preTotalPooledEther, _fuzzData.preTotalShares); - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_initLimiterTooHighLimit(TokenRebaseLimiterData calldata _fuzzData) external { - uint256 rebaseLimit = bound( - _fuzzData.positiveRebaseLimit, - PositiveTokenRebaseLimiter.UNLIMITED_REBASE + 1, - type(uint256).max - ); - - vm.expectRevert(PositiveTokenRebaseLimiter.TooHighTokenRebaseLimit.selector); - rebaseLimiter.initLimiterState(rebaseLimit, _fuzzData.preTotalPooledEther, _fuzzData.preTotalShares); - } + PositiveTokenRebaseLimiter__Harness public rebaseLimiter; - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_initLimiterState(TokenRebaseLimiterData calldata _fuzzData) external { - uint256 rebaseLimit = bound(_fuzzData.positiveRebaseLimit, 1, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); - uint256 preTotalPooledEther = bound(_fuzzData.preTotalPooledEther, 0, MAX_PROJECTED_ETH); - uint256 preTotalShares = bound(_fuzzData.preTotalShares, 0, MAX_PROJECTED_ETH); + // general purpose fuzz test constants + uint256 private constant MAX_PROJECTED_ETH = 200_000_000 * 1 ether; + uint256 private constant MAX_SHARE_RATE_COEF = 1_000; + uint256 private constant MIN_PROTOCOL_ETH = 1 ether; - rebaseLimiter.initLimiterState(rebaseLimit, preTotalPooledEther, preTotalShares); + // constants for `getSharesToBurnLimit` fuzz cases + uint256 private constant MAX_ETHER_DECREASE_COEF = 1e3; + uint256 private constant REBASE_COMPARISON_TOLERANCE = 1e5; + uint256 private constant SHARE_RATE_PRECISION = 1e27; - TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); + function setUp() public { + rebaseLimiter = new PositiveTokenRebaseLimiter__Harness(); + } - assertEq(data.preTotalPooledEther, preTotalPooledEther); - assertEq(data.preTotalShares, preTotalShares); - assertEq(data.currentTotalPooledEther, preTotalPooledEther); + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_initLimiterStateTooLowLimit(TokenRebaseLimiterData calldata _fuzzData) external { + vm.expectRevert(PositiveTokenRebaseLimiter.TooLowTokenRebaseLimit.selector); + rebaseLimiter.initLimiterState(0, _fuzzData.preTotalPooledEther, _fuzzData.preTotalShares); + } - if (preTotalPooledEther == 0) { - assertEq(data.positiveRebaseLimit, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_initLimiterTooHighLimit(TokenRebaseLimiterData calldata _fuzzData) external { + uint256 rebaseLimit = bound( + _fuzzData.positiveRebaseLimit, + PositiveTokenRebaseLimiter.UNLIMITED_REBASE + 1, + type(uint256).max + ); + + vm.expectRevert(PositiveTokenRebaseLimiter.TooHighTokenRebaseLimit.selector); + rebaseLimiter.initLimiterState(rebaseLimit, _fuzzData.preTotalPooledEther, _fuzzData.preTotalShares); } - if (data.positiveRebaseLimit != PositiveTokenRebaseLimiter.UNLIMITED_REBASE) { - assertTrue(preTotalPooledEther != 0); - assertEq(data.positiveRebaseLimit, rebaseLimit); - assertEq( - data.maxTotalPooledEther, - preTotalPooledEther + (preTotalPooledEther * rebaseLimit) / PositiveTokenRebaseLimiter.LIMITER_PRECISION_BASE - ); - } else { - assertEq(data.positiveRebaseLimit, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); - assertEq(data.maxTotalPooledEther, type(uint256).max); + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_initLimiterState(TokenRebaseLimiterData calldata _fuzzData) external { + uint256 rebaseLimit = bound(_fuzzData.positiveRebaseLimit, 1, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); + uint256 preTotalPooledEther = bound(_fuzzData.preTotalPooledEther, 0, MAX_PROJECTED_ETH); + uint256 preTotalShares = bound(_fuzzData.preTotalShares, 0, MAX_PROJECTED_ETH); + + rebaseLimiter.initLimiterState(rebaseLimit, preTotalPooledEther, preTotalShares); + + TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); + + assertEq(data.preTotalPooledEther, preTotalPooledEther); + assertEq(data.preTotalShares, preTotalShares); + assertEq(data.currentTotalPooledEther, preTotalPooledEther); + + if (preTotalPooledEther == 0) { + assertEq(data.positiveRebaseLimit, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); + } + + if (data.positiveRebaseLimit != PositiveTokenRebaseLimiter.UNLIMITED_REBASE) { + assertTrue(preTotalPooledEther != 0); + assertEq(data.positiveRebaseLimit, rebaseLimit); + assertEq( + data.maxTotalPooledEther, + preTotalPooledEther + + (preTotalPooledEther * rebaseLimit) / + PositiveTokenRebaseLimiter.LIMITER_PRECISION_BASE + ); + } else { + assertEq(data.positiveRebaseLimit, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); + assertEq(data.maxTotalPooledEther, type(uint256).max); + } } - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_isLimitReached(TokenRebaseLimiterData calldata _fuzzData) external { - rebaseLimiter.setData__harness(_fuzzData); - - bool isLimitReached = rebaseLimiter.isLimitReached(); - if (_fuzzData.currentTotalPooledEther >= _fuzzData.maxTotalPooledEther) { - assertTrue(isLimitReached); - } else { - assertFalse(isLimitReached); + + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_isLimitReached(TokenRebaseLimiterData calldata _fuzzData) external { + rebaseLimiter.setData__harness(_fuzzData); + + bool isLimitReached = rebaseLimiter.isLimitReached(); + if (_fuzzData.currentTotalPooledEther >= _fuzzData.maxTotalPooledEther) { + assertTrue(isLimitReached); + } else { + assertFalse(isLimitReached); + } } - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_decreaseEtherUnlimited(TokenRebaseLimiterData memory _fuzzData, uint256 _etherAmount) external { - _fuzzData.positiveRebaseLimit = PositiveTokenRebaseLimiter.UNLIMITED_REBASE; - rebaseLimiter.setData__harness(_fuzzData); - - rebaseLimiter.decreaseEther(_etherAmount); - - TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); - - // hasn't been changed - assertEq(data.currentTotalPooledEther, _fuzzData.currentTotalPooledEther); - assertEq(data.positiveRebaseLimit, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_decreaseEther(TokenRebaseLimiterData memory _fuzzData, uint256 _etherAmount) external { - _fuzzData.positiveRebaseLimit = bound( - _fuzzData.positiveRebaseLimit, - 1, - PositiveTokenRebaseLimiter.UNLIMITED_REBASE - 1 - ); - _fuzzData.currentTotalPooledEther = bound(_fuzzData.currentTotalPooledEther, 0, MAX_PROJECTED_ETH); - rebaseLimiter.setData__harness(_fuzzData); - _etherAmount = bound(_etherAmount, 0, MAX_PROJECTED_ETH); + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_decreaseEtherUnlimited(TokenRebaseLimiterData memory _fuzzData, uint256 _etherAmount) external { + _fuzzData.positiveRebaseLimit = PositiveTokenRebaseLimiter.UNLIMITED_REBASE; + rebaseLimiter.setData__harness(_fuzzData); + + rebaseLimiter.decreaseEther(_etherAmount); - if (_etherAmount > _fuzzData.currentTotalPooledEther) { - vm.expectRevert(PositiveTokenRebaseLimiter.NegativeTotalPooledEther.selector); - rebaseLimiter.decreaseEther(_etherAmount); - } else { - rebaseLimiter.decreaseEther(_etherAmount); - TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); + TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); - assertEq(data.currentTotalPooledEther, _fuzzData.currentTotalPooledEther - _etherAmount); - assertEq(data.positiveRebaseLimit, _fuzzData.positiveRebaseLimit); + // hasn't been changed + assertEq(data.currentTotalPooledEther, _fuzzData.currentTotalPooledEther); + assertEq(data.positiveRebaseLimit, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); } - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_increaseEtherUnlimited(TokenRebaseLimiterData memory _fuzzData, uint256 _etherAmount) external { - _fuzzData.positiveRebaseLimit = PositiveTokenRebaseLimiter.UNLIMITED_REBASE; - rebaseLimiter.setData__harness(_fuzzData); - - rebaseLimiter.increaseEther(_etherAmount); - - TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); - - assertEq(data.positiveRebaseLimit, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); - // values haven't been changed - assertEq(data.currentTotalPooledEther, _fuzzData.currentTotalPooledEther); - assertEq(data.maxTotalPooledEther, _fuzzData.maxTotalPooledEther); - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_increaseEther(TokenRebaseLimiterData memory _fuzzData, uint256 _etherAmount) external { - _fuzzData.positiveRebaseLimit = bound( - _fuzzData.positiveRebaseLimit, - 1, - PositiveTokenRebaseLimiter.UNLIMITED_REBASE - 1 - ); - _fuzzData.maxTotalPooledEther = bound(_fuzzData.maxTotalPooledEther, 0, MAX_PROJECTED_ETH); - _fuzzData.currentTotalPooledEther = bound(_fuzzData.currentTotalPooledEther, 0, _fuzzData.maxTotalPooledEther); - rebaseLimiter.setData__harness(_fuzzData); + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_decreaseEther(TokenRebaseLimiterData memory _fuzzData, uint256 _etherAmount) external { + _fuzzData.positiveRebaseLimit = bound( + _fuzzData.positiveRebaseLimit, + 1, + PositiveTokenRebaseLimiter.UNLIMITED_REBASE - 1 + ); + _fuzzData.currentTotalPooledEther = bound(_fuzzData.currentTotalPooledEther, 0, MAX_PROJECTED_ETH); + rebaseLimiter.setData__harness(_fuzzData); + + _etherAmount = bound(_etherAmount, 0, MAX_PROJECTED_ETH); + + if (_etherAmount > _fuzzData.currentTotalPooledEther) { + vm.expectRevert(PositiveTokenRebaseLimiter.NegativeTotalPooledEther.selector); + rebaseLimiter.decreaseEther(_etherAmount); + } else { + rebaseLimiter.decreaseEther(_etherAmount); + TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); + + assertEq(data.currentTotalPooledEther, _fuzzData.currentTotalPooledEther - _etherAmount); + assertEq(data.positiveRebaseLimit, _fuzzData.positiveRebaseLimit); + } + } - _etherAmount = bound(_etherAmount, 0, MAX_PROJECTED_ETH); + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_increaseEtherUnlimited(TokenRebaseLimiterData memory _fuzzData, uint256 _etherAmount) external { + _fuzzData.positiveRebaseLimit = PositiveTokenRebaseLimiter.UNLIMITED_REBASE; + rebaseLimiter.setData__harness(_fuzzData); - uint256 consumed = rebaseLimiter.increaseEther(_etherAmount); - TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); + rebaseLimiter.increaseEther(_etherAmount); - assertLe(data.currentTotalPooledEther, data.maxTotalPooledEther); + TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); - if ((_fuzzData.currentTotalPooledEther + _etherAmount) <= _fuzzData.maxTotalPooledEther) { - assertEq(consumed, _etherAmount); - if ((_fuzzData.currentTotalPooledEther + _etherAmount) == _fuzzData.maxTotalPooledEther) { - assertEq(data.currentTotalPooledEther, data.maxTotalPooledEther); - } - } else { - uint256 overlimit = (_fuzzData.currentTotalPooledEther + _etherAmount) - _fuzzData.maxTotalPooledEther; - assertEq(consumed, _etherAmount - overlimit); + assertEq(data.positiveRebaseLimit, PositiveTokenRebaseLimiter.UNLIMITED_REBASE); + // values haven't been changed + assertEq(data.currentTotalPooledEther, _fuzzData.currentTotalPooledEther); + assertEq(data.maxTotalPooledEther, _fuzzData.maxTotalPooledEther); } - assertEq(data.maxTotalPooledEther, _fuzzData.maxTotalPooledEther); - assertEq(data.positiveRebaseLimit, _fuzzData.positiveRebaseLimit); - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_getSharesToBurnLimitUnlimited(TokenRebaseLimiterData memory _fuzzData) external { - _fuzzData.positiveRebaseLimit = PositiveTokenRebaseLimiter.UNLIMITED_REBASE; - rebaseLimiter.setData__harness(_fuzzData); - - uint256 sharesToBurnLimit = rebaseLimiter.getSharesToBurnLimit(); - - assertEq(sharesToBurnLimit, _fuzzData.preTotalShares); - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_getSharesToBurnLimitZeroTVL(TokenRebaseLimiterData memory _fuzzData) external { - _fuzzData.positiveRebaseLimit = bound( - _fuzzData.positiveRebaseLimit, - 1, - PositiveTokenRebaseLimiter.UNLIMITED_REBASE - 1 - ); - _fuzzData.preTotalPooledEther = 0; - rebaseLimiter.setData__harness(_fuzzData); - if (!rebaseLimiter.isLimitReached()) { - vm.expectRevert(); - rebaseLimiter.getSharesToBurnLimit(); + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_increaseEther(TokenRebaseLimiterData memory _fuzzData, uint256 _etherAmount) external { + _fuzzData.positiveRebaseLimit = bound( + _fuzzData.positiveRebaseLimit, + 1, + PositiveTokenRebaseLimiter.UNLIMITED_REBASE - 1 + ); + _fuzzData.maxTotalPooledEther = bound(_fuzzData.maxTotalPooledEther, 0, MAX_PROJECTED_ETH); + _fuzzData.currentTotalPooledEther = bound(_fuzzData.currentTotalPooledEther, 0, _fuzzData.maxTotalPooledEther); + + rebaseLimiter.setData__harness(_fuzzData); + + _etherAmount = bound(_etherAmount, 0, MAX_PROJECTED_ETH); + + uint256 consumed = rebaseLimiter.increaseEther(_etherAmount); + TokenRebaseLimiterData memory data = rebaseLimiter.getData__harness(); + + assertLe(data.currentTotalPooledEther, data.maxTotalPooledEther); + + if ((_fuzzData.currentTotalPooledEther + _etherAmount) <= _fuzzData.maxTotalPooledEther) { + assertEq(consumed, _etherAmount); + if ((_fuzzData.currentTotalPooledEther + _etherAmount) == _fuzzData.maxTotalPooledEther) { + assertEq(data.currentTotalPooledEther, data.maxTotalPooledEther); + } + } else { + uint256 overlimit = (_fuzzData.currentTotalPooledEther + _etherAmount) - _fuzzData.maxTotalPooledEther; + assertEq(consumed, _etherAmount - overlimit); + } + assertEq(data.maxTotalPooledEther, _fuzzData.maxTotalPooledEther); + assertEq(data.positiveRebaseLimit, _fuzzData.positiveRebaseLimit); } - } - - /** - * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs - * forge-config: default.fuzz.runs = 65536 - * forge-config: default.fuzz.max-test-rejects = 0 - */ - function testFuzz_getSharesToBurnLimit(TokenRebaseLimiterData memory _fuzzData) external { + /** - * Review: As PositiveTokenRebaseLimiter uses a limited precision for calculation (only 1e9), - * data boundaries should be reasonable and tight to meet the requirements - * - * The data boundaries might be extended in future versions of the lib by usins the ray math internally (1e27) + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 */ + function testFuzz_getSharesToBurnLimitUnlimited(TokenRebaseLimiterData memory _fuzzData) external { + _fuzzData.positiveRebaseLimit = PositiveTokenRebaseLimiter.UNLIMITED_REBASE; + rebaseLimiter.setData__harness(_fuzzData); - _fuzzData.preTotalPooledEther = bound(_fuzzData.preTotalPooledEther, MIN_PROTOCOL_ETH, MAX_PROJECTED_ETH); - _fuzzData.preTotalShares = bound( - _fuzzData.preTotalShares, - _fuzzData.preTotalPooledEther / MAX_SHARE_RATE_COEF, - _fuzzData.preTotalPooledEther * MAX_SHARE_RATE_COEF - ); - _fuzzData.positiveRebaseLimit = bound( - _fuzzData.positiveRebaseLimit, - 1, - PositiveTokenRebaseLimiter.LIMITER_PRECISION_BASE - ); + uint256 sharesToBurnLimit = rebaseLimiter.getSharesToBurnLimit(); - rebaseLimiter.initLimiterState( - _fuzzData.positiveRebaseLimit, - _fuzzData.preTotalPooledEther, - _fuzzData.preTotalShares - ); + assertEq(sharesToBurnLimit, _fuzzData.preTotalShares); + } - TokenRebaseLimiterData memory initializedData = rebaseLimiter.getData__harness(); + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_getSharesToBurnLimitZeroTVL(TokenRebaseLimiterData memory _fuzzData) external { + _fuzzData.positiveRebaseLimit = bound( + _fuzzData.positiveRebaseLimit, + 1, + PositiveTokenRebaseLimiter.UNLIMITED_REBASE - 1 + ); + _fuzzData.preTotalPooledEther = 0; + rebaseLimiter.setData__harness(_fuzzData); + + if (!rebaseLimiter.isLimitReached()) { + vm.expectRevert(); + rebaseLimiter.getSharesToBurnLimit(); + } + } - initializedData.currentTotalPooledEther = bound( - _fuzzData.currentTotalPooledEther, - _fuzzData.preTotalPooledEther / MAX_ETHER_DECREASE_COEF, // x1000 drop at max - MAX_PROJECTED_ETH - ); + /** + * https://book.getfoundry.sh/reference/config/inline-test-config#in-line-fuzz-configs + * forge-config: default.fuzz.runs = 65536 + * forge-config: default.fuzz.max-test-rejects = 0 + */ + function testFuzz_getSharesToBurnLimit(TokenRebaseLimiterData memory _fuzzData) external { + /** + * Review: As PositiveTokenRebaseLimiter uses a limited precision for calculation (only 1e9), + * data boundaries should be reasonable and tight to meet the requirements + * + * The data boundaries might be extended in future versions of the lib by usins the ray math internally (1e27) + */ + + _fuzzData.preTotalPooledEther = bound(_fuzzData.preTotalPooledEther, MIN_PROTOCOL_ETH, MAX_PROJECTED_ETH); + _fuzzData.preTotalShares = bound( + _fuzzData.preTotalShares, + _fuzzData.preTotalPooledEther / MAX_SHARE_RATE_COEF, + _fuzzData.preTotalPooledEther * MAX_SHARE_RATE_COEF + ); + _fuzzData.positiveRebaseLimit = bound( + _fuzzData.positiveRebaseLimit, + 1, + PositiveTokenRebaseLimiter.LIMITER_PRECISION_BASE + ); + + rebaseLimiter.initLimiterState( + _fuzzData.positiveRebaseLimit, + _fuzzData.preTotalPooledEther, + _fuzzData.preTotalShares + ); + + TokenRebaseLimiterData memory initializedData = rebaseLimiter.getData__harness(); + + initializedData.currentTotalPooledEther = bound( + _fuzzData.currentTotalPooledEther, + _fuzzData.preTotalPooledEther / MAX_ETHER_DECREASE_COEF, // x1000 drop at max + MAX_PROJECTED_ETH + ); + + rebaseLimiter.setData__harness(initializedData); + + uint256 sharesToBurnLimit = rebaseLimiter.getSharesToBurnLimit(); + + if (initializedData.currentTotalPooledEther >= initializedData.maxTotalPooledEther) { + assertEq(sharesToBurnLimit, 0); + } else { + assertLt(sharesToBurnLimit, _fuzzData.preTotalShares); + + uint256 oldShareRate = (_fuzzData.preTotalPooledEther * SHARE_RATE_PRECISION) / _fuzzData.preTotalShares; + uint256 newShareRate = (initializedData.currentTotalPooledEther * SHARE_RATE_PRECISION) / + (_fuzzData.preTotalShares - sharesToBurnLimit); + + uint256 rebase = (((newShareRate - oldShareRate) * PositiveTokenRebaseLimiter.LIMITER_PRECISION_BASE) / + oldShareRate); + + // 0.1 BP difference at max + assertApproxEqAbs( + rebase, + initializedData.positiveRebaseLimit, + PositiveTokenRebaseLimiter.LIMITER_PRECISION_BASE / REBASE_COMPARISON_TOLERANCE + ); + } + } +} - rebaseLimiter.setData__harness(initializedData); +contract PositiveTokenRebaseLimiter__Harness { + using PositiveTokenRebaseLimiter for TokenRebaseLimiterData; - uint256 sharesToBurnLimit = rebaseLimiter.getSharesToBurnLimit(); + TokenRebaseLimiterData trlData; - if (initializedData.currentTotalPooledEther >= initializedData.maxTotalPooledEther) { - assertEq(sharesToBurnLimit, 0); - } else { - assertLt(sharesToBurnLimit, _fuzzData.preTotalShares); + event DataSet( + uint256 preTotalPooledEther, + uint256 preTotalShares, + uint256 currentTotalPooledEther, + uint256 positiveRebaseLimit, + uint256 maxTotalPooledEther + ); + event LimiterStateInitialized(uint256 rebaseLimit, uint256 preTotalPooledEther, uint256 preTotalShares); + event EtherDecreased(uint256 etherAmount); + event EtherIncreased(uint256 etherAmount); - uint256 oldShareRate = (_fuzzData.preTotalPooledEther * SHARE_RATE_PRECISION) / _fuzzData.preTotalShares; - uint256 newShareRate = (initializedData.currentTotalPooledEther * SHARE_RATE_PRECISION) / - (_fuzzData.preTotalShares - sharesToBurnLimit); + function getData__harness() external view returns (TokenRebaseLimiterData memory) { + return trlData; + } - uint256 rebase = (((newShareRate - oldShareRate) * PositiveTokenRebaseLimiter.LIMITER_PRECISION_BASE) / - oldShareRate); + function setData__harness(TokenRebaseLimiterData calldata _data) external { + trlData = _data; - // 0.1 BP difference at max - assertApproxEqAbs( - rebase, - initializedData.positiveRebaseLimit, - PositiveTokenRebaseLimiter.LIMITER_PRECISION_BASE / REBASE_COMPARISON_TOLERANCE - ); + emit DataSet( + _data.preTotalPooledEther, + _data.preTotalShares, + _data.currentTotalPooledEther, + _data.positiveRebaseLimit, + _data.maxTotalPooledEther + ); } - } -} - -contract PositiveTokenRebaseLimiter__Harness { - using PositiveTokenRebaseLimiter for TokenRebaseLimiterData; - - TokenRebaseLimiterData trlData; - - event DataSet( - uint256 preTotalPooledEther, - uint256 preTotalShares, - uint256 currentTotalPooledEther, - uint256 positiveRebaseLimit, - uint256 maxTotalPooledEther - ); - event LimiterStateInitialized(uint256 rebaseLimit, uint256 preTotalPooledEther, uint256 preTotalShares); - event EtherDecreased(uint256 etherAmount); - event EtherIncreased(uint256 etherAmount); - - function getData__harness() external view returns (TokenRebaseLimiterData memory) { - return trlData; - } - - function setData__harness(TokenRebaseLimiterData calldata _data) external { - trlData = _data; - - emit DataSet( - _data.preTotalPooledEther, - _data.preTotalShares, - _data.currentTotalPooledEther, - _data.positiveRebaseLimit, - _data.maxTotalPooledEther - ); - } - function initLimiterState(uint256 _rebaseLimit, uint256 _preTotalPooledEther, uint256 _preTotalShares) external { - trlData = PositiveTokenRebaseLimiter.initLimiterState(_rebaseLimit, _preTotalPooledEther, _preTotalShares); + function initLimiterState(uint256 _rebaseLimit, uint256 _preTotalPooledEther, uint256 _preTotalShares) external { + trlData = PositiveTokenRebaseLimiter.initLimiterState(_rebaseLimit, _preTotalPooledEther, _preTotalShares); - emit LimiterStateInitialized(_rebaseLimit, _preTotalPooledEther, _preTotalShares); - } + emit LimiterStateInitialized(_rebaseLimit, _preTotalPooledEther, _preTotalShares); + } - function isLimitReached() external view returns (bool) { - return trlData.isLimitReached(); - } + function isLimitReached() external view returns (bool) { + return trlData.isLimitReached(); + } - function decreaseEther(uint256 _etherAmount) external { - TokenRebaseLimiterData memory data = trlData; - data.decreaseEther(_etherAmount); - trlData = data; + function decreaseEther(uint256 _etherAmount) external { + TokenRebaseLimiterData memory data = trlData; + data.decreaseEther(_etherAmount); + trlData = data; - emit EtherDecreased(_etherAmount); - } + emit EtherDecreased(_etherAmount); + } - function increaseEther(uint256 _etherAmount) external returns (uint256 consumed) { - TokenRebaseLimiterData memory data = trlData; - consumed = data.increaseEther(_etherAmount); - trlData = data; + function increaseEther(uint256 _etherAmount) external returns (uint256 consumed) { + TokenRebaseLimiterData memory data = trlData; + consumed = data.increaseEther(_etherAmount); + trlData = data; - emit EtherIncreased(_etherAmount); - } + emit EtherIncreased(_etherAmount); + } - function getSharesToBurnLimit() external view returns (uint256 maxSharesToBurn) { - return trlData.getSharesToBurnLimit(); - } + function getSharesToBurnLimit() external view returns (uint256 maxSharesToBurn) { + return trlData.getSharesToBurnLimit(); + } } diff --git a/test/0.8.9/stakingRouter/stakingRouter.misc.test.ts b/test/0.8.9/stakingRouter/stakingRouter.misc.test.ts index 873a7f0f8..4b2afc194 100644 --- a/test/0.8.9/stakingRouter/stakingRouter.misc.test.ts +++ b/test/0.8.9/stakingRouter/stakingRouter.misc.test.ts @@ -4,16 +4,13 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - DepositContract__MockForBeaconChainDepositor, - DepositContract__MockForBeaconChainDepositor__factory, - StakingRouter, - StakingRouter__factory, -} from "typechain-types"; +import { DepositContract__MockForBeaconChainDepositor, StakingRouter } from "typechain-types"; import { certainAddress, ether, proxify } from "lib"; -describe("StakingRouter", () => { +import { Snapshot } from "test/suite"; + +describe("StakingRouter.sol:misc", () => { let deployer: HardhatEthersSigner; let proxyAdmin: HardhatEthersSigner; let stakingRouterAdmin: HardhatEthersSigner; @@ -23,17 +20,23 @@ describe("StakingRouter", () => { let stakingRouterImpl: StakingRouter; let stakingRouter: StakingRouter; + let originalState: string; + const lido = certainAddress("test:staking-router:lido"); const withdrawalCredentials = hexlify(randomBytes(32)); - beforeEach(async () => { + before(async () => { [deployer, proxyAdmin, stakingRouterAdmin, user] = await ethers.getSigners(); - depositContract = await new DepositContract__MockForBeaconChainDepositor__factory(deployer).deploy(); - stakingRouterImpl = await new StakingRouter__factory(deployer).deploy(depositContract); + depositContract = await ethers.deployContract("DepositContract__MockForBeaconChainDepositor", deployer); + stakingRouterImpl = await ethers.deployContract("StakingRouter", [depositContract], deployer); [stakingRouter] = await proxify({ impl: stakingRouterImpl, admin: proxyAdmin, caller: user }); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("initialize", () => { it("Reverts if admin is zero address", async () => { await expect(stakingRouter.initialize(ZeroAddress, lido, withdrawalCredentials)) diff --git a/test/0.8.9/stakingRouter/stakingRouter.module-management.test.ts b/test/0.8.9/stakingRouter/stakingRouter.module-management.test.ts index 3738a3404..51e1abb92 100644 --- a/test/0.8.9/stakingRouter/stakingRouter.module-management.test.ts +++ b/test/0.8.9/stakingRouter/stakingRouter.module-management.test.ts @@ -4,15 +4,11 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - DepositContract__MockForBeaconChainDepositor__factory, - StakingRouter, - StakingRouter__factory, -} from "typechain-types"; +import { StakingRouter } from "typechain-types"; import { certainAddress, getNextBlock, proxify, randomString } from "lib"; -describe("StakingRouter:module-management", () => { +describe("StakingRouter.sol:module-management", () => { let deployer: HardhatEthersSigner; let admin: HardhatEthersSigner; let user: HardhatEthersSigner; @@ -22,8 +18,8 @@ describe("StakingRouter:module-management", () => { beforeEach(async () => { [deployer, admin, user] = await ethers.getSigners(); - const depositContract = await new DepositContract__MockForBeaconChainDepositor__factory(deployer).deploy(); - const impl = await new StakingRouter__factory(deployer).deploy(depositContract); + const depositContract = await ethers.deployContract("DepositContract__MockForBeaconChainDepositor", deployer); + const impl = await ethers.deployContract("StakingRouter", [depositContract], deployer); [stakingRouter] = await proxify({ impl, admin }); @@ -87,7 +83,7 @@ describe("StakingRouter:module-management", () => { ).to.be.revertedWithCustomError(stakingRouter, "StakingModuleWrongName"); }); - it("Reverts if the number of staking modules is reached", async () => { + it("Reverts if the staking module name is too long", async () => { const MAX_STAKING_MODULE_NAME_LENGTH = await stakingRouter.MAX_STAKING_MODULE_NAME_LENGTH(); const NAME_TOO_LONG = randomString(Number(MAX_STAKING_MODULE_NAME_LENGTH + 1n)); diff --git a/test/0.8.9/stakingRouter/stakingRouter.module-sync.test.ts b/test/0.8.9/stakingRouter/stakingRouter.module-sync.test.ts index 2c80abd1a..32f4702f1 100644 --- a/test/0.8.9/stakingRouter/stakingRouter.module-sync.test.ts +++ b/test/0.8.9/stakingRouter/stakingRouter.module-sync.test.ts @@ -5,18 +5,13 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - DepositContract__MockForBeaconChainDepositor, - DepositContract__MockForBeaconChainDepositor__factory, - StakingModule__Mock, - StakingModule__Mock__factory, - StakingRouter, - StakingRouter__factory, -} from "typechain-types"; +import { DepositContract__MockForBeaconChainDepositor, StakingModule__Mock, StakingRouter } from "typechain-types"; import { ether, getNextBlock, proxify } from "lib"; -describe("StakingRouter:module-sync", () => { +import { Snapshot } from "test/suite"; + +describe("StakingRouter.sol:module-sync", () => { let deployer: HardhatEthersSigner; let admin: HardhatEthersSigner; let user: HardhatEthersSigner; @@ -37,11 +32,13 @@ describe("StakingRouter:module-sync", () => { const treasuryFee = 5_00n; const targetShare = 1_00n; - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, admin, user, lido] = await ethers.getSigners(); - depositContract = await new DepositContract__MockForBeaconChainDepositor__factory(deployer).deploy(); - const impl = await new StakingRouter__factory(deployer).deploy(depositContract); + depositContract = await ethers.deployContract("DepositContract__MockForBeaconChainDepositor", deployer); + const impl = await ethers.deployContract("StakingRouter", [depositContract], deployer); [stakingRouter] = await proxify({ impl, admin }); @@ -64,7 +61,7 @@ describe("StakingRouter:module-sync", () => { ]); // add staking module - stakingModule = await new StakingModule__Mock__factory(deployer).deploy(); + stakingModule = await ethers.deployContract("StakingModule__Mock", deployer); stakingModuleAddress = await stakingModule.getAddress(); const { timestamp, number } = await getNextBlock(); lastDepositAt = timestamp; @@ -75,6 +72,10 @@ describe("StakingRouter:module-sync", () => { moduleId = await stakingRouter.getStakingModulesCount(); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("Getters", () => { let stakingModuleInfo: [bigint, string, bigint, bigint, bigint, bigint, string, bigint, bigint, bigint]; diff --git a/test/0.8.9/stakingRouter/stakingRouter.rewards.test.ts b/test/0.8.9/stakingRouter/stakingRouter.rewards.test.ts index 16fa1d31f..06bb96684 100644 --- a/test/0.8.9/stakingRouter/stakingRouter.rewards.test.ts +++ b/test/0.8.9/stakingRouter/stakingRouter.rewards.test.ts @@ -4,30 +4,28 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - DepositContract__MockForBeaconChainDepositor__factory, - StakingModule__Mock, - StakingModule__Mock__factory, - StakingRouter, - StakingRouter__factory, -} from "typechain-types"; +import { StakingModule__Mock, StakingRouter } from "typechain-types"; import { certainAddress, ether, proxify } from "lib"; -describe("StakingRouter:deposits", () => { +import { Snapshot } from "test/suite"; + +describe("StakingRouter.sol:deposits", () => { let deployer: HardhatEthersSigner; let admin: HardhatEthersSigner; let stakingRouter: StakingRouter; + let originalState: string; + const DEPOSIT_VALUE = ether("32.0"); const DEFAULT_CONFIG: ModuleConfig = { targetShare: 100_00n, moduleFee: 5_00n, treasuryFee: 5_00n }; - beforeEach(async () => { + before(async () => { [deployer, admin] = await ethers.getSigners(); - const depositContract = await new DepositContract__MockForBeaconChainDepositor__factory(deployer).deploy(); - const impl = await new StakingRouter__factory(deployer).deploy(depositContract); + const depositContract = await ethers.deployContract("DepositContract__MockForBeaconChainDepositor", deployer); + const impl = await ethers.deployContract("StakingRouter", [depositContract], deployer); [stakingRouter] = await proxify({ impl, admin }); @@ -43,6 +41,10 @@ describe("StakingRouter:deposits", () => { await Promise.all([stakingRouter.grantRole(await stakingRouter.STAKING_MODULE_MANAGE_ROLE(), admin)]); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("getStakingModuleMaxDepositsCount", () => { it("Reverts if the module does not exist", async () => { await expect(stakingRouter.getStakingModuleMaxDepositsCount(1n, 100n)).to.be.revertedWithCustomError( @@ -424,7 +426,7 @@ describe("StakingRouter:deposits", () => { status = Status.Active, }: ModuleConfig): Promise<[StakingModule__Mock, bigint]> { const modulesCount = await stakingRouter.getStakingModulesCount(); - const module = await new StakingModule__Mock__factory(deployer).deploy(); + const module = await ethers.deployContract("StakingModule__Mock", deployer); await stakingRouter .connect(admin) diff --git a/test/0.8.9/stakingRouter/stakingRouter.status-control.test.ts b/test/0.8.9/stakingRouter/stakingRouter.status-control.test.ts index 2a9aadeae..5e5d67e62 100644 --- a/test/0.8.9/stakingRouter/stakingRouter.status-control.test.ts +++ b/test/0.8.9/stakingRouter/stakingRouter.status-control.test.ts @@ -5,21 +5,19 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - DepositContract__MockForBeaconChainDepositor__factory, - StakingRouter, - StakingRouter__factory, -} from "typechain-types"; +import { StakingRouter } from "typechain-types"; import { certainAddress, proxify } from "lib"; +import { Snapshot } from "test/suite"; + enum Status { Active, DepositsPaused, Stopped, } -context("StakingRouter:status-control", () => { +context("StakingRouter.sol:status-control", () => { let deployer: HardhatEthersSigner; let admin: HardhatEthersSigner; let user: HardhatEthersSigner; @@ -27,12 +25,14 @@ context("StakingRouter:status-control", () => { let stakingRouter: StakingRouter; let moduleId: bigint; - beforeEach(async () => { + let originalState: string; + + before(async () => { [deployer, admin, user] = await ethers.getSigners(); // deploy staking router - const depositContract = await new DepositContract__MockForBeaconChainDepositor__factory(deployer).deploy(); - const impl = await new StakingRouter__factory(deployer).deploy(depositContract); + const depositContract = await ethers.deployContract("DepositContract__MockForBeaconChainDepositor", deployer); + const impl = await ethers.deployContract("StakingRouter", [depositContract], deployer); [stakingRouter] = await proxify({ impl, admin }); @@ -61,6 +61,10 @@ context("StakingRouter:status-control", () => { moduleId = await stakingRouter.getStakingModulesCount(); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("setStakingModuleStatus", () => { it("Reverts if the caller does not have the role", async () => { await expect( diff --git a/test/0.8.9/stakingRouter/stakingRouter.versioned.test.ts b/test/0.8.9/stakingRouter/stakingRouter.versioned.test.ts index f59ac1e2a..3a440fde7 100644 --- a/test/0.8.9/stakingRouter/stakingRouter.versioned.test.ts +++ b/test/0.8.9/stakingRouter/stakingRouter.versioned.test.ts @@ -4,7 +4,7 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { OssifiableProxy, StakingRouter, StakingRouter__factory } from "typechain-types"; +import { OssifiableProxy, StakingRouter } from "typechain-types"; import { MAX_UINT256, randomAddress } from "lib"; @@ -25,11 +25,9 @@ describe("StakingRouter:Versioned", () => { impl = await ethers.deployContract("StakingRouter", [depositContract]); - proxy = await ethers.deployContract("OssifiableProxy", [await impl.getAddress(), admin.address, new Uint8Array()], { - from: admin, - }); + proxy = await ethers.deployContract("OssifiableProxy", [impl, admin, new Uint8Array()], admin); - versioned = StakingRouter__factory.connect(await proxy.getAddress(), user); + versioned = await ethers.getContractAt("StakingRouter", proxy, user); }); context("constructor", () => { diff --git a/test/0.8.9/unstructuredStorage.t.sol b/test/0.8.9/unstructuredStorage.t.sol index 23855a03a..1158e7478 100644 --- a/test/0.8.9/unstructuredStorage.t.sol +++ b/test/0.8.9/unstructuredStorage.t.sol @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity 0.8.9; diff --git a/test/0.8.9/utils/accessControl.test.ts b/test/0.8.9/utils/accessControl.test.ts index 8eab08366..ac4e4e6d4 100644 --- a/test/0.8.9/utils/accessControl.test.ts +++ b/test/0.8.9/utils/accessControl.test.ts @@ -18,7 +18,7 @@ import { Snapshot } from "test/suite"; const TEST_ROLE = streccak("TEST_ROLE"); const TEST_ADMIN_ROLE = streccak("TEST_ADMIN_ROLE"); -describe("AccessControl", () => { +describe("AccessControl.sol", () => { let owner: HardhatEthersSigner; let stranger: HardhatEthersSigner; @@ -149,7 +149,7 @@ describe("AccessControl", () => { context("_setRoleAdmin", () => { it("Sets the role's admin role", async () => { - await expect(await contract.exposedSetupAdminRole(TEST_ROLE, TEST_ADMIN_ROLE)) + await expect(await contract.harness__setupAdminRole(TEST_ROLE, TEST_ADMIN_ROLE)) .to.emit(contract, "RoleAdminChanged") .withArgs(TEST_ROLE, DEFAULT_ADMIN_ROLE, TEST_ADMIN_ROLE); diff --git a/test/0.8.9/utils/accessControlEnumerable.test.ts b/test/0.8.9/utils/accessControlEnumerable.test.ts index 24a3a56d6..57b0af983 100644 --- a/test/0.8.9/utils/accessControlEnumerable.test.ts +++ b/test/0.8.9/utils/accessControlEnumerable.test.ts @@ -18,7 +18,7 @@ import { Snapshot } from "test/suite"; const TEST_ROLE = streccak("TEST_ROLE"); -describe("AccessControlEnumerable", () => { +describe("AccessControlEnumerable.sol", () => { let owner: HardhatEthersSigner; let stranger: HardhatEthersSigner; diff --git a/test/0.8.9/utils/pausableUtils.test.ts b/test/0.8.9/utils/pausableUtils.test.ts index 0fcb5f48a..dda1c5386 100644 --- a/test/0.8.9/utils/pausableUtils.test.ts +++ b/test/0.8.9/utils/pausableUtils.test.ts @@ -27,7 +27,7 @@ describe("PausableUtils", () => { }); it("Does not revert if contract is paused", async () => { - await expect(pausable.exposedPauseFor(1000n)).to.emit(pausable, "Paused"); + await expect(pausable.harness__pauseFor(1000n)).to.emit(pausable, "Paused"); await expect(pausable.modifierWhenPaused()).to.not.be.reverted; }); @@ -35,7 +35,7 @@ describe("PausableUtils", () => { context("whenResumed", () => { it("Reverts if contract is paused", async () => { - await expect(pausable.exposedPauseFor(1000n)).to.emit(pausable, "Paused"); + await expect(pausable.harness__pauseFor(1000n)).to.emit(pausable, "Paused"); await expect(pausable.modifierWhenResumed()).to.be.revertedWithCustomError(pausable, "ResumedExpected"); }); @@ -52,7 +52,7 @@ describe("PausableUtils", () => { }); it("Returns true if paused", async () => { - await expect(pausable.exposedPauseFor(1000n)).to.emit(pausable, "Paused"); + await expect(pausable.harness__pauseFor(1000n)).to.emit(pausable, "Paused"); expect(await pausable.isPaused()).to.equal(true); }); @@ -64,7 +64,7 @@ describe("PausableUtils", () => { }); it("Returns the duration since the contract was paused", async () => { - await pausable.exposedPauseFor(1000n); + await pausable.harness__pauseFor(1000n); const timestamp = await time.latest(); expect(await pausable.getResumeSinceTimestamp()).to.equal(timestamp + 1000); @@ -73,66 +73,66 @@ describe("PausableUtils", () => { context("_pauseFor", () => { it("Reverts if contract is already paused", async () => { - await expect(pausable.exposedPauseFor(1000n)).to.emit(pausable, "Paused"); + await expect(pausable.harness__pauseFor(1000n)).to.emit(pausable, "Paused"); - await expect(pausable.exposedPauseFor(1000n)).to.be.revertedWithCustomError(pausable, "ResumedExpected"); + await expect(pausable.harness__pauseFor(1000n)).to.be.revertedWithCustomError(pausable, "ResumedExpected"); }); it("Reverts if zero pause duration", async () => { - await expect(pausable.exposedPauseFor(0)).to.be.revertedWithCustomError(pausable, "ZeroPauseDuration"); + await expect(pausable.harness__pauseFor(0)).to.be.revertedWithCustomError(pausable, "ZeroPauseDuration"); }); it("Pauses contract correctly and emits `Paused` event", async () => { - await expect(pausable.exposedPauseFor(404n)).to.emit(pausable, "Paused").withArgs(404n); + await expect(pausable.harness__pauseFor(404n)).to.emit(pausable, "Paused").withArgs(404n); }); it("Pauses contract to MAX_UINT256 and emits `Paused` event", async () => { - await expect(pausable.exposedPauseFor(MAX_UINT256)).to.emit(pausable, "Paused").withArgs(MAX_UINT256); + await expect(pausable.harness__pauseFor(MAX_UINT256)).to.emit(pausable, "Paused").withArgs(MAX_UINT256); }); }); context("_pauseUntil", () => { it("Reverts if contract is already paused", async () => { - await expect(pausable.exposedPauseFor(1000n)).to.emit(pausable, "Paused"); + await expect(pausable.harness__pauseFor(1000n)).to.emit(pausable, "Paused"); - await expect(pausable.exposedPauseFor(1000n)).to.be.revertedWithCustomError(pausable, "ResumedExpected"); + await expect(pausable.harness__pauseFor(1000n)).to.be.revertedWithCustomError(pausable, "ResumedExpected"); }); it("Reverts if timestamp is in the past", async () => { - await expect(pausable.exposedPauseUntil(0)).to.be.revertedWithCustomError(pausable, "PauseUntilMustBeInFuture"); + await expect(pausable.harness__pauseUntil(0)).to.be.revertedWithCustomError(pausable, "PauseUntilMustBeInFuture"); }); it("Pauses contract correctly and emits `Paused` event", async () => { const timestamp = await time.latest(); - await expect(pausable.exposedPauseUntil(timestamp + 1000)) + await expect(pausable.harness__pauseUntil(timestamp + 1000)) .to.emit(pausable, "Paused") .withArgs(1000n); }); it("Pauses contract to MAX_UINT256 and emits `Paused` event", async () => { - await expect(pausable.exposedPauseUntil(MAX_UINT256)).to.emit(pausable, "Paused").withArgs(MAX_UINT256); + await expect(pausable.harness__pauseUntil(MAX_UINT256)).to.emit(pausable, "Paused").withArgs(MAX_UINT256); }); }); context("_resume", async () => { it("Reverts if contract is not paused", async () => { - await expect(pausable.exposedResume()).to.be.revertedWithCustomError(pausable, "PausedExpected"); + await expect(pausable.harness__resume()).to.be.revertedWithCustomError(pausable, "PausedExpected"); }); it("Resumes the contract", async () => { - await expect(pausable.exposedPauseFor(1000n)).to.emit(pausable, "Paused"); + await expect(pausable.harness__pauseFor(1000n)).to.emit(pausable, "Paused"); - await expect(pausable.exposedResume()).to.emit(pausable, "Resumed"); + await expect(pausable.harness__resume()).to.emit(pausable, "Resumed"); expect(await pausable.isPaused()).to.equal(false); }); it("Reverts if already resumed", async () => { - await expect(pausable.exposedPauseFor(1000n)).to.emit(pausable, "Paused"); + await expect(pausable.harness__pauseFor(1000n)).to.emit(pausable, "Paused"); - await expect(pausable.exposedResume()).to.emit(pausable, "Resumed"); + await expect(pausable.harness__resume()).to.emit(pausable, "Resumed"); - await expect(pausable.exposedResume()).to.be.revertedWithCustomError(pausable, "PausedExpected"); + await expect(pausable.harness__resume()).to.be.revertedWithCustomError(pausable, "PausedExpected"); expect(await pausable.isPaused()).to.equal(false); }); }); @@ -147,19 +147,19 @@ describe("PausableUtils", () => { it("Pauses the contract", async () => { const resumeSinceTimestamp = BigInt(timestamp) + 1000n; - await expect(pausable.exposedSetPauseState(resumeSinceTimestamp)).to.emit(pausable, "Paused").withArgs(999n); // X+1000n - X+1n for the block timestamp + await expect(pausable.harness__setPauseState(resumeSinceTimestamp)).to.emit(pausable, "Paused").withArgs(999n); // X+1000n - X+1n for the block timestamp expect(await pausable.isPaused()).to.equal(true); }); it("Pauses the contract to MAX_UINT256", async () => { - await expect(pausable.exposedSetPauseState(MAX_UINT256)).to.emit(pausable, "Paused"); + await expect(pausable.harness__setPauseState(MAX_UINT256)).to.emit(pausable, "Paused"); expect(await pausable.isPaused()).to.equal(true); }); it("Resumes the contract", async () => { - await expect(pausable.exposedSetPauseState(timestamp + 1)) + await expect(pausable.harness__setPauseState(timestamp + 1)) .to.emit(pausable, "Paused") .withArgs(0n); diff --git a/test/0.8.9/versioned.test.ts b/test/0.8.9/versioned.test.ts index a7f3f1a4e..5fa444a04 100644 --- a/test/0.8.9/versioned.test.ts +++ b/test/0.8.9/versioned.test.ts @@ -7,6 +7,8 @@ import { Versioned__Harness089 } from "typechain-types"; import { MAX_UINT256, proxify, streccak } from "lib"; +import { Snapshot } from "test/suite"; + describe("Versioned.sol", () => { let admin: HardhatEthersSigner; let user: HardhatEthersSigner; @@ -14,10 +16,12 @@ describe("Versioned.sol", () => { let impl: Versioned__Harness089; let consumer: Versioned__Harness089; + let originalState: string; + const initialVersion = 0n; const petrifiedVersion = MAX_UINT256; - beforeEach(async () => { + before(async () => { [admin, user] = await ethers.getSigners(); impl = await ethers.deployContract("Versioned__Harness089"); @@ -28,6 +32,10 @@ describe("Versioned.sol", () => { }); }); + beforeEach(async () => (originalState = await Snapshot.take())); + + afterEach(async () => await Snapshot.restore(originalState)); + context("constructor", () => { it("Petrifies the implementation", async () => { expect(await impl.getContractVersion()).to.equal(petrifiedVersion); diff --git a/test/0.8.9/withdrawalQueue.t.sol b/test/0.8.9/withdrawalQueue.t.sol index 7a5d12db4..8605709ac 100644 --- a/test/0.8.9/withdrawalQueue.t.sol +++ b/test/0.8.9/withdrawalQueue.t.sol @@ -1,5 +1,4 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED // for testing purposes only pragma solidity 0.8.9; @@ -153,7 +152,7 @@ contract WQHandler is CommonBase, StdAssertions, StdUtils { uint256[] memory batches = calculateBatches(ethBudget, maxShareRate); if (batches.length > 0) { - (uint256 eth,) = wq.prefinalize(batches, maxShareRate); + (uint256 eth, ) = wq.prefinalize(batches, maxShareRate); vm.deal(address(this), eth); wq.finalize{value: eth}(batches[batches.length - 1], maxShareRate); diff --git a/test/0.8.9/withdrawalQueue.test.ts b/test/0.8.9/withdrawalQueue.test.ts index 415d0846e..6f3086eba 100644 --- a/test/0.8.9/withdrawalQueue.test.ts +++ b/test/0.8.9/withdrawalQueue.test.ts @@ -6,7 +6,7 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { setBalance, time } from "@nomicfoundation/hardhat-network-helpers"; import { - StETH__MockForWithdrawalQueue, + StETH__HarnessForWithdrawalQueue, WithdrawalsQueue__Harness, WstETH__MockForWithdrawalQueue, } from "typechain-types"; @@ -53,7 +53,7 @@ describe("WithdrawalQueue.sol", () => { let user: HardhatEthersSigner; let oracle: HardhatEthersSigner; - let stEth: StETH__MockForWithdrawalQueue; + let stEth: StETH__HarnessForWithdrawalQueue; let stEthAddress: string; let wstEth: WstETH__MockForWithdrawalQueue; let wstEthAddress: string; @@ -67,10 +67,10 @@ describe("WithdrawalQueue.sol", () => { before(async () => { [owner, stranger, user, oracle] = await ethers.getSigners(); - stEth = await ethers.deployContract("StETH__MockForWithdrawalQueue", []); + stEth = await ethers.deployContract("StETH__HarnessForWithdrawalQueue", []); stEthAddress = await stEth.getAddress(); - wstEth = await ethers.deployContract("WstETH__MockForWithdrawalQueue", [await stEth.getAddress()]); + wstEth = await ethers.deployContract("WstETH__MockForWithdrawalQueue", [stEth]); wstEthAddress = await wstEth.getAddress(); impl = await ethers.deployContract("WithdrawalsQueue__Harness", [wstEthAddress], owner); @@ -270,8 +270,8 @@ describe("WithdrawalQueue.sol", () => { context("requestWithdrawals", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queueAddress, ether("300.00")); }); @@ -343,10 +343,10 @@ describe("WithdrawalQueue.sol", () => { context("requestWithdrawalsWstETH", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(wstEthAddress, shares(100n)); - await stEth.exposedMintShares(user, shares(100n)); - await wstEth.exposedMint(user, ether("100.00")); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(wstEthAddress, shares(100n)); + await stEth.harness__mintShares(user, shares(100n)); + await wstEth.mock__mint(user, ether("100.00")); await wstEth.connect(user).approve(queueAddress, ether("300.00")); }); @@ -420,8 +420,8 @@ describe("WithdrawalQueue.sol", () => { }; beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("100.00")); - await stEth.exposedMintShares(alice, shares(100n)); + await stEth.mock__setTotalPooledEther(ether("100.00")); + await stEth.harness__mintShares(alice, shares(100n)); await stEth.connect(alice).approve(queueAddress, ether("100.00")); }); @@ -434,7 +434,7 @@ describe("WithdrawalQueue.sol", () => { }); it("Reverts bad permit with `INVALID_SIGNATURE`", async () => { - await stEth.workaroundSetIsSignatureValid(false); + await stEth.mock__setIsSignatureValid(false); await expect(queue.connect(alice).requestWithdrawalsWithPermit(requests, owner, permit)).to.be.revertedWith( "INVALID_SIGNATURE", @@ -480,11 +480,11 @@ describe("WithdrawalQueue.sol", () => { const permit = { ...DEFAULT_PERMIT, value: amount }; beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("200.00")); - await stEth.exposedMintShares(wstEthAddress, shares(100n)); - await stEth.exposedMintShares(alice, shares(100n)); + await stEth.mock__setTotalPooledEther(ether("200.00")); + await stEth.harness__mintShares(wstEthAddress, shares(100n)); + await stEth.harness__mintShares(alice, shares(100n)); - await wstEth.exposedMint(alice, ether("100.00")); + await wstEth.mock__mint(alice, ether("100.00")); await wstEth.connect(alice).approve(queueAddress, ether("300.00")); }); @@ -497,7 +497,7 @@ describe("WithdrawalQueue.sol", () => { }); it("Reverts bad permit with `ERC20Permit: invalid signature`", async () => { - await wstEth.workaroundSetIsSignatureValid(false); + await wstEth.mock__setIsSignatureValid(false); await expect( queue.connect(alice).requestWithdrawalsWstETHWithPermit(requests, owner, permit), @@ -539,8 +539,8 @@ describe("WithdrawalQueue.sol", () => { context("getWithdrawalRequests", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("1000.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("1000.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queueAddress, ether("300.00")); }); @@ -557,10 +557,10 @@ describe("WithdrawalQueue.sol", () => { context("getWithdrawalStatus", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("1000.00")); + await stEth.mock__setTotalPooledEther(ether("1000.00")); await setBalance(stEthAddress, ether("1001.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queueAddress, ether("300.00")); }); @@ -603,15 +603,15 @@ describe("WithdrawalQueue.sol", () => { await queue.grantRole(await queue.RESUME_ROLE(), owner); await queue.resume(); - await stEth.mockSetTotalPooledEther(ether("300.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("300.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queueAddress, ether("300.00")); await queue.connect(user).requestWithdrawals(amounts, stranger); await queue.prefinalize(requests, shareRate(1n)); // Only finalize the first request, the second one will be finalized later in the test - await queue.exposedFinalize(1, shareRate(1n), { value: amounts[0] }); + await queue.harness__finalize(1, shareRate(1n), { value: amounts[0] }); lastCheckpointIndex = await queue.getLastCheckpointIndex(); }); @@ -640,7 +640,7 @@ describe("WithdrawalQueue.sol", () => { it("Returns the claimable ether", async () => { await queue.connect(user).requestWithdrawals([], stranger); - await queue.exposedFinalize(2, shareRate(1n), { value: amounts[0] }); // Finalize the second request + await queue.harness__finalize(2, shareRate(1n), { value: amounts[0] }); // Finalize the second request lastCheckpointIndex = await queue.getLastCheckpointIndex(); const hints = await queue.findCheckpointHints(requests, 1, lastCheckpointIndex); @@ -682,9 +682,9 @@ describe("WithdrawalQueue.sol", () => { const requests = [1, 2]; for (const requestId of requests) { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); await queue.prefinalize([requestId], shareRate(1n)); - await queue.exposedFinalize(requestId, shareRate(1n), { value: ether("1.00") }); + await queue.harness__finalize(requestId, shareRate(1n), { value: ether("1.00") }); } const lastCheckpointIndex = await queue.getLastCheckpointIndex(); @@ -721,9 +721,9 @@ describe("WithdrawalQueue.sol", () => { const requests = [1, 2]; for (const requestId of requests) { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); await queue.prefinalize([requestId], shareRate(1n)); - await queue.exposedFinalize(requestId, shareRate(1n), { value: ether("1.00") }); + await queue.harness__finalize(requestId, shareRate(1n), { value: ether("1.00") }); } const lastCheckpointIndex = await queue.getLastCheckpointIndex(); @@ -751,9 +751,9 @@ describe("WithdrawalQueue.sol", () => { const requestId = 1; await setBalance(queueAddress, ether("10.00")); - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); await queue.prefinalize([requestId], shareRate(1n)); - await queue.exposedFinalize(requestId, shareRate(1n), { value: ether("1.00") }); + await queue.harness__finalize(requestId, shareRate(1n), { value: ether("1.00") }); await expect(queue.connect(owner).claimWithdrawal(requestId)) .to.emit(queue, "WithdrawalClaimed") @@ -774,9 +774,9 @@ describe("WithdrawalQueue.sol", () => { await queue.resume(); for (const requestId of requests) { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); await queue.prefinalize([requestId], shareRate(1n)); - await queue.exposedFinalize(requestId, shareRate(1n), { value: ether("1.00") }); + await queue.harness__finalize(requestId, shareRate(1n), { value: ether("1.00") }); } lastCheckpointIndex = await queue.getLastCheckpointIndex(); diff --git a/test/0.8.9/withdrawalQueueBase.test.ts b/test/0.8.9/withdrawalQueueBase.test.ts index 9bf52b1da..30801682a 100644 --- a/test/0.8.9/withdrawalQueueBase.test.ts +++ b/test/0.8.9/withdrawalQueueBase.test.ts @@ -34,9 +34,9 @@ describe("WithdrawalQueueBase.sol", () => { // Required for _findCheckpointHint, _calculateClaimableEther, _calcBatch tests const setUpRequestsState = async (requestsCount: number, finalizedCount: number) => { for (let i = 0; i < requestsCount; i++) { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); if (i < finalizedCount) { - await queue.exposedFinalize(i + 1, ether("1.00"), shareRate(1n)); + await queue.harness__finalize(i + 1, ether("1.00"), shareRate(1n)); } } }; @@ -68,7 +68,7 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Returns the last request id in case queue is not empty", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); expect(await queue.getLastRequestId()).to.equal(1); }); @@ -80,8 +80,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Returns the last finalized request id in case queue is not empty", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedFinalize(1, ether("1.00"), shareRate(1n)); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__finalize(1, ether("1.00"), shareRate(1n)); expect(await queue.getLastFinalizedRequestId()).to.equal(1); }); @@ -93,8 +93,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Returns the locked ether amount in case queue is not empty", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedFinalize(1, ether("1.00"), shareRate(1n)); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__finalize(1, ether("1.00"), shareRate(1n)); expect(await queue.getLockedEtherAmount()).to.equal(ether("1.00")); }); @@ -106,8 +106,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Returns the last checkpoint index in case queue is not empty", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedFinalize(1, ether("1.00"), shareRate(1n)); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__finalize(1, ether("1.00"), shareRate(1n)); expect(await queue.getLastCheckpointIndex()).to.equal(1); }); @@ -119,8 +119,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Returns the number of unfinalized requests in case queue is not empty", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedEnqueue(ether("2.00"), shares(2n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("2.00"), shares(2n), owner); expect(await queue.unfinalizedRequestNumber()).to.equal(2); }); @@ -132,8 +132,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Returns the amount of unfinalized stETH in case queue is not empty", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedEnqueue(ether("2.00"), shares(2n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("2.00"), shares(2n), owner); expect(await queue.unfinalizedStETH()).to.equal(shares(3n)); }); @@ -161,7 +161,7 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Stops on max timestamp", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); const timestamp = await time.latest(); @@ -177,8 +177,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Works correctly on multiple calls", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); const calc1 = await queue.calculateFinalizationBatches( shareRate(1n), @@ -211,8 +211,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Works correctly on multiple calls with multiple batches for discounts", async () => { - await queue.exposedEnqueue(ether("2.00"), shares(1n), owner); - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("2.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); const calc1 = await queue.calculateFinalizationBatches( shareRate(1n), @@ -247,11 +247,11 @@ describe("WithdrawalQueueBase.sol", () => { it("Works for multiple requests above max share rate in different reports", async () => { const maxShareRate = parseUnits("1", 26); // 0.1 - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedSetLastReportTimestamp(await time.latest()); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__setLastReportTimestamp(await time.latest()); - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedSetLastReportTimestamp(await time.latest()); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__setLastReportTimestamp(await time.latest()); const calc1 = await queue.calculateFinalizationBatches( maxShareRate, @@ -286,11 +286,11 @@ describe("WithdrawalQueueBase.sol", () => { it("Works for multiple requests below max share rate in different reports", async () => { const maxShareRate = shareRate(1n); - await queue.exposedEnqueue(ether("10.00"), shares(500n), owner); - await queue.exposedSetLastReportTimestamp(await time.latest()); + await queue.harness__enqueue(ether("10.00"), shares(500n), owner); + await queue.harness__setLastReportTimestamp(await time.latest()); - await queue.exposedEnqueue(ether("10.00"), shares(500n), owner); - await queue.exposedSetLastReportTimestamp(await time.latest()); + await queue.harness__enqueue(ether("10.00"), shares(500n), owner); + await queue.harness__setLastReportTimestamp(await time.latest()); const calc1 = await queue.calculateFinalizationBatches( maxShareRate, @@ -325,7 +325,7 @@ describe("WithdrawalQueueBase.sol", () => { it("Works for budget break", async () => { const budget = ether("0.50"); - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); const calc = await queue.calculateFinalizationBatches( shareRate(1n), @@ -366,8 +366,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Reverts if request id is already finalized", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedFinalize(1, ether("1.00"), shareRate(1n)); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__finalize(1, ether("1.00"), shareRate(1n)); await expect(queue.prefinalize([1], shareRate(1n))) .to.be.revertedWithCustomError(queue, "InvalidRequestId") @@ -375,8 +375,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Reverts if batches are not in ascending order", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedEnqueue(ether("2.00"), shares(2n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("2.00"), shares(2n), owner); await expect(queue.prefinalize([2, 1], shareRate(1n))).to.be.revertedWithCustomError( queue, @@ -385,7 +385,7 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Returns ethToLock and sharesToBurn", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); const result = await queue.prefinalize([1], shareRate(1n)); @@ -394,8 +394,8 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Returns ethToLock and sharesToBurn for discounted", async () => { - await queue.exposedEnqueue(ether("2.00"), shares(1n), owner); - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("2.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); const result = await queue.prefinalize([1, 2], shareRate(1n)); @@ -406,24 +406,24 @@ describe("WithdrawalQueueBase.sol", () => { context("_finalize", () => { it("Reverts if request id is out of queue bounds", async () => { - await expect(queue.exposedFinalize(1, ether("1.00"), shareRate(1n))) + await expect(queue.harness__finalize(1, ether("1.00"), shareRate(1n))) .to.be.revertedWithCustomError(queue, "InvalidRequestId") .withArgs(1); }); it("Reverts if request id is already finalized", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedFinalize(1, ether("1.00"), shareRate(1n)); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__finalize(1, ether("1.00"), shareRate(1n)); - await expect(queue.exposedFinalize(1, ether("1.00"), shareRate(1n))) + await expect(queue.harness__finalize(1, ether("1.00"), shareRate(1n))) .to.be.revertedWithCustomError(queue, "InvalidRequestId") .withArgs(1); }); it("Reverts if amount to finalize is greater than the locked amount", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); - await expect(queue.exposedFinalize(1, ether("2.00"), shareRate(1n))) + await expect(queue.harness__finalize(1, ether("2.00"), shareRate(1n))) .to.be.revertedWithCustomError(queue, "TooMuchEtherToFinalize") .withArgs(ether("2.00"), ether("1.00")); }); @@ -431,7 +431,7 @@ describe("WithdrawalQueueBase.sol", () => { context("_enqueue", () => { it("Enqueues a new request", async () => { - await expect(queue.exposedEnqueue(ether("1.00"), shares(1n), owner)) + await expect(queue.harness__enqueue(ether("1.00"), shares(1n), owner)) .to.emit(queue, "WithdrawalRequested") .withArgs(1, owner.address, owner.address, ether("1.00"), shares(1n)); @@ -439,11 +439,11 @@ describe("WithdrawalQueueBase.sol", () => { }); it("Enqueues multiple requests", async () => { - await expect(queue.exposedEnqueue(ether("1.00"), shares(1n), owner)) + await expect(queue.harness__enqueue(ether("1.00"), shares(1n), owner)) .to.emit(queue, "WithdrawalRequested") .withArgs(1, owner.address, owner.address, ether("1.00"), shares(1n)); - await expect(queue.exposedEnqueue(ether("2.00"), shares(2n), owner)) + await expect(queue.harness__enqueue(ether("2.00"), shares(2n), owner)) .to.emit(queue, "WithdrawalRequested") .withArgs(2, owner.address, owner.address, ether("2.00"), shares(2n)); @@ -453,19 +453,19 @@ describe("WithdrawalQueueBase.sol", () => { context("_getStatus", () => { it("Reverts if request id is out of queue bounds", async () => { - await expect(queue.exposedGetStatus(0)).to.be.revertedWithCustomError(queue, "InvalidRequestId").withArgs(0); + await expect(queue.harness__getStatus(0)).to.be.revertedWithCustomError(queue, "InvalidRequestId").withArgs(0); }); it("Reverts if request out of queue bounds", async () => { - await expect(queue.exposedGetStatus(1)).to.be.revertedWithCustomError(queue, "InvalidRequestId").withArgs(1); + await expect(queue.harness__getStatus(1)).to.be.revertedWithCustomError(queue, "InvalidRequestId").withArgs(1); }); it("Returns the queue status", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); const timestamp = await time.latest(); - const status = await queue.exposedGetStatus(1); + const status = await queue.harness__getStatus(1); expect(status.amountOfStETH).to.equal(shares(1n)); expect(status.amountOfShares).to.equal(shares(1n)); @@ -478,29 +478,29 @@ describe("WithdrawalQueueBase.sol", () => { context("_findCheckpointHint", () => { it("Reverts if request id is 0", async () => { - await expect(queue.exposedFindCheckpointHint(0n, 0n, 1n)) + await expect(queue.harness__findCheckpointHint(0n, 0n, 1n)) .to.revertedWithCustomError(queue, "InvalidRequestId") .withArgs(0); }); it("Reverts if request id is out of queue bounds", async () => { - await expect(queue.exposedFindCheckpointHint(1n, 0n, 1n)) + await expect(queue.harness__findCheckpointHint(1n, 0n, 1n)) .to.revertedWithCustomError(queue, "InvalidRequestId") .withArgs(1); }); it("Reverts if start index is out of queue bounds", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); - await expect(queue.exposedFindCheckpointHint(1n, 0n, 1n)) + await expect(queue.harness__findCheckpointHint(1n, 0n, 1n)) .to.revertedWithCustomError(queue, "InvalidRequestIdRange") .withArgs(0n, 1n); }); it("Reverts if end index is out of queue bounds", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); - await expect(queue.exposedFindCheckpointHint(1n, 1n, 1000n)) + await expect(queue.harness__findCheckpointHint(1n, 1n, 1000n)) .to.revertedWithCustomError(queue, "InvalidRequestIdRange") .withArgs(1n, 1000n); }); @@ -508,79 +508,79 @@ describe("WithdrawalQueueBase.sol", () => { it("Rerurns 0 if last checkpoint id is 0", async () => { await setUpRequestsState(1, 0); - expect(await queue.exposedFindCheckpointHint(1n, 1n, 0n)).to.equal(0); + expect(await queue.harness__findCheckpointHint(1n, 1n, 0n)).to.equal(0); }); it("Returns 0 if request id is greater than last finalized request", async () => { - await queue.exposedSetLastCheckpointIndex(1n); + await queue.harness__setLastCheckpointIndex(1n); await setUpRequestsState(2, 1); - expect(await queue.exposedFindCheckpointHint(2n, 1n, 2n)).to.equal(0); + expect(await queue.harness__findCheckpointHint(2n, 1n, 2n)).to.equal(0); }); it("Returns 0 if start request id is greater than end request id", async () => { - await queue.exposedSetLastCheckpointIndex(1n); + await queue.harness__setLastCheckpointIndex(1n); await setUpRequestsState(2, 1); - expect(await queue.exposedFindCheckpointHint(1n, 2n, 1n)).to.equal(0); + expect(await queue.harness__findCheckpointHint(1n, 2n, 1n)).to.equal(0); }); it("Returns right boundary hint for last checkpoint", async () => { await setUpRequestsState(1, 1); - expect(await queue.exposedFindCheckpointHint(1n, 1n, 1n)).to.equal(1n); + expect(await queue.harness__findCheckpointHint(1n, 1n, 1n)).to.equal(1n); }); it("Returns right boundary hint if request fits right before the next checkpoint", async () => { - await queue.exposedSetLastCheckpointIndex(1n); + await queue.harness__setLastCheckpointIndex(1n); await setUpRequestsState(3, 3); - expect(await queue.exposedFindCheckpointHint(1n, 2n, 2n)).to.equal(2n); + expect(await queue.harness__findCheckpointHint(1n, 2n, 2n)).to.equal(2n); }); it("Returns 0 for right boundary hint request can't be fitted", async () => { - await queue.exposedSetLastCheckpointIndex(3n); + await queue.harness__setLastCheckpointIndex(3n); await setUpRequestsState(3, 1); - expect(await queue.exposedFindCheckpointHint(1n, 1n, 3n)).to.equal(0); + expect(await queue.harness__findCheckpointHint(1n, 1n, 3n)).to.equal(0); }); it("Returns left boundary hint for first request", async () => { await setUpRequestsState(3, 3); - expect(await queue.exposedFindCheckpointHint(1n, 2n, 3n)).to.equal(0); + expect(await queue.harness__findCheckpointHint(1n, 2n, 3n)).to.equal(0); }); it("Returns binary search results", async () => { await setUpRequestsState(3, 3); - expect(await queue.exposedFindCheckpointHint(2n, 1n, 3n)).to.equal(2n); + expect(await queue.harness__findCheckpointHint(2n, 1n, 3n)).to.equal(2n); }); it("Returns binary search results", async () => { await setUpRequestsState(5, 5); - expect(await queue.exposedFindCheckpointHint(3n, 1n, 5n)).to.equal(3n); + expect(await queue.harness__findCheckpointHint(3n, 1n, 5n)).to.equal(3n); }); }); context("_claim", () => { it("Reverts if request id is 0", async () => { - await expect(queue.exposedClaim(0, 1, owner)) + await expect(queue.harness__claim(0, 1, owner)) .to.be.revertedWithCustomError(queue, "InvalidRequestId") .withArgs(0); }); it("Reverts if request id is out of queue bounds", async () => { - await expect(queue.exposedClaim(1, 1, owner)) + await expect(queue.harness__claim(1, 1, owner)) .to.be.revertedWithCustomError(queue, "RequestNotFoundOrNotFinalized") .withArgs(1); }); it("Reverts if request is not finalized", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); - await expect(queue.exposedClaim(1, 1, owner)) + await expect(queue.harness__claim(1, 1, owner)) .to.be.revertedWithCustomError(queue, "RequestNotFoundOrNotFinalized") .withArgs(1); }); @@ -588,29 +588,29 @@ describe("WithdrawalQueueBase.sol", () => { it("Reverts if request is already claimed", async () => { await setBalance(queueAddress, ether("10.00")); - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedFinalize(1, ether("1.00"), shareRate(1n)); - await queue.exposedClaim(1, 1, owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__finalize(1, ether("1.00"), shareRate(1n)); + await queue.harness__claim(1, 1, owner); - await expect(queue.exposedClaim(1, 1, owner)) + await expect(queue.harness__claim(1, 1, owner)) .to.be.revertedWithCustomError(queue, "RequestAlreadyClaimed") .withArgs(1); }); it("Reverts if not enough ether", async () => { - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedFinalize(1, ether("1.00"), shareRate(1n)); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__finalize(1, ether("1.00"), shareRate(1n)); - await expect(queue.exposedClaim(1, 1, owner)).to.be.revertedWithCustomError(queue, "NotEnoughEther"); + await expect(queue.harness__claim(1, 1, owner)).to.be.revertedWithCustomError(queue, "NotEnoughEther"); }); it("Reverts if not owner", async () => { await setBalance(queueAddress, ether("10.00")); - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); - await queue.exposedFinalize(1, ether("1.00"), shareRate(1n)); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); + await queue.harness__finalize(1, ether("1.00"), shareRate(1n)); - await expect(queue.connect(stranger).exposedClaim(1, 1, owner)) + await expect(queue.connect(stranger).harness__claim(1, 1, owner)) .to.be.revertedWithCustomError(queue, "NotOwner") .withArgs(stranger.address, owner.address); }); @@ -618,14 +618,14 @@ describe("WithdrawalQueueBase.sol", () => { it("Claims the request", async () => { await setBalance(queueAddress, ether("10.00")); - await queue.exposedEnqueue(ether("1.00"), shares(1n), owner); + await queue.harness__enqueue(ether("1.00"), shares(1n), owner); await queue.prefinalize([1], shareRate(1n)); - await queue.exposedFinalize(1, ether("1.00"), shareRate(1n)); + await queue.harness__finalize(1, ether("1.00"), shareRate(1n)); const balanceBefore = await provider.getBalance(stranger); const lockedBefore = await queue.getLockedEtherAmount(); - await expect(queue.exposedClaim(1, 1, stranger)) + await expect(queue.harness__claim(1, 1, stranger)) .to.emit(queue, "WithdrawalClaimed") .withArgs(1, owner.address, stranger.address, shares(1n)); @@ -639,13 +639,13 @@ describe("WithdrawalQueueBase.sol", () => { context("_calculateClaimableEther", () => { it("Reverts if hint is 0", async () => { - await expect(queue.exposedCalculateClaimableEther(1, 0)) + await expect(queue.harness__calculateClaimableEther(1, 0)) .to.be.revertedWithCustomError(queue, "InvalidHint") .withArgs(0); }); it("Reverts if request id is 0", async () => { - await expect(queue.exposedCalculateClaimableEther(0, 1)) + await expect(queue.harness__calculateClaimableEther(0, 1)) .to.be.revertedWithCustomError(queue, "InvalidHint") .withArgs(1); }); @@ -653,7 +653,7 @@ describe("WithdrawalQueueBase.sol", () => { it("Reverts if request id is out of hints range", async () => { await setUpRequestsState(3, 3); - await expect(queue.exposedCalculateClaimableEther(1, 3)) + await expect(queue.harness__calculateClaimableEther(1, 3)) .to.be.revertedWithCustomError(queue, "InvalidHint") .withArgs(3); }); @@ -661,7 +661,7 @@ describe("WithdrawalQueueBase.sol", () => { it("Reverts if request id is not in hints range", async () => { await setUpRequestsState(5, 5); - await expect(queue.exposedCalculateClaimableEther(5, 3)) + await expect(queue.harness__calculateClaimableEther(5, 3)) .to.be.revertedWithCustomError(queue, "InvalidHint") .withArgs(3); }); @@ -669,36 +669,36 @@ describe("WithdrawalQueueBase.sol", () => { it("Calculates the claimable ether", async () => { await setUpRequestsState(5, 5); - expect(await queue.exposedCalculateClaimableEther(3, 3)).to.equal(ether("1.00")); + expect(await queue.harness__calculateClaimableEther(3, 3)).to.equal(ether("1.00")); }); it("Calculates the claimable ether taking share rate into account", async () => { - await queue.exposedEnqueue(ether("2.00"), shares(3n), owner); - await queue.exposedEnqueue(ether("2.00"), shares(2n), owner); - await queue.exposedEnqueue(ether("2.00"), shares(1n), owner); - await queue.exposedFinalize(1, ether("2.00"), shareRate(3n)); - await queue.exposedFinalize(2, ether("2.00"), shareRate(2n)); - await queue.exposedFinalize(3, ether("2.00"), shareRate(1n)); + await queue.harness__enqueue(ether("2.00"), shares(3n), owner); + await queue.harness__enqueue(ether("2.00"), shares(2n), owner); + await queue.harness__enqueue(ether("2.00"), shares(1n), owner); + await queue.harness__finalize(1, ether("2.00"), shareRate(3n)); + await queue.harness__finalize(2, ether("2.00"), shareRate(2n)); + await queue.harness__finalize(3, ether("2.00"), shareRate(1n)); - expect(await queue.exposedCalculateClaimableEther(3, 3)).to.equal(ether("1.00")); + expect(await queue.harness__calculateClaimableEther(3, 3)).to.equal(ether("1.00")); }); }); context("_initializeQueue", () => { it("Initializes the queue with default params", async () => { - await queue.exposedInitializeQueue(); + await queue.harness__initializeQueue(); expect(await queue.getLastRequestId()).to.equal(0); expect(await queue.getLastFinalizedRequestId()).to.equal(0); expect(await queue.getLastCheckpointIndex()).to.equal(0); expect(await queue.getLockedEtherAmount()).to.equal(0); - expect(await queue.exposedGetLastReportTimestamp()).to.equal(0); + expect(await queue.harness__getLastReportTimestamp()).to.equal(0); }); }); context("_sendValue", () => { it("Reverts if not enough ether", async () => { - await expect(queue.exposedSendValue(stranger, ether("1.00"))).to.be.revertedWithCustomError( + await expect(queue.harness__sendValue(stranger, ether("1.00"))).to.be.revertedWithCustomError( queue, "NotEnoughEther", ); @@ -707,9 +707,9 @@ describe("WithdrawalQueueBase.sol", () => { it("Reverts if not successful transfer", async () => { await setBalance(queueAddress, ether("10.00")); - await receiver.setCanReceive(false); + await receiver.mock__setCanReceive(false); - await expect(queue.exposedSendValue(receiver, ether("1.00"))).to.be.revertedWithCustomError( + await expect(queue.harness__sendValue(receiver, ether("1.00"))).to.be.revertedWithCustomError( queue, "CantSendValueRecipientMayHaveReverted", ); @@ -720,7 +720,7 @@ describe("WithdrawalQueueBase.sol", () => { const balanceBefore = await provider.getBalance(stranger); - await queue.exposedSendValue(stranger, ether("1.00")); + await queue.harness__sendValue(stranger, ether("1.00")); const balanceAfter = await provider.getBalance(stranger); @@ -748,7 +748,7 @@ describe("WithdrawalQueueBase.sol", () => { cumulativeShares: 2000, }; - const batch = await queue.exposedCalcBatch(prevRequest, request); + const batch = await queue.harness__calcBatch(prevRequest, request); expect(batch.shareRate).to.equal(shareRate(1n), "batch->shareRate"); expect(batch.shares).to.equal(1000, "batch->shares"); @@ -773,7 +773,7 @@ describe("WithdrawalQueueBase.sol", () => { cumulativeShares: 3000, }; - const batch = await queue.exposedCalcBatch(prevRequest, request); + const batch = await queue.harness__calcBatch(prevRequest, request); expect(batch.shareRate).to.equal(shareRate(2n), "batch->shareRate"); expect(batch.shares).to.equal(2000, "batch->shares"); @@ -782,15 +782,15 @@ describe("WithdrawalQueueBase.sol", () => { context("_getLastReportTimestamp", () => { it("Returns 0 if no reports", async () => { - expect(await queue.exposedGetLastReportTimestamp()).to.equal(0); + expect(await queue.harness__getLastReportTimestamp()).to.equal(0); }); it("Returns the last report timestamp", async () => { const timestamp = await time.latest(); - await queue.exposedSetLastReportTimestamp(timestamp); + await queue.harness__setLastReportTimestamp(timestamp); - expect(await queue.exposedGetLastReportTimestamp()).to.equal(timestamp); + expect(await queue.harness__getLastReportTimestamp()).to.equal(timestamp); }); }); @@ -798,7 +798,7 @@ describe("WithdrawalQueueBase.sol", () => { it("Sets the last request id", async () => { expect(await queue.getLastRequestId()).to.equal(0); - await queue.exposedSetLastRequestId(1); + await queue.harness__setLastRequestId(1); expect(await queue.getLastRequestId()).to.equal(1); }); @@ -808,7 +808,7 @@ describe("WithdrawalQueueBase.sol", () => { it("Sets the last finalized request id", async () => { expect(await queue.getLastFinalizedRequestId()).to.equal(0); - await queue.exposedSetLastFinalizedRequestId(1); + await queue.harness__setLastFinalizedRequestId(1); expect(await queue.getLastFinalizedRequestId()).to.equal(1); }); @@ -818,7 +818,7 @@ describe("WithdrawalQueueBase.sol", () => { it("Sets the last checkpoint index", async () => { expect(await queue.getLastCheckpointIndex()).to.equal(0); - await queue.exposedSetLastCheckpointIndex(1); + await queue.harness__setLastCheckpointIndex(1); expect(await queue.getLastCheckpointIndex()).to.equal(1); }); @@ -828,7 +828,7 @@ describe("WithdrawalQueueBase.sol", () => { it("Sets the locked ether amount", async () => { expect(await queue.getLockedEtherAmount()).to.equal(0); - await queue.exposedSetLockedEtherAmount(ether("100.00")); + await queue.harness__setLockedEtherAmount(ether("100.00")); expect(await queue.getLockedEtherAmount()).to.equal(ether("100.00")); }); @@ -838,11 +838,11 @@ describe("WithdrawalQueueBase.sol", () => { it("Sets the last report timestamp", async () => { const timestamp = await time.latest(); - expect(await queue.exposedGetLastReportTimestamp()).to.equal(0); + expect(await queue.harness__getLastReportTimestamp()).to.equal(0); - await queue.exposedSetLastReportTimestamp(timestamp); + await queue.harness__setLastReportTimestamp(timestamp); - expect(await queue.exposedGetLastReportTimestamp()).to.equal(timestamp); + expect(await queue.harness__getLastReportTimestamp()).to.equal(timestamp); }); }); }); diff --git a/test/0.8.9/withdrawalQueueERC721.test.ts b/test/0.8.9/withdrawalQueueERC721.test.ts index e5a4a595d..f68652f23 100644 --- a/test/0.8.9/withdrawalQueueERC721.test.ts +++ b/test/0.8.9/withdrawalQueueERC721.test.ts @@ -6,10 +6,10 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { setBalance } from "@nomicfoundation/hardhat-network-helpers"; import { - ERC721Receiver__MockWithdrawalQueueERC721, + ERC721Receiver__Mock, NFTDescriptor__MockForWithdrawalQueue, Receiver__MockForWithdrawalQueueBase, - StETH__MockForWithdrawalQueue, + StETH__HarnessForWithdrawalQueue, WithdrawalQueueERC721, WstETH__MockForWithdrawalQueue, } from "typechain-types"; @@ -47,7 +47,7 @@ describe("WithdrawalQueueERC721.sol", () => { let nftDescriptor: NFTDescriptor__MockForWithdrawalQueue; let nftDescriptorAddress: string; - let stEth: StETH__MockForWithdrawalQueue; + let stEth: StETH__HarnessForWithdrawalQueue; let stEthAddress: string; let wstEth: WstETH__MockForWithdrawalQueue; let wstEthAddress: string; @@ -66,7 +66,7 @@ describe("WithdrawalQueueERC721.sol", () => { ]); nftDescriptorAddress = await nftDescriptor.getAddress(); - stEth = await ethers.deployContract("StETH__MockForWithdrawalQueue", []); + stEth = await ethers.deployContract("StETH__HarnessForWithdrawalQueue", []); stEthAddress = await stEth.getAddress(); wstEth = await ethers.deployContract("WstETH__MockForWithdrawalQueue", [stEthAddress]); @@ -177,8 +177,8 @@ describe("WithdrawalQueueERC721.sol", () => { const requestId = 1; beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queue, shares(300n)); await queue.resume(); @@ -327,8 +327,8 @@ describe("WithdrawalQueueERC721.sol", () => { context("finalize", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queue, shares(300n)); }); @@ -379,8 +379,8 @@ describe("WithdrawalQueueERC721.sol", () => { }); it("Returns correct balance for token holder", async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queue, shares(300n)); await queue.resume(); await queue.connect(user).requestWithdrawals([ether("25.00"), ether("25.00")], user); @@ -391,8 +391,8 @@ describe("WithdrawalQueueERC721.sol", () => { context("ownerOf", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queue, shares(300n)); await queue.resume(); @@ -425,8 +425,8 @@ describe("WithdrawalQueueERC721.sol", () => { context("approve", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queue, shares(300n)); await queue.resume(); @@ -452,8 +452,8 @@ describe("WithdrawalQueueERC721.sol", () => { context("getApproved", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queue, shares(300n)); await queue.resume(); @@ -506,8 +506,8 @@ describe("WithdrawalQueueERC721.sol", () => { context("safeTransferFrom", () => { context("safeTransferFrom(address,address,uint256)", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queue, shares(300n)); await queue.resume(); @@ -522,20 +522,20 @@ describe("WithdrawalQueueERC721.sol", () => { }); context("safeTransferFrom(address,address,uint256,bytes)", () => { - let erc721ReceiverContract: ERC721Receiver__MockWithdrawalQueueERC721; + let erc721ReceiverContract: ERC721Receiver__Mock; let erc721ReceiverContractAddress: string; let receiverContract: Receiver__MockForWithdrawalQueueBase; let receiverContractAddress: string; beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queue, shares(300n)); await queue.resume(); await queue.connect(user).requestWithdrawals([ether("25.00"), ether("25.00")], user); - erc721ReceiverContract = await ethers.deployContract("ERC721Receiver__MockWithdrawalQueueERC721", []); + erc721ReceiverContract = await ethers.deployContract("ERC721Receiver__Mock", []); erc721ReceiverContractAddress = await erc721ReceiverContract.getAddress(); receiverContract = await ethers.deployContract("Receiver__MockForWithdrawalQueueBase"); @@ -561,26 +561,26 @@ describe("WithdrawalQueueERC721.sol", () => { }); it("Reverts when transfer to IERC721 receiver that does not accept tokens", async () => { - await erc721ReceiverContract.setDoesAcceptTokens(false); + await erc721ReceiverContract.mock__setDoesAcceptTokens(false); await expect( queue .connect(user) [ - "safeTransferFrom(address,address,uint256,bytes)" + "safeTransferFrom(address,address,uint256,bytes)" ](user, erc721ReceiverContractAddress, 1, new Uint8Array()), ).revertedWith("ERC721_NOT_ACCEPT_TOKENS"); }); it("Reverts when transfer to IERC721 receiver that returns not selector", async () => { - await erc721ReceiverContract.setDoesAcceptTokens(true); - await erc721ReceiverContract.setReturnValid(false); + await erc721ReceiverContract.mock__setDoesAcceptTokens(true); + await erc721ReceiverContract.mock__setReturnValid(false); await expect( queue .connect(user) [ - "safeTransferFrom(address,address,uint256,bytes)" + "safeTransferFrom(address,address,uint256,bytes)" ](user, erc721ReceiverContractAddress, 1, new Uint8Array()), ) .revertedWithCustomError(queue, "TransferToNonIERC721Receiver") @@ -588,14 +588,14 @@ describe("WithdrawalQueueERC721.sol", () => { }); it("Transfers token to IERC721 receiver", async () => { - await erc721ReceiverContract.setDoesAcceptTokens(true); - await erc721ReceiverContract.setReturnValid(true); + await erc721ReceiverContract.mock__setDoesAcceptTokens(true); + await erc721ReceiverContract.mock__setReturnValid(true); await expect( queue .connect(user) [ - "safeTransferFrom(address,address,uint256,bytes)" + "safeTransferFrom(address,address,uint256,bytes)" ](user, erc721ReceiverContractAddress, 1, new Uint8Array()), ) .to.emit(queue, "Transfer") @@ -606,8 +606,8 @@ describe("WithdrawalQueueERC721.sol", () => { context("transferFrom", () => { beforeEach(async () => { - await stEth.mockSetTotalPooledEther(ether("600.00")); - await stEth.exposedMintShares(user, shares(300n)); + await stEth.mock__setTotalPooledEther(ether("600.00")); + await stEth.harness__mintShares(user, shares(300n)); await stEth.connect(user).approve(queue, shares(300n)); await queue.resume(); diff --git a/test/0.8.9/withdrawalVault.test.ts b/test/0.8.9/withdrawalVault.test.ts index 670ff4a0c..c953f23d7 100644 --- a/test/0.8.9/withdrawalVault.test.ts +++ b/test/0.8.9/withdrawalVault.test.ts @@ -5,12 +5,7 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { setBalance } from "@nomicfoundation/hardhat-network-helpers"; -import { - ERC20Token__MockForWithdrawalVault, - ERC721Token_MockForWithdrawalVault, - Lido__MockForWithdrawalVault, - WithdrawalVault, -} from "typechain-types"; +import { ERC20__Harness, ERC721__Harness, Lido__MockForWithdrawalVault, WithdrawalVault } from "typechain-types"; import { MAX_UINT256, proxify } from "lib"; @@ -114,11 +109,11 @@ describe("WithdrawalVault.sol", () => { }); context("recoverERC20", () => { - let token: ERC20Token__MockForWithdrawalVault; + let token: ERC20__Harness; let tokenAddress: string; before(async () => { - token = await ethers.deployContract("ERC20Token__MockForWithdrawalVault", ["Test Token", "TT"]); + token = await ethers.deployContract("ERC20__Harness", ["Test Token", "TT"]); tokenAddress = await token.getAddress(); }); @@ -147,11 +142,11 @@ describe("WithdrawalVault.sol", () => { }); context("recoverERC721", () => { - let token: ERC721Token_MockForWithdrawalVault; + let token: ERC721__Harness; let tokenAddress: string; before(async () => { - token = await ethers.deployContract("ERC721Token_MockForWithdrawalVault", ["Test NFT", "tNFT"]); + token = await ethers.deployContract("ERC721__Harness", ["Test NFT", "tNFT"]); tokenAddress = await token.getAddress(); }); diff --git a/test/common/contracts/ERC1271Wallet.sol b/test/common/contracts/ERC1271Wallet.sol index ec641e671..569fcc11a 100644 --- a/test/common/contracts/ERC1271Wallet.sol +++ b/test/common/contracts/ERC1271Wallet.sol @@ -1,4 +1,6 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only + pragma solidity ^0.8.0; import "@openzeppelin/contracts-v4.4/utils/cryptography/ECDSA.sol"; diff --git a/test/common/ecdsa.t.sol b/test/common/ecdsa.t.sol index eb06a92ab..b0193a0da 100644 --- a/test/common/ecdsa.t.sol +++ b/test/common/ecdsa.t.sol @@ -1,9 +1,9 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity >=0.4.24 <0.9.0; -import {Test} from "forge-std/Test.sol"; +import "forge-std/Test.sol"; import {ECDSA} from "contracts/common/lib/ECDSA.sol"; diff --git a/test/common/erc721.test.ts b/test/common/erc721.test.ts index 1ab670d64..ef90bf50e 100644 --- a/test/common/erc721.test.ts +++ b/test/common/erc721.test.ts @@ -5,7 +5,7 @@ import { ExclusiveSuiteFunction, PendingSuiteFunction } from "mocha"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { ERC721, ERC721ReceiverMock } from "typechain-types"; +import { ERC721, ERC721Receiver__Mock } from "typechain-types"; import { ERC165_INTERFACE_ID, ERC721_INTERFACE_ID, ERC721METADATA_INTERFACE_ID, INVALID_INTERFACE_ID } from "lib"; @@ -71,7 +71,7 @@ export function testERC721Compliance({ tokenName, deploy, suiteFunction = descri let spender: HardhatEthersSigner; let newSpender: HardhatEthersSigner; let eoaRecipient: HardhatEthersSigner; - let contractRecipient: ERC721ReceiverMock; + let contractRecipient: ERC721Receiver__Mock; let stranger: HardhatEthersSigner; let originalState: string; @@ -80,7 +80,7 @@ export function testERC721Compliance({ tokenName, deploy, suiteFunction = descri ({ token, name, symbol, holder, holderTokenId } = await deploy()); [spender, newSpender, eoaRecipient, stranger] = await ethers.getSigners(); - contractRecipient = await ethers.deployContract("ERC721ReceiverMock"); + contractRecipient = await ethers.deployContract("ERC721Receiver__Mock"); }); beforeEach(async () => (originalState = await Snapshot.take())); @@ -251,7 +251,7 @@ export function testERC721Compliance({ tokenName, deploy, suiteFunction = descri }); it("Allows the holder to transfer the token to the IERC721 contract", async () => { - await contractRecipient.setDoesAcceptTokens(true); + await contractRecipient.mock__setDoesAcceptTokens(true); await expect( token.connect(spender)["safeTransferFrom(address,address,uint256)"](holder, contractRecipient, holderTokenId), @@ -261,7 +261,7 @@ export function testERC721Compliance({ tokenName, deploy, suiteFunction = descri }); it("Allows the holder to transfer the token to the IERC721 contract (with data)", async () => { - await contractRecipient.setDoesAcceptTokens(true); + await contractRecipient.mock__setDoesAcceptTokens(true); await expect( token diff --git a/test/common/math256.t.sol b/test/common/math256.t.sol index 6ad6b0662..bc5c0431e 100644 --- a/test/common/math256.t.sol +++ b/test/common/math256.t.sol @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity >=0.4.24 <0.9.0; diff --git a/test/common/memUtils.h.sol b/test/common/memUtils.h.sol index c3393041b..bfa5054ad 100644 --- a/test/common/memUtils.h.sol +++ b/test/common/memUtils.h.sol @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity >=0.4.24 <0.9.0; diff --git a/test/common/memUtils.t.sol b/test/common/memUtils.t.sol index 7465868f9..1e10db057 100644 --- a/test/common/memUtils.t.sol +++ b/test/common/memUtils.t.sol @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity >=0.4.24 <0.9.0; @@ -386,9 +386,13 @@ contract MemUtilsTest is Test, MemUtilsTestHelper { } function test_memcpy_CopiesMemChunksShorterThan32Bytes() external pure { - bytes memory src = abi.encodePacked(bytes32(0x1111111111111111111111111111111111111111111111111111111111111111)); + bytes memory src = abi.encodePacked( + bytes32(0x1111111111111111111111111111111111111111111111111111111111111111) + ); - bytes memory dst = abi.encodePacked(bytes32(0x2222222222222222222222222222222222222222222222222222222222222222)); + bytes memory dst = abi.encodePacked( + bytes32(0x2222222222222222222222222222222222222222222222222222222222222222) + ); MemUtils.memcpy(getDataPtr(src), getDataPtr(dst), 5); @@ -396,9 +400,13 @@ contract MemUtilsTest is Test, MemUtilsTestHelper { } function test_memcpy_CopiesMemChunksShorterThan32BytesFromANon32BytesOffset() external pure { - bytes memory src = abi.encodePacked(bytes32(0xcccccccccccccccccccccccccccccccccc8badf00d1234eeeeeeeeeeeeeeeeee)); + bytes memory src = abi.encodePacked( + bytes32(0xcccccccccccccccccccccccccccccccccc8badf00d1234eeeeeeeeeeeeeeeeee) + ); - bytes memory dst = abi.encodePacked(bytes32(0x2222222222222222222222222222222222222222222222222222222222222222)); + bytes memory dst = abi.encodePacked( + bytes32(0x2222222222222222222222222222222222222222222222222222222222222222) + ); MemUtils.memcpy(getDataPtr(src) + 17, getDataPtr(dst), 4); @@ -406,9 +414,13 @@ contract MemUtilsTest is Test, MemUtilsTestHelper { } function test_memcpy_CopiesMemChunksShorterThan32BytesToANon32BytesOffset() external pure { - bytes memory src = abi.encodePacked(bytes32(0x1111111111111111111111111111111111111111111111111111111111111111)); + bytes memory src = abi.encodePacked( + bytes32(0x1111111111111111111111111111111111111111111111111111111111111111) + ); - bytes memory dst = abi.encodePacked(bytes32(0x2222222222222222222222222222222222222222222222222222222222222222)); + bytes memory dst = abi.encodePacked( + bytes32(0x2222222222222222222222222222222222222222222222222222222222222222) + ); MemUtils.memcpy(getDataPtr(src), getDataPtr(dst) + 5, 5); @@ -416,9 +428,13 @@ contract MemUtilsTest is Test, MemUtilsTestHelper { } function test_memcpy_CopiesMemChunksShorterThan32BytesFromAndToANon32BytesOffset() external pure { - bytes memory src = abi.encodePacked(bytes32(0xcccccccccccccccccccccccccccccccccc8badf00d1234eeeeeeeeeeeeeeeeee)); + bytes memory src = abi.encodePacked( + bytes32(0xcccccccccccccccccccccccccccccccccc8badf00d1234eeeeeeeeeeeeeeeeee) + ); - bytes memory dst = abi.encodePacked(bytes32(0x2222222222222222222222222222222222222222222222222222222222222222)); + bytes memory dst = abi.encodePacked( + bytes32(0x2222222222222222222222222222222222222222222222222222222222222222) + ); MemUtils.memcpy(getDataPtr(src) + 17, getDataPtr(dst) + 3, 4); @@ -426,9 +442,13 @@ contract MemUtilsTest is Test, MemUtilsTestHelper { } function test_memcpy_HandlesZeroLength() external pure { - bytes memory src = abi.encodePacked(bytes32(0x1111111111111111111111111111111111111111111111111111111111111111)); + bytes memory src = abi.encodePacked( + bytes32(0x1111111111111111111111111111111111111111111111111111111111111111) + ); - bytes memory dst = abi.encodePacked(bytes32(0x2222222222222222222222222222222222222222222222222222222222222222)); + bytes memory dst = abi.encodePacked( + bytes32(0x2222222222222222222222222222222222222222222222222222222222222222) + ); MemUtils.memcpy(getDataPtr(src) + 11, getDataPtr(dst) + 13, 0); @@ -436,9 +456,13 @@ contract MemUtilsTest is Test, MemUtilsTestHelper { } function test_copyBytes_CopiesMemChunksThatAreMultiplesOf32Bytes() external pure { - bytes memory src = abi.encodePacked(bytes32(0x1111111111111111111111111111111111111111111111111111111111111111)); + bytes memory src = abi.encodePacked( + bytes32(0x1111111111111111111111111111111111111111111111111111111111111111) + ); - bytes memory dst = abi.encodePacked(bytes32(0x2222222222222222222222222222222222222222222222222222222222222222)); + bytes memory dst = abi.encodePacked( + bytes32(0x2222222222222222222222222222222222222222222222222222222222222222) + ); MemUtils.copyBytes(src, dst, 0); @@ -446,9 +470,13 @@ contract MemUtilsTest is Test, MemUtilsTestHelper { } function test_copyBytes_CopiesMemChunksThatAreMultiplesOf32BytesFromANon32BytesOffset() external pure { - bytes memory src = abi.encodePacked(bytes32(0x1111111111111111111111111111111111111111111111111111111111111111)); + bytes memory src = abi.encodePacked( + bytes32(0x1111111111111111111111111111111111111111111111111111111111111111) + ); - bytes memory dst = abi.encodePacked(bytes32(0x2222222222222222222222222222222222222222222222222222222222222222)); + bytes memory dst = abi.encodePacked( + bytes32(0x2222222222222222222222222222222222222222222222222222222222222222) + ); MemUtils.copyBytes(src, dst, 1, 1, 31); @@ -456,9 +484,13 @@ contract MemUtilsTest is Test, MemUtilsTestHelper { } function test_copyBytes_RevertsWhenSrcArrayIsOutOfBounds() external { - bytes memory src = abi.encodePacked(bytes32(0x1111111111111111111111111111111111111111111111111111111111111111)); + bytes memory src = abi.encodePacked( + bytes32(0x1111111111111111111111111111111111111111111111111111111111111111) + ); - bytes memory dst = abi.encodePacked(bytes32(0x2222222222222222222222222222222222222222222222222222222222222222)); + bytes memory dst = abi.encodePacked( + bytes32(0x2222222222222222222222222222222222222222222222222222222222222222) + ); vm.expectRevert(bytes("BYTES_ARRAY_OUT_OF_BOUNDS")); MemUtils.copyBytes(src, dst, 1, 1, 32); diff --git a/test/common/minFirstAllocationStrategy.t.sol b/test/common/minFirstAllocationStrategy.t.sol index 9695dac35..fe283f56b 100644 --- a/test/common/minFirstAllocationStrategy.t.sol +++ b/test/common/minFirstAllocationStrategy.t.sol @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity >=0.4.24 <0.9.0; @@ -28,7 +28,7 @@ contract MinFirstAllocationStrategyInvariants is Test { uint256[] memory capacities = new uint256[](1); uint256 allocationSize = 0; - (uint256 allocated,,) = harness.allocateToBestCandidate(buckets, capacities, allocationSize); + (uint256 allocated, , ) = harness.allocateToBestCandidate(buckets, capacities, allocationSize); assertEq(allocated, 0, "INVALID_ALLOCATED_VALUE"); } @@ -45,7 +45,7 @@ contract MinFirstAllocationStrategyInvariants is Test { capacities[1] = 101; capacities[2] = 100; - (uint256 allocated, uint256[] memory newBuckets,) = harness.allocate(buckets, capacities, allocationSize); + (uint256 allocated, uint256[] memory newBuckets, ) = harness.allocate(buckets, capacities, allocationSize); assertEq(allocated, 101, "INVALID_ALLOCATED_VALUE"); @@ -63,8 +63,8 @@ contract MinFirstAllocationStrategyInvariants is Test { * forge-config: default.invariant.fail-on-revert = true */ function invariant_AllocatedOutput() public view { - (,, uint256 allocatedActual) = handler.getActualOutput(); - (,, uint256 allocatedExpected) = handler.getExpectedOutput(); + (, , uint256 allocatedActual) = handler.getActualOutput(); + (, , uint256 allocatedExpected) = handler.getExpectedOutput(); assertEq(allocatedExpected, allocatedActual, "INVALID_ALLOCATED_VALUE"); } @@ -78,8 +78,8 @@ contract MinFirstAllocationStrategyInvariants is Test { * forge-config: default.invariant.fail-on-revert = true */ function invariant_BucketsOutput() public view { - (uint256[] memory bucketsActual,,) = handler.getActualOutput(); - (uint256[] memory bucketsExpected,,) = handler.getExpectedOutput(); + (uint256[] memory bucketsActual, , ) = handler.getActualOutput(); + (uint256[] memory bucketsExpected, , ) = handler.getExpectedOutput(); for (uint256 i = 0; i < bucketsExpected.length; ++i) { assertEq(bucketsExpected[i], bucketsActual[i], "INVALID_ALLOCATED_VALUE"); @@ -95,8 +95,8 @@ contract MinFirstAllocationStrategyInvariants is Test { * forge-config: default.invariant.fail-on-revert = true */ function invariant_AllocatedBucketValuesNotExceedCapacities() public view { - (uint256[] memory inputBuckets, uint256[] memory inputCapacities,) = handler.getInput(); - (uint256[] memory buckets, uint256[] memory capacities,) = handler.getActualOutput(); + (uint256[] memory inputBuckets, uint256[] memory inputCapacities, ) = handler.getInput(); + (uint256[] memory buckets, uint256[] memory capacities, ) = handler.getActualOutput(); for (uint256 i = 0; i < buckets.length; ++i) { // when bucket initially overloaded skip it from the check @@ -114,8 +114,8 @@ contract MinFirstAllocationStrategyInvariants is Test { * forge-config: default.invariant.fail-on-revert = true */ function invariant_AllocatedMatchesBucketChanges() public view { - (uint256[] memory inputBuckets,,) = handler.getInput(); - (uint256[] memory buckets,, uint256 allocated) = handler.getActualOutput(); + (uint256[] memory inputBuckets, , ) = handler.getInput(); + (uint256[] memory buckets, , uint256 allocated) = handler.getActualOutput(); uint256 inputSum = 0; uint256 outputSum = 0; @@ -137,7 +137,7 @@ contract MinFirstAllocationStrategyInvariants is Test { * forge-config: default.invariant.fail-on-revert = true */ function invariant_AllocatedLessThenAllocationSizeOnlyWhenAllBucketsFilled() public view { - (,, uint256 allocationSize) = handler.getInput(); + (, , uint256 allocationSize) = handler.getInput(); (uint256[] memory buckets, uint256[] memory capacities, uint256 allocated) = handler.getActualOutput(); if (allocationSize == allocated) return; @@ -217,9 +217,11 @@ contract MinFirstAllocationStrategyBase { } contract MinFirstAllocationStrategyAllocateHandler is MinFirstAllocationStrategyBase { - function allocate(uint256[] memory _fuzzBuckets, uint256[] memory _fuzzCapacities, uint256 _fuzzAllocationSize) - public - { + function allocate( + uint256[] memory _fuzzBuckets, + uint256[] memory _fuzzCapacities, + uint256 _fuzzAllocationSize + ) public { _fillTestInput(_fuzzBuckets, _fuzzCapacities, _fuzzAllocationSize); _fillActualAllocateOutput(); @@ -252,21 +254,21 @@ contract MinFirstAllocationStrategyAllocateHandler is MinFirstAllocationStrategy } contract MinFirstAllocationStrategy__Harness { - function allocate(uint256[] memory _buckets, uint256[] memory _capacities, uint256 _allocationSize) - public - pure - returns (uint256 allocated, uint256[] memory newBuckets, uint256[] memory newCapacities) - { + function allocate( + uint256[] memory _buckets, + uint256[] memory _capacities, + uint256 _allocationSize + ) public pure returns (uint256 allocated, uint256[] memory newBuckets, uint256[] memory newCapacities) { allocated = MinFirstAllocationStrategy.allocate(_buckets, _capacities, _allocationSize); newBuckets = _buckets; newCapacities = _capacities; } - function allocateToBestCandidate(uint256[] memory _buckets, uint256[] memory _capacities, uint256 _allocationSize) - public - pure - returns (uint256 allocated, uint256[] memory newBuckets, uint256[] memory newCapacities) - { + function allocateToBestCandidate( + uint256[] memory _buckets, + uint256[] memory _capacities, + uint256 _allocationSize + ) public pure returns (uint256 allocated, uint256[] memory newBuckets, uint256[] memory newCapacities) { allocated = MinFirstAllocationStrategy.allocateToBestCandidate(_buckets, _capacities, _allocationSize); newBuckets = _buckets; newCapacities = _capacities; @@ -276,11 +278,11 @@ contract MinFirstAllocationStrategy__Harness { library NaiveMinFirstAllocationStrategy { uint256 private constant MAX_UINT256 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; - function allocate(uint256[] memory buckets, uint256[] memory capacities, uint256 allocationSize) - internal - pure - returns (uint256 allocated) - { + function allocate( + uint256[] memory buckets, + uint256[] memory capacities, + uint256 allocationSize + ) internal pure returns (uint256 allocated) { while (allocated < allocationSize) { uint256 bestCandidateIndex = MAX_UINT256; uint256 bestCandidateAllocation = MAX_UINT256; diff --git a/test/common/signatureUtils.t.sol b/test/common/signatureUtils.t.sol index bad2dcb22..893e149b6 100644 --- a/test/common/signatureUtils.t.sol +++ b/test/common/signatureUtils.t.sol @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 Lido -// SPDX-License-Identifier: GPL-3.0 +// SPDX-License-Identifier: UNLICENSED +// for testing purposes only pragma solidity >=0.4.24 <0.9.0; @@ -172,11 +172,13 @@ contract SignatureUtilsTest is Test { } contract SignatureUtils__Harness { - function isValidSignature(address signer, bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) - public - view - returns (bool) - { + function isValidSignature( + address signer, + bytes32 msgHash, + uint8 v, + bytes32 r, + bytes32 s + ) public view returns (bool) { return SignatureUtils.isValidSignature(signer, msgHash, v, r, s); } diff --git a/test/deploy/accountingOracle.ts b/test/deploy/accountingOracle.ts index 352e06d87..3526035a8 100644 --- a/test/deploy/accountingOracle.ts +++ b/test/deploy/accountingOracle.ts @@ -1,7 +1,7 @@ import { expect } from "chai"; import { ethers } from "hardhat"; -import { AccountingOracle, HashConsensusTimeTravellable, LegacyOracle, MockReportProcessor } from "typechain-types"; +import { AccountingOracle, HashConsensus__Harness, LegacyOracle, ReportProcessor__Mock } from "typechain-types"; import { CONSENSUS_VERSION, @@ -34,9 +34,9 @@ export async function deployMockLegacyOracle({ } async function deployMockLidoAndStakingRouter() { - const stakingRouter = await ethers.deployContract("MockStakingRouterForAccountingOracle"); - const withdrawalQueue = await ethers.deployContract("MockWithdrawalQueueForAccountingOracle"); - const lido = await ethers.deployContract("MockLidoForAccountingOracle"); + const stakingRouter = await ethers.deployContract("StakingRouter__MockForAccountingOracle"); + const withdrawalQueue = await ethers.deployContract("WithdrawalQueue__MockForAccountingOracle"); + const lido = await ethers.deployContract("Lido__MockForAccountingOracle"); return { lido, stakingRouter, withdrawalQueue }; } @@ -66,7 +66,7 @@ export async function deployAccountingOracleSetup( initialEpoch = (await legacyOracle.getLastCompletedEpochId()) + epochsPerFrame; } - const oracle = await ethers.deployContract("AccountingOracleTimeTravellable", [ + const oracle = await ethers.deployContract("AccountingOracle__Harness", [ lidoLocatorAddr || locatorAddr, lidoAddr || (await lido.getAddress()), legacyOracleAddr || (await legacyOracle.getAddress()), @@ -75,7 +75,7 @@ export async function deployAccountingOracleSetup( ]); const { consensus } = await deployHashConsensus(admin, { - reportProcessor: oracle as unknown as MockReportProcessor, + reportProcessor: oracle as unknown as ReportProcessor__Mock, epochsPerFrame, slotsPerEpoch, secondsPerSlot, @@ -109,7 +109,7 @@ export async function deployAccountingOracleSetup( interface AccountingOracleConfig { admin: string; oracle: AccountingOracle; - consensus: HashConsensusTimeTravellable; + consensus: HashConsensus__Harness; dataSubmitter?: string; consensusVersion?: bigint; shouldMigrateLegacyOracle?: boolean; @@ -161,7 +161,7 @@ async function deployOracleReportSanityCheckerForAccounting(lidoLocator: string, interface AccountingOracleSetup { admin: string; - consensus: HashConsensusTimeTravellable; + consensus: HashConsensus__Harness; oracle: AccountingOracle; legacyOracle: LegacyOracle; dataSubmitter?: string; diff --git a/test/deploy/baseOracle.ts b/test/deploy/baseOracle.ts index 9f456e160..ef47a71cd 100644 --- a/test/deploy/baseOracle.ts +++ b/test/deploy/baseOracle.ts @@ -2,7 +2,7 @@ import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { MockConsensusContract } from "typechain-types"; +import { ConsensusContract__Mock } from "typechain-types"; import { CONSENSUS_VERSION, @@ -38,7 +38,7 @@ export async function deployBaseOracle( secondsPerSlot = SECONDS_PER_SLOT, genesisTime = GENESIS_TIME, slotsPerEpoch = SLOTS_PER_EPOCH, - consensusContract = null as MockConsensusContract | null, + consensusContract = null as ConsensusContract__Mock | null, epochsPerFrame = EPOCHS_PER_FRAME, fastLaneLengthSlots = INITIAL_FAST_LANE_LENGTH_SLOTS, initialEpoch = INITIAL_EPOCH, @@ -46,7 +46,7 @@ export async function deployBaseOracle( } = {}, ) { if (!consensusContract) { - consensusContract = await ethers.deployContract("MockConsensusContract", [ + consensusContract = await ethers.deployContract("ConsensusContract__Mock", [ slotsPerEpoch, secondsPerSlot, genesisTime, diff --git a/test/deploy/dao.ts b/test/deploy/dao.ts index 782386c5a..615b23e2b 100644 --- a/test/deploy/dao.ts +++ b/test/deploy/dao.ts @@ -1,17 +1,9 @@ import { BaseContract } from "ethers"; +import { ethers } from "hardhat"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { - ACL__factory, - DAOFactory__factory, - EIP712StETH__factory, - EVMScriptRegistryFactory__factory, - Kernel, - Kernel__factory, - Lido__factory, - LidoLocator, -} from "typechain-types"; +import { Kernel, LidoLocator } from "typechain-types"; import { ether, findEvents, streccak } from "lib"; @@ -31,17 +23,21 @@ interface DeployLidoDaoArgs { } async function createAragonDao(rootAccount: HardhatEthersSigner) { - const kernelBase = await new Kernel__factory(rootAccount).deploy(true); - const aclBase = await new ACL__factory(rootAccount).deploy(); - const EvmScriptRegistryFactory = await new EVMScriptRegistryFactory__factory(rootAccount).deploy(); - const daoFactory = await new DAOFactory__factory(rootAccount).deploy(kernelBase, aclBase, EvmScriptRegistryFactory); + const kernelBase = await ethers.deployContract("Kernel", [true], rootAccount); + const aclBase = await ethers.deployContract("ACL", rootAccount); + const evmScriptRegistryFactory = await ethers.deployContract("EVMScriptRegistryFactory", rootAccount); + const daoFactory = await ethers.deployContract( + "DAOFactory", + [kernelBase, aclBase, evmScriptRegistryFactory], + rootAccount, + ); const tx = await daoFactory.newDAO(rootAccount); const txReceipt = await tx.wait(); const daoAddress = findEvents(txReceipt!, "DeployDAO")[0].args[0]; - const dao = Kernel__factory.connect(daoAddress, rootAccount); - const acl = ACL__factory.connect(await dao.acl(), rootAccount); + const dao = await ethers.getContractAt("Kernel", daoAddress, rootAccount); + const acl = await ethers.getContractAt("ACL", await dao.acl(), rootAccount); const APP_MANAGER_ROLE = await kernelBase.APP_MANAGER_ROLE(); await acl.createPermission(rootAccount, await dao.getAddress(), APP_MANAGER_ROLE, rootAccount); @@ -66,7 +62,7 @@ export async function addAragonApp({ dao, name, impl, rootAccount }: CreateAddAp export async function deployLidoDao({ rootAccount, initialized, locatorConfig = {} }: DeployLidoDaoArgs) { const { dao, acl } = await createAragonDao(rootAccount); - const impl = await new Lido__factory(rootAccount).deploy(); + const impl = await ethers.deployContract("Lido", rootAccount); const lidoProxyAddress = await addAragonApp({ dao, @@ -75,11 +71,11 @@ export async function deployLidoDao({ rootAccount, initialized, locatorConfig = rootAccount, }); - const lido = Lido__factory.connect(lidoProxyAddress, rootAccount); + const lido = await ethers.getContractAt("Lido", lidoProxyAddress, rootAccount); if (initialized) { const locator = await deployLidoLocator({ lido, ...locatorConfig }, rootAccount); - const eip712steth = await new EIP712StETH__factory(rootAccount).deploy(lido); + const eip712steth = await ethers.deployContract("EIP712StETH", [lido], rootAccount); await lido.initialize(locator, eip712steth, { value: ether("1.0") }); } diff --git a/test/deploy/hashConsensus.ts b/test/deploy/hashConsensus.ts index 236570bf4..e8c2d306e 100644 --- a/test/deploy/hashConsensus.ts +++ b/test/deploy/hashConsensus.ts @@ -1,6 +1,6 @@ import { ethers } from "hardhat"; -import { MockReportProcessor } from "typechain-types"; +import { ReportProcessor__Mock } from "typechain-types"; import { CONSENSUS_VERSION, @@ -13,7 +13,7 @@ import { } from "lib"; export interface DeployHashConsensusParams { - reportProcessor?: MockReportProcessor; + reportProcessor?: ReportProcessor__Mock; slotsPerEpoch?: bigint | undefined; secondsPerSlot?: bigint | undefined; genesisTime?: bigint | undefined; @@ -35,10 +35,10 @@ export async function deployHashConsensus( }: DeployHashConsensusParams = {}, ) { if (!reportProcessor) { - reportProcessor = await ethers.deployContract("MockReportProcessor", [CONSENSUS_VERSION]); + reportProcessor = await ethers.deployContract("ReportProcessor__Mock", [CONSENSUS_VERSION]); } - const consensus = await ethers.deployContract("HashConsensusTimeTravellable", [ + const consensus = await ethers.deployContract("HashConsensus__Harness", [ slotsPerEpoch, secondsPerSlot, genesisTime, diff --git a/test/deploy/locator.ts b/test/deploy/locator.ts index 84e63a22e..3fbf3bdb1 100644 --- a/test/deploy/locator.ts +++ b/test/deploy/locator.ts @@ -28,6 +28,7 @@ async function deployDummyLocator(config?: Partial, de validatorsExitBusOracle: certainAddress("dummy-locator:validatorsExitBusOracle"), withdrawalQueue: certainAddress("dummy-locator:withdrawalQueue"), withdrawalVault: certainAddress("dummy-locator:withdrawalVault"), + wstEth: certainAddress("dummy-locator:wstEth"), ...config, }); @@ -102,6 +103,7 @@ async function getLocatorConfig(locatorAddress: string) { "withdrawalQueue", "withdrawalVault", "oracleDaemonConfig", + "wstEth", ] as Partial[]; const configPromises = addresses.map((name) => locator[name]()); diff --git a/test/deploy/withdrawalQueue.ts b/test/deploy/withdrawalQueue.ts index f51599b68..8f9c0f6e8 100644 --- a/test/deploy/withdrawalQueue.ts +++ b/test/deploy/withdrawalQueue.ts @@ -6,9 +6,9 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { NFTDescriptor__MockForWithdrawalQueue, OssifiableProxy, - StETHPermit__MockForWithdrawalQueueDeploy, + StETHPermit__HarnessForWithdrawalQueueDeploy, WithdrawalQueueERC721, - WstETH__MockForWithdrawalQueueDeploy, + WstETH__HarnessForWithdrawalQueueDeploy, } from "typechain-types"; import { ONE_ETHER, proxify, WITHDRAWAL_QUEUE_NAME, WITHDRAWAL_QUEUE_SYMBOL } from "lib"; @@ -40,13 +40,15 @@ interface WithdrawalQueueDeploymentParams extends BaseWithdrawalQueueDeploymentP export const MOCK_NFT_DESCRIPTOR_BASE_URI = "https://example-descriptor.com/"; async function deployNftDescriptor() { - const nftDescriptor = await ethers.deployContract("NFTDescriptor__MockForWithdrawalQueue", [MOCK_NFT_DESCRIPTOR_BASE_URI]); + const nftDescriptor = await ethers.deployContract("NFTDescriptor__MockForWithdrawalQueue", [ + MOCK_NFT_DESCRIPTOR_BASE_URI, + ]); return { nftDescriptor, nftDescriptorAddress: await nftDescriptor.getAddress() }; } async function deployStEthMock(stEthSettings: StEthDeploymentParams) { - const stEth = await ethers.deployContract("StETHPermit__MockForWithdrawalQueueDeploy", { + const stEth = await ethers.deployContract("StETHPermit__HarnessForWithdrawalQueueDeploy", { value: stEthSettings.initialStEth, }); @@ -67,7 +69,7 @@ async function deployStEthMock(stEthSettings: StEthDeploymentParams) { } async function deployWstEthMock(stEthAddress: string) { - const wstEth = await ethers.deployContract("WstETH__MockForWithdrawalQueueDeploy", [stEthAddress]); + const wstEth = await ethers.deployContract("WstETH__HarnessForWithdrawalQueueDeploy", [stEthAddress]); return { wstEth, wstEthAddress: await wstEth.getAddress() }; } @@ -117,9 +119,9 @@ export async function deployWithdrawalQueue({ name: string; symbol: string; initTx: ContractTransactionResponse | null; - stEth: StETHPermit__MockForWithdrawalQueueDeploy; + stEth: StETHPermit__HarnessForWithdrawalQueueDeploy; stEthAddress: string; - wstEth: WstETH__MockForWithdrawalQueueDeploy; + wstEth: WstETH__HarnessForWithdrawalQueueDeploy; wstEthAddress: string; nftDescriptor: NFTDescriptor__MockForWithdrawalQueue; nftDescriptorAddress: string; diff --git a/test/integration/protocol-happy-path.ts b/test/integration/protocol-happy-path.ts index eade6bf90..e798eb4a9 100644 --- a/test/integration/protocol-happy-path.ts +++ b/test/integration/protocol-happy-path.ts @@ -152,17 +152,23 @@ describe("Happy Path", () => { const sharesToBeMinted = await lido.getSharesByPooledEth(AMOUNT); const mintedShares = await lido.sharesOf(stranger); - expect(submittedEvent?.args.toObject()).to.deep.equal({ - sender: stranger.address, - amount: AMOUNT, - referral: ZeroAddress, - }, "Submitted event"); - - expect(transferSharesEvent?.args.toObject()).to.deep.equal({ - from: ZeroAddress, - to: stranger.address, - sharesValue: sharesToBeMinted, - }, "TransferShares event"); + expect(submittedEvent?.args.toObject()).to.deep.equal( + { + sender: stranger.address, + amount: AMOUNT, + referral: ZeroAddress, + }, + "Submitted event", + ); + + expect(transferSharesEvent?.args.toObject()).to.deep.equal( + { + from: ZeroAddress, + to: stranger.address, + sharesValue: sharesToBeMinted, + }, + "TransferShares event", + ); expect(mintedShares).to.equal(sharesToBeMinted, "Minted shares"); @@ -230,7 +236,10 @@ describe("Happy Path", () => { expectedBufferedEtherAfterDeposit -= unbufferedAmountSdvt; expect(depositCountsTotal).to.be.gt(0n, "Deposit counts"); - expect(newValidatorsCountSdvt).to.equal(depositedValidatorsBefore + depositCountsTotal, "New validators count after deposit"); + expect(newValidatorsCountSdvt).to.equal( + depositedValidatorsBefore + depositCountsTotal, + "New validators count after deposit", + ); } const bufferedEtherAfterDeposit = await lido.getBufferedEther(); @@ -337,27 +346,39 @@ describe("Happy Path", () => { expect(transferEvents.length).to.equal(expectedTransferEvents, "Transfer events count"); - expect(toBurnerTransfer?.args.toObject()).to.include({ - from: withdrawalQueue.address, - to: burner.address, - }, "Transfer to burner"); + expect(toBurnerTransfer?.args.toObject()).to.include( + { + from: withdrawalQueue.address, + to: burner.address, + }, + "Transfer to burner", + ); - expect(toNorTransfer?.args.toObject()).to.include({ - from: ZeroAddress, - to: nor.address, - }, "Transfer to NOR"); + expect(toNorTransfer?.args.toObject()).to.include( + { + from: ZeroAddress, + to: nor.address, + }, + "Transfer to NOR", + ); if (ctx.flags.withSimpleDvtModule) { - expect(toSdvtTransfer?.args.toObject()).to.include({ - from: ZeroAddress, - to: sdvt.address, - }, "Transfer to SDVT"); + expect(toSdvtTransfer?.args.toObject()).to.include( + { + from: ZeroAddress, + to: sdvt.address, + }, + "Transfer to SDVT", + ); } - expect(toTreasuryTransfer?.args.toObject()).to.include({ - from: ZeroAddress, - to: treasuryAddress, - }, "Transfer to Treasury"); + expect(toTreasuryTransfer?.args.toObject()).to.include( + { + from: ZeroAddress, + to: treasuryAddress, + }, + "Transfer to Treasury", + ); const treasurySharesMinted = await lido.getSharesByPooledEth(toTreasuryTransfer.args.value); @@ -374,11 +395,14 @@ describe("Happy Path", () => { ); const transfers = ctx.getEvents(extraDataTxReceipt, "Transfer"); - const burnerTransfers = transfers.filter(e => e?.args[1] == burner.address).length; + const burnerTransfers = transfers.filter((e) => e?.args[1] == burner.address).length; expect(burnerTransfers).to.equal(expectedBurnerTransfers, "Burner transfers is correct"); - expect(transfers.length).to.equal(expectedTransfers + expectedBurnerTransfers, "All active operators received transfers"); + expect(transfers.length).to.equal( + expectedTransfers + expectedBurnerTransfers, + "All active operators received transfers", + ); log.debug("Transfers", { "Transfers to operators": expectedTransfers, @@ -401,7 +425,9 @@ describe("Happy Path", () => { it("Should allow stETH holder to request withdrawals", async () => { const { lido, withdrawalQueue } = ctx.contracts; - const withdrawalsFromStrangerBeforeRequest = await withdrawalQueue.connect(stranger).getWithdrawalRequests(stranger); + const withdrawalsFromStrangerBeforeRequest = await withdrawalQueue + .connect(stranger) + .getWithdrawalRequests(stranger); expect(withdrawalsFromStrangerBeforeRequest.length).to.equal(0, "Withdrawals from stranger"); @@ -421,24 +447,33 @@ describe("Happy Path", () => { const approveEvent = ctx.getEvents(approveTxReceipt, "Approval")[0]; - expect(approveEvent?.args.toObject()).to.deep.include({ - owner: stranger.address, - spender: withdrawalQueue.address, - value: amountWithRewards, - }, "Approval event"); + expect(approveEvent?.args.toObject()).to.deep.include( + { + owner: stranger.address, + spender: withdrawalQueue.address, + value: amountWithRewards, + }, + "Approval event", + ); const lastRequestIdBefore = await withdrawalQueue.getLastRequestId(); const withdrawalTx = await withdrawalQueue.connect(stranger).requestWithdrawals([amountWithRewards], stranger); - const withdrawalTxReceipt = await trace("withdrawalQueue.requestWithdrawals", withdrawalTx); + const withdrawalTxReceipt = await trace( + "withdrawalQueue.requestWithdrawals", + withdrawalTx, + ); const withdrawalEvent = ctx.getEvents(withdrawalTxReceipt, "WithdrawalRequested")[0]; - expect(withdrawalEvent?.args.toObject()).to.deep.include({ - requestor: stranger.address, - owner: stranger.address, - amountOfStETH: amountWithRewards, - }, "WithdrawalRequested event"); + expect(withdrawalEvent?.args.toObject()).to.deep.include( + { + requestor: stranger.address, + owner: stranger.address, + amountOfStETH: amountWithRewards, + }, + "WithdrawalRequested event", + ); const requestId = withdrawalEvent.args.requestId; const withdrawalTransferEvents = ctx.getEvents(withdrawalTxReceipt, "Transfer"); @@ -447,17 +482,23 @@ describe("Happy Path", () => { const [stEthTransfer, unstEthTransfer] = withdrawalTransferEvents; - expect(stEthTransfer?.args.toObject()).to.deep.include({ - from: stranger.address, - to: withdrawalQueue.address, - value: amountWithRewards, - }, "Transfer stETH"); + expect(stEthTransfer?.args.toObject()).to.deep.include( + { + from: stranger.address, + to: withdrawalQueue.address, + value: amountWithRewards, + }, + "Transfer stETH", + ); - expect(unstEthTransfer?.args.toObject()).to.deep.include({ - from: ZeroAddress, - to: stranger.address, - tokenId: requestId, - }, "Transfer unstETH"); + expect(unstEthTransfer?.args.toObject()).to.deep.include( + { + from: ZeroAddress, + to: stranger.address, + tokenId: requestId, + }, + "Transfer unstETH", + ); const balanceAfterRequest = await getBalances(stranger); @@ -498,7 +539,11 @@ describe("Happy Path", () => { "Expected withdrawal amount": ethers.formatEther(expectedWithdrawalAmount), }); - expect(withdrawalQueueBalanceBeforeFinalization).to.be.approximately(expectedWithdrawalAmount, 10n, "Withdrawal queue balance before finalization"); + expect(withdrawalQueueBalanceBeforeFinalization).to.be.approximately( + expectedWithdrawalAmount, + 10n, + "Withdrawal queue balance before finalization", + ); const lockedEtherAmountBeforeFinalization = await withdrawalQueue.getLockedEtherAmount(); @@ -518,20 +563,29 @@ describe("Happy Path", () => { "Amount with rewards": ethers.formatEther(amountWithRewards), }); - expect(lockedEtherAmountBeforeFinalization).to.equal(expectedLockedEtherAmountAfterFinalization, "Locked ether amount after finalization"); + expect(lockedEtherAmountBeforeFinalization).to.equal( + expectedLockedEtherAmountAfterFinalization, + "Locked ether amount after finalization", + ); const withdrawalFinalizedEvent = ctx.getEvents(reportTxReceipt, "WithdrawalsFinalized")[0]; - expect(withdrawalFinalizedEvent?.args.toObject()).to.deep.include({ - amountOfETHLocked: amountWithRewards, - from: requestId, - to: requestId, - }, "WithdrawalFinalized event"); + expect(withdrawalFinalizedEvent?.args.toObject()).to.deep.include( + { + amountOfETHLocked: amountWithRewards, + from: requestId, + to: requestId, + }, + "WithdrawalFinalized event", + ); const withdrawalQueueBalanceAfterFinalization = await lido.balanceOf(withdrawalQueue.address); const uncountedStETHBalanceAfterFinalization = await lido.getPooledEthByShares(uncountedStETHShares); - expect(withdrawalQueueBalanceAfterFinalization).to.equal(uncountedStETHBalanceAfterFinalization, "Withdrawal queue balance after finalization"); + expect(withdrawalQueueBalanceAfterFinalization).to.equal( + uncountedStETHBalanceAfterFinalization, + "Withdrawal queue balance after finalization", + ); }); it("Should claim withdrawals", async () => { @@ -543,7 +597,7 @@ describe("Happy Path", () => { const requestId = await withdrawalQueue.getLastRequestId(); // in fact, it's a proxy and not a real array, so we need to convert it to array - const hintsProxy = await withdrawalQueue.findCheckpointHints([requestId], 1n, lastCheckpointIndex) as Result; + const hintsProxy = (await withdrawalQueue.findCheckpointHints([requestId], 1n, lastCheckpointIndex)) as Result; const hints = hintsProxy.toArray(); const [claimableEtherBeforeClaim] = await withdrawalQueue.getClaimableEther([requestId], hints); @@ -561,24 +615,33 @@ describe("Happy Path", () => { const claimEvent = ctx.getEvents(claimTxReceipt, "WithdrawalClaimed")[0]; - expect(claimEvent?.args.toObject()).to.deep.include({ - requestId, - owner: stranger.address, - receiver: stranger.address, - amountOfETH: amountWithRewards, - }, "WithdrawalClaimed event"); + expect(claimEvent?.args.toObject()).to.deep.include( + { + requestId, + owner: stranger.address, + receiver: stranger.address, + amountOfETH: amountWithRewards, + }, + "WithdrawalClaimed event", + ); const transferEvent = ctx.getEvents(claimTxReceipt, "Transfer")[0]; - expect(transferEvent?.args.toObject()).to.deep.include({ - from: stranger.address, - to: ZeroAddress, - tokenId: requestId, - }, "Transfer event"); + expect(transferEvent?.args.toObject()).to.deep.include( + { + from: stranger.address, + to: ZeroAddress, + tokenId: requestId, + }, + "Transfer event", + ); const balanceAfterClaim = await getBalances(stranger); - expect(balanceAfterClaim.ETH).to.equal(balanceBeforeClaim.ETH + amountWithRewards - spentGas, "ETH balance after claim"); + expect(balanceAfterClaim.ETH).to.equal( + balanceBeforeClaim.ETH + amountWithRewards - spentGas, + "ETH balance after claim", + ); const lockedEtherAmountAfterClaim = await withdrawalQueue.getLockedEtherAmount(); @@ -588,7 +651,10 @@ describe("Happy Path", () => { "Amount with rewards": ethers.formatEther(amountWithRewards), }); - expect(lockedEtherAmountAfterClaim).to.equal(lockedEtherAmountBeforeWithdrawal - amountWithRewards, "Locked ether amount after claim"); + expect(lockedEtherAmountAfterClaim).to.equal( + lockedEtherAmountBeforeWithdrawal - amountWithRewards, + "Locked ether amount after claim", + ); const [statusAfterClaim] = await withdrawalQueue.connect(stranger).getWithdrawalStatus([requestId]); diff --git a/yarn.lock b/yarn.lock index cd5452cd7..493e5e6a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -99,37 +99,49 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0": - version: 7.24.2 - resolution: "@babel/code-frame@npm:7.24.2" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/code-frame@npm:7.24.7" dependencies: - "@babel/highlight": "npm:^7.24.2" + "@babel/highlight": "npm:^7.24.7" picocolors: "npm:^1.0.0" - checksum: 10c0/d1d4cba89475ab6aab7a88242e1fd73b15ecb9f30c109b69752956434d10a26a52cbd37727c4eca104b6d45227bd1dfce39a6a6f4a14c9b2f07f871e968cf406 + checksum: 10c0/ab0af539473a9f5aeaac7047e377cb4f4edd255a81d84a76058595f8540784cc3fbe8acf73f1e073981104562490aabfb23008cd66dc677a456a4ed5390fdde6 languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.23.5": - version: 7.24.4 - resolution: "@babel/compat-data@npm:7.24.4" - checksum: 10c0/9cd8a9cd28a5ca6db5d0e27417d609f95a8762b655e8c9c97fd2de08997043ae99f0139007083c5e607601c6122e8432c85fe391731b19bf26ad458fa0c60dd3 +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.2": + version: 7.25.4 + resolution: "@babel/compat-data@npm:7.25.4" + checksum: 10c0/50d79734d584a28c69d6f5b99adfaa064d0f41609a378aef04eb06accc5b44f8520e68549eba3a082478180957b7d5783f1bfb1672e4ae8574e797ce8bae79fa + languageName: node + linkType: hard + +"@babel/generator@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/generator@npm:7.25.4" + dependencies: + "@babel/types": "npm:^7.25.4" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + jsesc: "npm:^2.5.1" + checksum: 10c0/a2d8cc39e759214740f836360c8d9c17aa93e16e41afe73368a9e7ccd1d5c3303a420ce3aca1c9a31fdb93d1899de471d5aac97d1c64f741f8750a25a6e91fbc languageName: node linkType: hard "@babel/helper-compilation-targets@npm:^7.22.6": - version: 7.23.6 - resolution: "@babel/helper-compilation-targets@npm:7.23.6" + version: 7.25.2 + resolution: "@babel/helper-compilation-targets@npm:7.25.2" dependencies: - "@babel/compat-data": "npm:^7.23.5" - "@babel/helper-validator-option": "npm:^7.23.5" - browserslist: "npm:^4.22.2" + "@babel/compat-data": "npm:^7.25.2" + "@babel/helper-validator-option": "npm:^7.24.8" + browserslist: "npm:^4.23.1" lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - checksum: 10c0/ba38506d11185f48b79abf439462ece271d3eead1673dd8814519c8c903c708523428806f05f2ec5efd0c56e4e278698fac967e5a4b5ee842c32415da54bc6fa + checksum: 10c0/de10e986b5322c9f807350467dc845ec59df9e596a5926a3b5edbb4710d8e3b8009d4396690e70b88c3844fe8ec4042d61436dd4b92d1f5f75655cf43ab07e99 languageName: node linkType: hard -"@babel/helper-define-polyfill-provider@npm:^0.6.1, @babel/helper-define-polyfill-provider@npm:^0.6.2": +"@babel/helper-define-polyfill-provider@npm:^0.6.2": version: 0.6.2 resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2" dependencies: @@ -144,88 +156,126 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.24.3": - version: 7.24.3 - resolution: "@babel/helper-module-imports@npm:7.24.3" +"@babel/helper-module-imports@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-module-imports@npm:7.24.7" dependencies: - "@babel/types": "npm:^7.24.0" - checksum: 10c0/052c188adcd100f5e8b6ff0c9643ddaabc58b6700d3bbbc26804141ad68375a9f97d9d173658d373d31853019e65f62610239e3295cdd58e573bdcb2fded188d + "@babel/traverse": "npm:^7.24.7" + "@babel/types": "npm:^7.24.7" + checksum: 10c0/97c57db6c3eeaea31564286e328a9fb52b0313c5cfcc7eee4bc226aebcf0418ea5b6fe78673c0e4a774512ec6c86e309d0f326e99d2b37bfc16a25a032498af0 languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0": - version: 7.24.5 - resolution: "@babel/helper-plugin-utils@npm:7.24.5" - checksum: 10c0/4ae40094e6a2f183281213344f4df60c66b16b19a2bc38d2bb11810a6dc0a0e7ec638957d0e433ff8b615775b8f3cd1b7edbf59440d1b50e73c389fc22913377 +"@babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-plugin-utils@npm:7.24.8" + checksum: 10c0/0376037f94a3bfe6b820a39f81220ac04f243eaee7193774b983e956c1750883ff236b30785795abbcda43fac3ece74750566830c2daa4d6e3870bb0dff34c2d languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/helper-string-parser@npm:7.24.1" - checksum: 10c0/2f9bfcf8d2f9f083785df0501dbab92770111ece2f90d120352fda6dd2a7d47db11b807d111e6f32aa1ba6d763fe2dc6603d153068d672a5d0ad33ca802632b2 +"@babel/helper-string-parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-string-parser@npm:7.24.8" + checksum: 10c0/6361f72076c17fabf305e252bf6d580106429014b3ab3c1f5c4eb3e6d465536ea6b670cc0e9a637a77a9ad40454d3e41361a2909e70e305116a23d68ce094c08 languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.24.5": - version: 7.24.5 - resolution: "@babel/helper-validator-identifier@npm:7.24.5" - checksum: 10c0/05f957229d89ce95a137d04e27f7d0680d84ae48b6ad830e399db0779341f7d30290f863a93351b4b3bde2166737f73a286ea42856bb07c8ddaa95600d38645c +"@babel/helper-validator-identifier@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-validator-identifier@npm:7.24.7" + checksum: 10c0/87ad608694c9477814093ed5b5c080c2e06d44cb1924ae8320474a74415241223cc2a725eea2640dd783ff1e3390e5f95eede978bc540e870053152e58f1d651 languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/helper-validator-option@npm:7.23.5" - checksum: 10c0/af45d5c0defb292ba6fd38979e8f13d7da63f9623d8ab9ededc394f67eb45857d2601278d151ae9affb6e03d5d608485806cd45af08b4468a0515cf506510e94 +"@babel/helper-validator-option@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-validator-option@npm:7.24.8" + checksum: 10c0/73db93a34ae89201351288bee7623eed81a54000779462a986105b54ffe82069e764afd15171a428b82e7c7a9b5fec10b5d5603b216317a414062edf5c67a21f languageName: node linkType: hard -"@babel/highlight@npm:^7.24.2": - version: 7.24.5 - resolution: "@babel/highlight@npm:7.24.5" +"@babel/highlight@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/highlight@npm:7.24.7" dependencies: - "@babel/helper-validator-identifier": "npm:^7.24.5" + "@babel/helper-validator-identifier": "npm:^7.24.7" chalk: "npm:^2.4.2" js-tokens: "npm:^4.0.0" picocolors: "npm:^1.0.0" - checksum: 10c0/e98047d3ad24608bfa596d000c861a2cc875af897427f2833b91a4e0d4cead07301a7ec15fa26093dcd61e036e2eed2db338ae54f93016fe0dc785fadc4159db + checksum: 10c0/674334c571d2bb9d1c89bdd87566383f59231e16bcdcf5bb7835babdf03c9ae585ca0887a7b25bdf78f303984af028df52831c7989fecebb5101cc132da9393a + languageName: node + linkType: hard + +"@babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/parser@npm:7.25.4" + dependencies: + "@babel/types": "npm:^7.25.4" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/bdada5662f15d1df11a7266ec3bc9bb769bf3637ecf3d051eafcfc8f576dcf5a3ac1007c5e059db4a1e1387db9ae9caad239fc4f79e4c2200930ed610e779993 languageName: node linkType: hard "@babel/plugin-transform-runtime@npm:^7.5.5": - version: 7.24.3 - resolution: "@babel/plugin-transform-runtime@npm:7.24.3" + version: 7.25.4 + resolution: "@babel/plugin-transform-runtime@npm:7.25.4" dependencies: - "@babel/helper-module-imports": "npm:^7.24.3" - "@babel/helper-plugin-utils": "npm:^7.24.0" + "@babel/helper-module-imports": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.24.8" babel-plugin-polyfill-corejs2: "npm:^0.4.10" - babel-plugin-polyfill-corejs3: "npm:^0.10.1" + babel-plugin-polyfill-corejs3: "npm:^0.10.6" babel-plugin-polyfill-regenerator: "npm:^0.6.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/ee01967bf405d84bd95ca4089166a18fb23fe9851a6da53dcf712a7f8ba003319996f21f320d568ec76126e18adfaee978206ccda86eef7652d47cc9a052e75e + checksum: 10c0/c08698276596d58bf49e222ead3c414c35d099a7e5a6174b11e2db9b74420e94783ada596820437622c3eccc8852c0e750ad053bd8e775f0050839479ba76e6a languageName: node linkType: hard "@babel/runtime@npm:^7.5.5": - version: 7.24.5 - resolution: "@babel/runtime@npm:7.24.5" + version: 7.25.4 + resolution: "@babel/runtime@npm:7.25.4" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/05730e43e8ba6550eae9fd4fb5e7d9d3cb91140379425abcb2a1ff9cebad518a280d82c4c4b0f57ada26a863106ac54a748d90c775790c0e2cd0ddd85ccdf346 + checksum: 10c0/33e937e685f0bfc2d40c219261e2e50d0df7381a6e7cbf56b770e0c5d77cb0c21bf4d97da566cf0164317ed7508e992082c7b6cce7aaa3b17da5794f93fbfb46 + languageName: node + linkType: hard + +"@babel/template@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/template@npm:7.25.0" + dependencies: + "@babel/code-frame": "npm:^7.24.7" + "@babel/parser": "npm:^7.25.0" + "@babel/types": "npm:^7.25.0" + checksum: 10c0/4e31afd873215744c016e02b04f43b9fa23205d6d0766fb2e93eb4091c60c1b88897936adb895fb04e3c23de98dfdcbe31bc98daaa1a4e0133f78bb948e1209b languageName: node linkType: hard -"@babel/types@npm:^7.24.0": - version: 7.24.5 - resolution: "@babel/types@npm:7.24.5" +"@babel/traverse@npm:^7.24.7": + version: 7.25.4 + resolution: "@babel/traverse@npm:7.25.4" dependencies: - "@babel/helper-string-parser": "npm:^7.24.1" - "@babel/helper-validator-identifier": "npm:^7.24.5" + "@babel/code-frame": "npm:^7.24.7" + "@babel/generator": "npm:^7.25.4" + "@babel/parser": "npm:^7.25.4" + "@babel/template": "npm:^7.25.0" + "@babel/types": "npm:^7.25.4" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: 10c0/37c9b49b277e051fe499ef5f6f217370c4f648d6370564d70b5e6beb2da75bfda6d7dab1d39504d89e9245448f8959bc1a5880d2238840cdc3979b35338ed0f5 + languageName: node + linkType: hard + +"@babel/types@npm:^7.24.7, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/types@npm:7.25.4" + dependencies: + "@babel/helper-string-parser": "npm:^7.24.8" + "@babel/helper-validator-identifier": "npm:^7.24.7" to-fast-properties: "npm:^2.0.0" - checksum: 10c0/e1284eb046c5e0451b80220d1200e2327e0a8544a2fe45bb62c952e5fdef7099c603d2336b17b6eac3cc046b7a69bfbce67fe56e1c0ea48cd37c65cb88638f2a + checksum: 10c0/9aa25dfcd89cc4e4dde3188091c34398a005a49e2c2b069d0367b41e1122c91e80fd92998c52a90f2fb500f7e897b6090ec8be263d9cb53d0d75c756f44419f2 languageName: node linkType: hard @@ -448,14 +498,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0": - version: 4.10.0 - resolution: "@eslint-community/regexpp@npm:4.10.0" - checksum: 10c0/c5f60ef1f1ea7649fa7af0e80a5a79f64b55a8a8fa5086de4727eb4c86c652aedee407a9c143b8995d2c0b2d75c1222bec9ba5d73dbfc1f314550554f0979ef4 - languageName: node - linkType: hard - -"@eslint-community/regexpp@npm:^4.11.0": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0": version: 4.11.0 resolution: "@eslint-community/regexpp@npm:4.11.0" checksum: 10c0/0f6328869b2741e2794da4ad80beac55cba7de2d3b44f796a60955b0586212ec75e6b0253291fd4aad2100ad471d1480d8895f2b54f1605439ba4c875e05e523 @@ -1001,17 +1044,35 @@ __metadata: languageName: node linkType: hard -"@jridgewell/resolve-uri@npm:^3.0.3": +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": "npm:^1.2.1" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": version: 3.1.2 resolution: "@jridgewell/resolve-uri@npm:3.1.2" checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10": - version: 1.4.15 - resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" - checksum: 10c0/0c6b5ae663087558039052a626d2d7ed5208da36cfd707dcc5cea4a07cfc918248403dcb5989a8f7afaf245ce0573b7cc6fd94c4a30453bd10e44d9363940ba5 +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 10c0/2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 10c0/2eb864f276eb1096c3c11da3e9bb518f6d9fc0023c78344cdc037abadc725172c70314bdb360f2d4b7bffec7f5d657ce006816bc5d4ecb35e61b66132db00c18 languageName: node linkType: hard @@ -1025,6 +1086,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10c0/3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4 + languageName: node + linkType: hard + "@juanelas/base64@npm:^1.1.2": version: 1.1.5 resolution: "@juanelas/base64@npm:1.1.5" @@ -1072,12 +1143,12 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:1.3.0, @noble/curves@npm:~1.3.0": - version: 1.3.0 - resolution: "@noble/curves@npm:1.3.0" +"@noble/curves@npm:1.4.2, @noble/curves@npm:~1.4.0": + version: 1.4.2 + resolution: "@noble/curves@npm:1.4.2" dependencies: - "@noble/hashes": "npm:1.3.3" - checksum: 10c0/704bf8fda8e1365a9bb9e9945bd06645ef4ce85aa2fac5594abe09f19889197518152319481b89a271e0ee011787bd2ee87202441500bca7ca587a2c3ac10b01 + "@noble/hashes": "npm:1.4.0" + checksum: 10c0/65620c895b15d46e8087939db6657b46a1a15cd4e0e4de5cd84b97a0dfe0af85f33a431bb21ac88267e3dc508618245d4cb564213959d66a84d690fe18a63419 languageName: node linkType: hard @@ -1095,14 +1166,7 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:1.3.3, @noble/hashes@npm:~1.3.2": - version: 1.3.3 - resolution: "@noble/hashes@npm:1.3.3" - checksum: 10c0/23c020b33da4172c988e44100e33cd9f8f6250b68b43c467d3551f82070ebd9716e0d9d2347427aa3774c85934a35fa9ee6f026fca2117e3fa12db7bedae7668 - languageName: node - linkType: hard - -"@noble/hashes@npm:^1.4.0": +"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.4.0, @noble/hashes@npm:~1.4.0": version: 1.4.0 resolution: "@noble/hashes@npm:1.4.0" checksum: 10c0/8c3f005ee72e7b8f9cff756dfae1241485187254e3f743873e22073d63906863df5d4f13d441b7530ea614b7a093f0d889309f28b59850f33b66cb26a779a4a5 @@ -1274,16 +1338,16 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/hardhat-ethers@npm:^3.0.6": - version: 3.0.6 - resolution: "@nomicfoundation/hardhat-ethers@npm:3.0.6" +"@nomicfoundation/hardhat-ethers@npm:^3.0.7": + version: 3.0.7 + resolution: "@nomicfoundation/hardhat-ethers@npm:3.0.7" dependencies: debug: "npm:^4.1.1" lodash.isequal: "npm:^4.5.0" peerDependencies: ethers: ^6.1.0 - hardhat: ^2.0.0 - checksum: 10c0/c7abe4234fae6422a357ef9e959cfe4183d5d7121d18e9f71b1659944419fde7d2a0290cd42fd5e85d855d8c83b86bbaed316f4950f0976015f941d958679a99 + hardhat: "*" + checksum: 10c0/623efffe17fd770bf71ebf8692141d534b88a71e7a2dbaae020e3a3f4528cebb65acf485ab456da6ec80f5d61a4e973fef2803f988e01e9385fe050e7111dab9 languageName: node linkType: hard @@ -1397,97 +1461,71 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/solidity-analyzer-darwin-arm64@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-darwin-arm64@npm:0.1.1" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@nomicfoundation/solidity-analyzer-darwin-x64@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-darwin-x64@npm:0.1.1" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@nomicfoundation/solidity-analyzer-freebsd-x64@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-freebsd-x64@npm:0.1.1" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-linux-arm64-gnu@npm:0.1.1" - conditions: os=linux & cpu=arm64 & libc=glibc +"@nomicfoundation/solidity-analyzer-darwin-arm64@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-darwin-arm64@npm:0.1.2" + checksum: 10c0/ef3b13bb2133fea6621db98f991036a3a84d2b240160edec50beafa6ce821fe2f0f5cd4aa61adb9685aff60cd0425982ffd15e0b868b7c768e90e26b8135b825 languageName: node linkType: hard -"@nomicfoundation/solidity-analyzer-linux-arm64-musl@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-linux-arm64-musl@npm:0.1.1" - conditions: os=linux & cpu=arm64 & libc=musl +"@nomicfoundation/solidity-analyzer-darwin-x64@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-darwin-x64@npm:0.1.2" + checksum: 10c0/3cb6a00cd200b94efd6f59ed626c705c6f773b92ccf8b90471285cd0e81b35f01edb30c1aa5a4633393c2adb8f20fd34e90c51990dc4e30658e8a67c026d16c9 languageName: node linkType: hard -"@nomicfoundation/solidity-analyzer-linux-x64-gnu@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-linux-x64-gnu@npm:0.1.1" - conditions: os=linux & cpu=x64 & libc=glibc +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-linux-arm64-gnu@npm:0.1.2" + checksum: 10c0/cb9725e7bdc3ba9c1feaef96dbf831c1a59c700ca633a9929fd97debdcb5ce06b5d7b4e6dbc076279978707214d01e2cd126d8e3f4cabc5c16525c031a47b95c languageName: node linkType: hard -"@nomicfoundation/solidity-analyzer-linux-x64-musl@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-linux-x64-musl@npm:0.1.1" - conditions: os=linux & cpu=x64 & libc=musl +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-linux-arm64-musl@npm:0.1.2" + checksum: 10c0/82a90b1d09ad266ddc510ece2e397f51fdaf29abf7263d2a3a85accddcba2ac24cceb670a3120800611cdcc552eed04919d071e259fdda7564818359ed541f5d languageName: node linkType: hard -"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-win32-arm64-msvc@npm:0.1.1" - conditions: os=win32 & cpu=arm64 +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-linux-x64-gnu@npm:0.1.2" + checksum: 10c0/d1f20d4d55683bd041ead957e5461b2e43a39e959f905e8866de1d65f8d96118e9b861e994604d9002cb7f056be0844e36c241a6bb531c336b399609977c0998 languageName: node linkType: hard -"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-win32-ia32-msvc@npm:0.1.1" - conditions: os=win32 & cpu=ia32 +"@nomicfoundation/solidity-analyzer-linux-x64-musl@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-linux-x64-musl@npm:0.1.2" + checksum: 10c0/6c17f9af3aaf184c0a217cf723076051c502d85e731dbc97f34b838f9ae1b597577abac54a2af49b3fd986b09131c52fa21fd5393b22d05e1ec7fee96a8249c2 languageName: node linkType: hard -"@nomicfoundation/solidity-analyzer-win32-x64-msvc@npm:0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer-win32-x64-msvc@npm:0.1.1" - conditions: os=win32 & cpu=x64 +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-win32-x64-msvc@npm:0.1.2" + checksum: 10c0/da198464f5ee0d19b6decdfaa65ee0df3097b8960b8483bb7080931968815a5d60f27191229d47a198955784d763d5996f0b92bfde3551612ad972c160b0b000 languageName: node linkType: hard "@nomicfoundation/solidity-analyzer@npm:^0.1.0, @nomicfoundation/solidity-analyzer@npm:^0.1.1": - version: 0.1.1 - resolution: "@nomicfoundation/solidity-analyzer@npm:0.1.1" - dependencies: - "@nomicfoundation/solidity-analyzer-darwin-arm64": "npm:0.1.1" - "@nomicfoundation/solidity-analyzer-darwin-x64": "npm:0.1.1" - "@nomicfoundation/solidity-analyzer-freebsd-x64": "npm:0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "npm:0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "npm:0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "npm:0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "npm:0.1.1" - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "npm:0.1.1" - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "npm:0.1.1" - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "npm:0.1.1" + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer@npm:0.1.2" + dependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-darwin-x64": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "npm:0.1.2" dependenciesMeta: "@nomicfoundation/solidity-analyzer-darwin-arm64": optional: true "@nomicfoundation/solidity-analyzer-darwin-x64": optional: true - "@nomicfoundation/solidity-analyzer-freebsd-x64": - optional: true "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": optional: true "@nomicfoundation/solidity-analyzer-linux-arm64-musl": @@ -1496,13 +1534,9 @@ __metadata: optional: true "@nomicfoundation/solidity-analyzer-linux-x64-musl": optional: true - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": - optional: true - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": - optional: true "@nomicfoundation/solidity-analyzer-win32-x64-msvc": optional: true - checksum: 10c0/1feee48a9506125d7736e3d1200d997cd07777f52ee6c71f7fad7d50b6705f7d3e028894968b449ca6e950991e726e9464ee5dc0c52d1066d127632be29667b4 + checksum: 10c0/e4f503e9287e18967535af669ca7e26e2682203c45a34ea85da53122da1dee1278f2b8c76c20c67fadd7c1b1a98eeecffd2cbc136860665e3afa133817c0de54 languageName: node linkType: hard @@ -1520,11 +1554,11 @@ __metadata: linkType: hard "@npmcli/fs@npm:^3.1.0": - version: 3.1.0 - resolution: "@npmcli/fs@npm:3.1.0" + version: 3.1.1 + resolution: "@npmcli/fs@npm:3.1.1" dependencies: semver: "npm:^7.3.5" - checksum: 10c0/162b4a0b8705cd6f5c2470b851d1dc6cd228c86d2170e1769d738c1fbb69a87160901411c3c035331e9e99db72f1f1099a8b734bf1637cc32b9a5be1660e4e1e + checksum: 10c0/c37a5b4842bfdece3d14dfdb054f73fe15ed2d3da61b34ff76629fb5b1731647c49166fd2a8bf8b56fcfa51200382385ea8909a3cbecdad612310c114d3f6c99 languageName: node linkType: hard @@ -1573,13 +1607,13 @@ __metadata: linkType: hard "@pnpm/npm-conf@npm:^2.1.0": - version: 2.2.2 - resolution: "@pnpm/npm-conf@npm:2.2.2" + version: 2.3.1 + resolution: "@pnpm/npm-conf@npm:2.3.1" dependencies: "@pnpm/config.env-replace": "npm:^1.1.0" "@pnpm/network.ca-file": "npm:^1.0.1" config-chain: "npm:^1.1.11" - checksum: 10c0/71393dcfce85603fddd8484b486767163000afab03918303253ae97992615b91d25942f83751366cb40ad2ee32b0ae0a033561de9d878199a024286ff98b0296 + checksum: 10c0/778a3a34ff7d6000a2594d2a9821f873f737bc56367865718b2cf0ba5d366e49689efe7975148316d7afd8e6f1dcef7d736fbb6ea7ef55caadd1dc93a36bb302 languageName: node linkType: hard @@ -1625,10 +1659,10 @@ __metadata: languageName: node linkType: hard -"@scure/base@npm:~1.1.0, @scure/base@npm:~1.1.4": - version: 1.1.6 - resolution: "@scure/base@npm:1.1.6" - checksum: 10c0/237a46a1f45391fc57719154f14295db936a0b1562ea3e182dd42d7aca082dbb7062a28d6c49af16a7e478b12dae8a0fe678d921ea5056bcc30238d29eb05c55 +"@scure/base@npm:~1.1.0, @scure/base@npm:~1.1.6": + version: 1.1.7 + resolution: "@scure/base@npm:1.1.7" + checksum: 10c0/2d06aaf39e6de4b9640eb40d2e5419176ebfe911597856dcbf3bc6209277ddb83f4b4b02cb1fd1208f819654268ec083da68111d3530bbde07bae913e2fc2e5d languageName: node linkType: hard @@ -1643,14 +1677,14 @@ __metadata: languageName: node linkType: hard -"@scure/bip32@npm:1.3.3": - version: 1.3.3 - resolution: "@scure/bip32@npm:1.3.3" +"@scure/bip32@npm:1.4.0": + version: 1.4.0 + resolution: "@scure/bip32@npm:1.4.0" dependencies: - "@noble/curves": "npm:~1.3.0" - "@noble/hashes": "npm:~1.3.2" - "@scure/base": "npm:~1.1.4" - checksum: 10c0/48fa04ebf0e3b56e3d086f029ae207ea753d8d8a1b3564f3c80fafea63dc3ee4edbd21e44eadb79bd4de4afffb075cbbbcb258fd5030a9680065cb524424eb83 + "@noble/curves": "npm:~1.4.0" + "@noble/hashes": "npm:~1.4.0" + "@scure/base": "npm:~1.1.6" + checksum: 10c0/6849690d49a3bf1d0ffde9452eb16ab83478c1bc0da7b914f873e2930cd5acf972ee81320e3df1963eb247cf57e76d2d975b5f97093d37c0e3f7326581bf41bd languageName: node linkType: hard @@ -1664,13 +1698,13 @@ __metadata: languageName: node linkType: hard -"@scure/bip39@npm:1.2.2": - version: 1.2.2 - resolution: "@scure/bip39@npm:1.2.2" +"@scure/bip39@npm:1.3.0": + version: 1.3.0 + resolution: "@scure/bip39@npm:1.3.0" dependencies: - "@noble/hashes": "npm:~1.3.2" - "@scure/base": "npm:~1.1.4" - checksum: 10c0/be38bc1dc10b9a763d8b02d91dc651a4f565c822486df6cb1d3cc84896c1aab3ef6acbf7b3dc7e4a981bc9366086a4d72020aa21e11a692734a750de049c887c + "@noble/hashes": "npm:~1.4.0" + "@scure/base": "npm:~1.1.6" + checksum: 10c0/1ae1545a7384a4d9e33e12d9e9f8824f29b0279eb175b0f0657c0a782c217920054f9a1d28eb316a417dfc6c4e0b700d6fbdc6da160670107426d52fcbe017a8 languageName: node linkType: hard @@ -1975,14 +2009,7 @@ __metadata: languageName: node linkType: hard -"@types/chai@npm:*": - version: 4.3.16 - resolution: "@types/chai@npm:4.3.16" - checksum: 10c0/745d4a9be429d5d86a7ab26064610b8957fe12dd80e94dc7d0707cf3db1c889e3ffe0d73d69bb15e6d376bf4462a7a75e9d8fc1051750b5d656d6cfe459829b7 - languageName: node - linkType: hard - -"@types/chai@npm:^4.3.17": +"@types/chai@npm:*, @types/chai@npm:^4.3.17": version: 4.3.17 resolution: "@types/chai@npm:4.3.17" checksum: 10c0/322a74489cdfde9c301b593d086c539584924c4c92689a858e0930708895a5ab229c31c64ac26b137615ef3ffbff1866851c280c093e07b3d3de05983d3793e0 @@ -2088,11 +2115,11 @@ __metadata: linkType: hard "@types/node@npm:*": - version: 20.12.8 - resolution: "@types/node@npm:20.12.8" + version: 22.5.0 + resolution: "@types/node@npm:22.5.0" dependencies: - undici-types: "npm:~5.26.4" - checksum: 10c0/840002d20654e38a9af8cdffa215598fdb28ac4f96c5701ed672ec365ed6ccc66da299edddaa409baf13cd71bbf1128901f633b5e44e070fc236e26415805b78 + undici-types: "npm:~6.19.2" + checksum: 10c0/45aa75c5e71645fac42dced4eff7f197c3fdfff6e8a9fdacd0eb2e748ff21ee70ffb73982f068a58e8d73b2c088a63613142c125236cdcf3c072ea97eada1559 languageName: node linkType: hard @@ -2103,12 +2130,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:20.14.15": - version: 20.14.15 - resolution: "@types/node@npm:20.14.15" +"@types/node@npm:20.16.1": + version: 20.16.1 + resolution: "@types/node@npm:20.16.1" dependencies: - undici-types: "npm:~5.26.4" - checksum: 10c0/093713db52dc544f3931a3dec9d7d8ef661f323e57becd083a7918c778cef1eb6ec32d1017bf5ade06bb06dc5c7551f4f4d749a14e40868cce44d51e54acd8ed + undici-types: "npm:~6.19.2" + checksum: 10c0/cac13c0f42467df3254805a671ca9e74a6eb7c41568de972e26b10dcc448a45743aaf00e9e5fce4a9214da5bc8444fe902918e105dac5a224e24e83fd9989a97 languageName: node linkType: hard @@ -2158,15 +2185,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.0.1": - version: 8.0.1 - resolution: "@typescript-eslint/eslint-plugin@npm:8.0.1" +"@typescript-eslint/eslint-plugin@npm:8.2.0": + version: 8.2.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.2.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.0.1" - "@typescript-eslint/type-utils": "npm:8.0.1" - "@typescript-eslint/utils": "npm:8.0.1" - "@typescript-eslint/visitor-keys": "npm:8.0.1" + "@typescript-eslint/scope-manager": "npm:8.2.0" + "@typescript-eslint/type-utils": "npm:8.2.0" + "@typescript-eslint/utils": "npm:8.2.0" + "@typescript-eslint/visitor-keys": "npm:8.2.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" @@ -2177,66 +2204,66 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10c0/fd4e11599c4a85d0fbbd0be350f11acaa32d424bc5c2c0b672133266b4b56fc20a78edd0c7b803b4223a1a66736624561a60fee827738118550733d14afb775a + checksum: 10c0/17243ee1b34d78723fe3e1a308c64490eee49bd83301e3abe8a6f05bce05434d70f56caf75756b8cffa051154dc89cdf485114ede6781fc087f0aaca37a026ec languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.0.1": - version: 8.0.1 - resolution: "@typescript-eslint/parser@npm:8.0.1" +"@typescript-eslint/parser@npm:8.2.0": + version: 8.2.0 + resolution: "@typescript-eslint/parser@npm:8.2.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.0.1" - "@typescript-eslint/types": "npm:8.0.1" - "@typescript-eslint/typescript-estree": "npm:8.0.1" - "@typescript-eslint/visitor-keys": "npm:8.0.1" + "@typescript-eslint/scope-manager": "npm:8.2.0" + "@typescript-eslint/types": "npm:8.2.0" + "@typescript-eslint/typescript-estree": "npm:8.2.0" + "@typescript-eslint/visitor-keys": "npm:8.2.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/bf93640f06c9d2e09a79d015d2c3303f58a8569a3f6928544feeeaad8825388133b5e44ca017b4480d38c037644cf6390c785129539fe256f55422ae608943b5 + checksum: 10c0/bb4ebc0a40b5e68c5287de17af3acf3045e2ef7886ebee8d1c4a6fd07bd6d55e9fc12bc7b89d07d15a2a4182cbf6380b50ad148d4a37e93d2e54930aa386a3bf languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.0.1": - version: 8.0.1 - resolution: "@typescript-eslint/scope-manager@npm:8.0.1" +"@typescript-eslint/scope-manager@npm:8.2.0": + version: 8.2.0 + resolution: "@typescript-eslint/scope-manager@npm:8.2.0" dependencies: - "@typescript-eslint/types": "npm:8.0.1" - "@typescript-eslint/visitor-keys": "npm:8.0.1" - checksum: 10c0/79c00bc726c0c14b800bbbc1c1b88978c2cbeb29d2b06b94a5773f959aafac5cfb37bdb8c3bb80b9fb07fd10440413fce9098f338dce100696a4d3dc1ea6b187 + "@typescript-eslint/types": "npm:8.2.0" + "@typescript-eslint/visitor-keys": "npm:8.2.0" + checksum: 10c0/8026e11d9cfbb674c62eb38929d08d42c4a373f3463c2591ed6603c496d3d00321f553edce47f1d7504b55fcbe9664ea2bdcaa3131c8c834bde1b1f07497af5d languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.0.1": - version: 8.0.1 - resolution: "@typescript-eslint/type-utils@npm:8.0.1" +"@typescript-eslint/type-utils@npm:8.2.0": + version: 8.2.0 + resolution: "@typescript-eslint/type-utils@npm:8.2.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:8.0.1" - "@typescript-eslint/utils": "npm:8.0.1" + "@typescript-eslint/typescript-estree": "npm:8.2.0" + "@typescript-eslint/utils": "npm:8.2.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependenciesMeta: typescript: optional: true - checksum: 10c0/5cbf604044d5cd9cc6e95a2eee5a62803a09f46ccf4aa7293e373a4be8b7b57b470cbc97c1121ef354f842e7fc1d17b30c81bf3540023382ad5e339c9ca3ce15 + checksum: 10c0/5ff387d39fec3ba47af167ca3e48a200f87e4b97b010170245f495cd3d2e30fd0a5b2a9b27aae2ae929c99f92acabcd07315944dc6f9de963bad1c61ba9ea53c languageName: node linkType: hard -"@typescript-eslint/types@npm:8.0.1": - version: 8.0.1 - resolution: "@typescript-eslint/types@npm:8.0.1" - checksum: 10c0/e7c02d4e153a935c04bfddc0c8fc1618b1c8e9767583cff05a0e063bbacb7f3c8fac2257879c41162fe19094a0de3a567b57969177b2a0c32f39accd4c5601d5 +"@typescript-eslint/types@npm:8.2.0": + version: 8.2.0 + resolution: "@typescript-eslint/types@npm:8.2.0" + checksum: 10c0/2ffba0d0183dfdd2f859fb414013d17d009f5e886664823f973aaa1145243fceb52cfe26aa7c50208af7833b3703b7788337f1aab136c9a4eb36d905493847d1 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.0.1": - version: 8.0.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.0.1" +"@typescript-eslint/typescript-estree@npm:8.2.0": + version: 8.2.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.2.0" dependencies: - "@typescript-eslint/types": "npm:8.0.1" - "@typescript-eslint/visitor-keys": "npm:8.0.1" + "@typescript-eslint/types": "npm:8.2.0" + "@typescript-eslint/visitor-keys": "npm:8.2.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -2246,31 +2273,31 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10c0/12507995dc634a1746b581635e0df9f986ad01e7f0b4482f1f240986e7277ebd301dfe3b59c07da6d1f3d465f9110dc2a61ce50b67a8f31188cad13f7cc3632e + checksum: 10c0/f49aabc78e396908307394812fdebc4015ca407983efc361be106d3e2d58971dec4a1a725362fcfbd637f3d8150baa0735eb5929fd170172b7f2a65e06eeb3d2 languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.0.1": - version: 8.0.1 - resolution: "@typescript-eslint/utils@npm:8.0.1" +"@typescript-eslint/utils@npm:8.2.0": + version: 8.2.0 + resolution: "@typescript-eslint/utils@npm:8.2.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.0.1" - "@typescript-eslint/types": "npm:8.0.1" - "@typescript-eslint/typescript-estree": "npm:8.0.1" + "@typescript-eslint/scope-manager": "npm:8.2.0" + "@typescript-eslint/types": "npm:8.2.0" + "@typescript-eslint/typescript-estree": "npm:8.2.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - checksum: 10c0/9ab4baee82ac74caee18fb687697698043385aea5d0ec4bb34d874a6969eaa3e48f9319ab023cbcb6114f86de17f7360a43460fb4159c61760a2d2984004dd21 + checksum: 10c0/0f3d5cf804c2863ea9432ef76bfdb1cadbb244cbf8a64ac77c0e559c012a1e98382c4535354e54696c564c0abd9c10dffc78d38972c97035e963798d360d1830 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.0.1": - version: 8.0.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.0.1" +"@typescript-eslint/visitor-keys@npm:8.2.0": + version: 8.2.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.2.0" dependencies: - "@typescript-eslint/types": "npm:8.0.1" + "@typescript-eslint/types": "npm:8.2.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10c0/64c12095a97808bb1e1f5709192b274cac58d6b8fbbf9ec8fafead30f7effef7f0232244ec759298d046e1cd43521b9f3ba37b80618d5184c8b22fae665a7068 + checksum: 10c0/788633bd2905c88ea2cf20d9e317a2bc992a70fcf725cb54bbe55a17c42138a6fe877c89fbda41a733e0e8ad6dce893163bada60509a1b856321f4329a316973 languageName: node linkType: hard @@ -2335,13 +2362,15 @@ __metadata: linkType: hard "acorn-walk@npm:^8.1.1": - version: 8.3.2 - resolution: "acorn-walk@npm:8.3.2" - checksum: 10c0/7e2a8dad5480df7f872569b9dccff2f3da7e65f5353686b1d6032ab9f4ddf6e3a2cb83a9b52cf50b1497fd522154dda92f0abf7153290cc79cd14721ff121e52 + version: 8.3.3 + resolution: "acorn-walk@npm:8.3.3" + dependencies: + acorn: "npm:^8.11.0" + checksum: 10c0/4a9e24313e6a0a7b389e712ba69b66b455b4cb25988903506a8d247e7b126f02060b05a8a5b738a9284214e4ca95f383dd93443a4ba84f1af9b528305c7f243b languageName: node linkType: hard -"acorn@npm:^8.12.0": +"acorn@npm:^8.11.0, acorn@npm:^8.12.0, acorn@npm:^8.4.1": version: 8.12.1 resolution: "acorn@npm:8.12.1" bin: @@ -2350,15 +2379,6 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.4.1": - version: 8.11.3 - resolution: "acorn@npm:8.11.3" - bin: - acorn: bin/acorn - checksum: 10c0/3ff155f8812e4a746fee8ecff1f227d527c4c45655bb1fad6347c3cb58e46190598217551b1500f18542d2bbe5c87120cb6927f5a074a59166fbdd9468f0a299 - languageName: node - linkType: hard - "adm-zip@npm:^0.4.16": version: 0.4.16 resolution: "adm-zip@npm:0.4.16" @@ -2428,14 +2448,14 @@ __metadata: linkType: hard "ajv@npm:^8.0.1, ajv@npm:^8.11.0": - version: 8.13.0 - resolution: "ajv@npm:8.13.0" + version: 8.17.1 + resolution: "ajv@npm:8.17.1" dependencies: fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" json-schema-traverse: "npm:^1.0.0" require-from-string: "npm:^2.0.2" - uri-js: "npm:^4.4.1" - checksum: 10c0/14c6497b6f72843986d7344175a1aa0e2c35b1e7f7475e55bc582cddb765fca7e6bf950f465dc7846f817776d9541b706f4b5b3fbedd8dfdeb5fce6f22864264 + checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 languageName: node linkType: hard @@ -2455,14 +2475,7 @@ __metadata: languageName: node linkType: hard -"ansi-colors@npm:4.1.1": - version: 4.1.1 - resolution: "ansi-colors@npm:4.1.1" - checksum: 10c0/6086ade4336b4250b6b25e144b83e5623bcaf654d3df0c3546ce09c9c5ff999cb6a6f00c87e802d05cf98aef79d92dc76ade2670a2493b8dcb80220bec457838 - languageName: node - linkType: hard - -"ansi-colors@npm:^4.1.1": +"ansi-colors@npm:^4.1.1, ansi-colors@npm:^4.1.3": version: 4.1.3 resolution: "ansi-colors@npm:4.1.3" checksum: 10c0/ec87a2f59902f74e61eada7f6e6fe20094a628dab765cfdbd03c3477599368768cffccdb5d3bb19a1b6c99126783a143b1fee31aab729b31ffe5836c7e5e28b9 @@ -2548,9 +2561,9 @@ __metadata: linkType: hard "antlr4@npm:^4.13.1-patch-1": - version: 4.13.1 - resolution: "antlr4@npm:4.13.1" - checksum: 10c0/f92191677cf277e9c65806bcc40e0d844838203047e3d50cb2628cdda3052500dad0827f9308fc46283935786b0e6bc2986beb47cdd9b1ac88b5258d1b311294 + version: 4.13.2 + resolution: "antlr4@npm:4.13.2" + checksum: 10c0/dfe7dcb24fe99ce103e1eac3ce30558a3df713cf5deeacd7e30686f5cca8206864e49b254af3bd5eff5904d31e5cd7902a7468c13dcb619da10caf3f703d03b4 languageName: node linkType: hard @@ -2780,20 +2793,20 @@ __metadata: linkType: hard "aws4@npm:^1.8.0": - version: 1.12.0 - resolution: "aws4@npm:1.12.0" - checksum: 10c0/1e39c266f53b04daf88e112de93a6006375b386a1b7ab6197260886e39abd012aa90bdd87949c3bf9c30754846031f6d5d8ac4f8676628097c11065b5d39847a + version: 1.13.1 + resolution: "aws4@npm:1.13.1" + checksum: 10c0/c40a90b998853b92f9d0198e9992f4a94c81f29b02ca02b75952efaef07ff0660e756c7ebd04ff674edfa36c29406abaa8aad84f23dbc8b362d31979a631d3fe languageName: node linkType: hard "axios@npm:^1.5.1": - version: 1.6.8 - resolution: "axios@npm:1.6.8" + version: 1.7.4 + resolution: "axios@npm:1.7.4" dependencies: follow-redirects: "npm:^1.15.6" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: 10c0/0f22da6f490335479a89878bc7d5a1419484fbb437b564a80c34888fc36759ae4f56ea28d55a191695e5ed327f0bad56e7ff60fb6770c14d1be6501505d47ab9 + checksum: 10c0/5ea1a93140ca1d49db25ef8e1bd8cfc59da6f9220159a944168860ad15a2743ea21c5df2967795acb15cbe81362f5b157fdebbea39d53117ca27658bab9f7f17 languageName: node linkType: hard @@ -3019,15 +3032,15 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs3@npm:^0.10.1": - version: 0.10.4 - resolution: "babel-plugin-polyfill-corejs3@npm:0.10.4" +"babel-plugin-polyfill-corejs3@npm:^0.10.6": + version: 0.10.6 + resolution: "babel-plugin-polyfill-corejs3@npm:0.10.6" dependencies: - "@babel/helper-define-polyfill-provider": "npm:^0.6.1" - core-js-compat: "npm:^3.36.1" + "@babel/helper-define-polyfill-provider": "npm:^0.6.2" + core-js-compat: "npm:^3.38.0" peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 10c0/31b92cd3dfb5b417da8dfcf0deaa4b8b032b476d7bb31ca51c66127cf25d41e89260e89d17bc004b2520faa38aa9515fafabf81d89f9d4976e9dc1163e4a7c41 + checksum: 10c0/3a69220471b07722c2ae6537310bf26b772514e12b601398082965459c838be70a0ca70b0662f0737070654ff6207673391221d48599abb4a2b27765206d9f79 languageName: node linkType: hard @@ -3479,11 +3492,11 @@ __metadata: linkType: hard "base-x@npm:^3.0.2": - version: 3.0.9 - resolution: "base-x@npm:3.0.9" + version: 3.0.10 + resolution: "base-x@npm:3.0.10" dependencies: safe-buffer: "npm:^5.0.1" - checksum: 10c0/e6bbeae30b24f748b546005affb710c5fbc8b11a83f6cd0ca999bd1ab7ad3a22e42888addc40cd145adc4edfe62fcfab4ebc91da22e4259aae441f95a77aee1a + checksum: 10c0/a13a34b71439ee5381667efa630b3bf640cf17f632c5ba01990483367592e72f247d7fb4f8c6d0e3ff8c0fb7224b3ac682ff5be09b87063a45b3968f0457e563 languageName: node linkType: hard @@ -3616,7 +3629,7 @@ __metadata: languageName: node linkType: hard -"braces@npm:^3.0.2, braces@npm:^3.0.3, braces@npm:~3.0.2": +"braces@npm:^3.0.3, braces@npm:~3.0.2": version: 3.0.3 resolution: "braces@npm:3.0.3" dependencies: @@ -3632,7 +3645,7 @@ __metadata: languageName: node linkType: hard -"browser-stdout@npm:1.3.1": +"browser-stdout@npm:^1.3.1": version: 1.3.1 resolution: "browser-stdout@npm:1.3.1" checksum: 10c0/c40e482fd82be872b6ea7b9f7591beafbf6f5ba522fe3dade98ba1573a1c29a11101564993e4eb44e5488be8f44510af072df9a9637c739217eb155ceb639205 @@ -3665,17 +3678,17 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.22.2, browserslist@npm:^4.23.0": - version: 4.23.0 - resolution: "browserslist@npm:4.23.0" +"browserslist@npm:^4.23.1, browserslist@npm:^4.23.3": + version: 4.23.3 + resolution: "browserslist@npm:4.23.3" dependencies: - caniuse-lite: "npm:^1.0.30001587" - electron-to-chromium: "npm:^1.4.668" - node-releases: "npm:^2.0.14" - update-browserslist-db: "npm:^1.0.13" + caniuse-lite: "npm:^1.0.30001646" + electron-to-chromium: "npm:^1.5.4" + node-releases: "npm:^2.0.18" + update-browserslist-db: "npm:^1.1.0" bin: browserslist: cli.js - checksum: 10c0/8e9cc154529062128d02a7af4d8adeead83ca1df8cd9ee65a88e2161039f3d68a4d40fea7353cab6bae4c16182dec2fdd9a1cf7dc2a2935498cee1af0e998943 + checksum: 10c0/3063bfdf812815346447f4796c8f04601bf5d62003374305fd323c2a463e42776475bcc5309264e39bcf9a8605851e53560695991a623be988138b3ff8c66642 languageName: node linkType: hard @@ -3730,8 +3743,8 @@ __metadata: linkType: hard "cacache@npm:^18.0.0": - version: 18.0.3 - resolution: "cacache@npm:18.0.3" + version: 18.0.4 + resolution: "cacache@npm:18.0.4" dependencies: "@npmcli/fs": "npm:^3.1.0" fs-minipass: "npm:^3.0.0" @@ -3745,7 +3758,7 @@ __metadata: ssri: "npm:^10.0.0" tar: "npm:^6.1.11" unique-filename: "npm:^3.0.0" - checksum: 10c0/dfda92840bb371fb66b88c087c61a74544363b37a265023223a99965b16a16bbb87661fe4948718d79df6e0cc04e85e62784fbcf1832b2a5e54ff4c46fbb45b7 + checksum: 10c0/6c055bafed9de4f3dcc64ac3dc7dd24e863210902b7c470eb9ce55a806309b3efff78033e3d8b4f7dcc5d467f2db43c6a2857aaaf26f0094b8a351d44c42179f languageName: node linkType: hard @@ -3805,10 +3818,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30000844, caniuse-lite@npm:^1.0.30001587": - version: 1.0.30001616 - resolution: "caniuse-lite@npm:1.0.30001616" - checksum: 10c0/4c29f0a6c65ec888fadf5112cffc3b162872b74dce6ca4964d242c1c0fd05ab284f8e500f85739d5c96573589cf6e0e911424646b1009440a7c142ef6a5187ce +"caniuse-lite@npm:^1.0.30000844, caniuse-lite@npm:^1.0.30001646": + version: 1.0.30001651 + resolution: "caniuse-lite@npm:1.0.30001651" + checksum: 10c0/7821278952a6dbd17358e5d08083d258f092e2a530f5bc1840657cb140fbbc5ec44293bc888258c44a18a9570cde149ed05819ac8320b9710cf22f699891e6ad languageName: node linkType: hard @@ -3838,13 +3851,13 @@ __metadata: linkType: hard "chai-as-promised@npm:^7.1.1": - version: 7.1.1 - resolution: "chai-as-promised@npm:7.1.1" + version: 7.1.2 + resolution: "chai-as-promised@npm:7.1.2" dependencies: check-error: "npm:^1.0.2" peerDependencies: - chai: ">= 2.1.2 < 5" - checksum: 10c0/e25a602c3a8cd0b97ce6b0c7ddaaf4bd8517941da9f44dc65262c5268ea463f634dc495cdef6a21eaeffdb5022b6f4c3781027b8308273b7fff089c605abf6aa + chai: ">= 2.1.2 < 6" + checksum: 10c0/ee20ed75296d8cbf828b2f3c9ad64627cee67b1a38b8e906ca59fe788fb6965ddb10f702ae66645ed88f15a905ade4f2d9f8540029e92e2d59b229c9f912273f languageName: node linkType: hard @@ -3929,25 +3942,6 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:3.5.3": - version: 3.5.3 - resolution: "chokidar@npm:3.5.3" - dependencies: - anymatch: "npm:~3.1.2" - braces: "npm:~3.0.2" - fsevents: "npm:~2.3.2" - glob-parent: "npm:~5.1.2" - is-binary-path: "npm:~2.1.0" - is-glob: "npm:~4.0.1" - normalize-path: "npm:~3.0.0" - readdirp: "npm:~3.6.0" - dependenciesMeta: - fsevents: - optional: true - checksum: 10c0/1076953093e0707c882a92c66c0f56ba6187831aa51bb4de878c1fec59ae611a3bf02898f190efec8e77a086b8df61c2b2a3ea324642a0558bdf8ee6c5dc9ca1 - languageName: node - linkType: hard - "chokidar@npm:^3.4.0, chokidar@npm:^3.5.3": version: 3.6.0 resolution: "chokidar@npm:3.6.0" @@ -4029,15 +4023,15 @@ __metadata: linkType: hard "cli-table3@npm:^0.6.0": - version: 0.6.4 - resolution: "cli-table3@npm:0.6.4" + version: 0.6.5 + resolution: "cli-table3@npm:0.6.5" dependencies: "@colors/colors": "npm:1.5.0" string-width: "npm:^4.2.0" dependenciesMeta: "@colors/colors": optional: true - checksum: 10c0/8233c3d588db19122ed62a64256c7f0208232d2cece89a6cd7732481887fd9dcef69d976c4719149e77ccbf0a68f637bd5923536adccf6cdea051eeffa0ef1c2 + checksum: 10c0/d7cc9ed12212ae68241cc7a3133c52b844113b17856e11f4f81308acc3febcea7cc9fd298e70933e294dd642866b29fd5d113c2c098948701d0c35f09455de78 languageName: node linkType: hard @@ -4297,12 +4291,12 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.36.1": - version: 3.37.0 - resolution: "core-js-compat@npm:3.37.0" +"core-js-compat@npm:^3.38.0": + version: 3.38.1 + resolution: "core-js-compat@npm:3.38.1" dependencies: - browserslist: "npm:^4.23.0" - checksum: 10c0/ca6ba7d200f7a4a850fd5cba58b40ab78139d3f301bad7b53816eafe0cfb000523e72882069ddaba440794b950ed101225668bf7b97b73e54a5e3384a8215e03 + browserslist: "npm:^4.23.3" + checksum: 10c0/d8bc8a35591fc5fbf3e376d793f298ec41eb452619c7ef9de4ea59b74be06e9fda799e0dcbf9ba59880dae87e3b41fb191d744ffc988315642a1272bb9442b31 languageName: node linkType: hard @@ -4508,15 +4502,15 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4": - version: 4.3.4 - resolution: "debug@npm:4.3.4" +"debug@npm:4, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:~4.3.6": + version: 4.3.6 + resolution: "debug@npm:4.3.6" dependencies: ms: "npm:2.1.2" peerDependenciesMeta: supports-color: optional: true - checksum: 10c0/cedbec45298dd5c501d01b92b119cd3faebe5438c3917ff11ae1bff86a6c722930ac9c8659792824013168ba6db7c4668225d845c633fbdafbbf902a6389f736 + checksum: 10c0/3293416bff072389c101697d4611c402a6bacd1900ac20c0492f61a9cdd6b3b29750fc7f5e299f8058469ef60ff8fb79b86395a30374fbd2490113c1c7112285 languageName: node linkType: hard @@ -4538,18 +4532,6 @@ __metadata: languageName: node linkType: hard -"debug@npm:~4.3.6": - version: 4.3.6 - resolution: "debug@npm:4.3.6" - dependencies: - ms: "npm:2.1.2" - peerDependenciesMeta: - supports-color: - optional: true - checksum: 10c0/3293416bff072389c101697d4611c402a6bacd1900ac20c0492f61a9cdd6b3b29750fc7f5e299f8058469ef60ff8fb79b86395a30374fbd2490113c1c7112285 - languageName: node - linkType: hard - "decamelize@npm:^1.1.1": version: 1.2.0 resolution: "decamelize@npm:1.2.0" @@ -4574,11 +4556,11 @@ __metadata: linkType: hard "deep-eql@npm:^4.0.1, deep-eql@npm:^4.1.3": - version: 4.1.3 - resolution: "deep-eql@npm:4.1.3" + version: 4.1.4 + resolution: "deep-eql@npm:4.1.4" dependencies: type-detect: "npm:^4.0.0" - checksum: 10c0/ff34e8605d8253e1bf9fe48056e02c6f347b81d9b5df1c6650a1b0f6f847b4a86453b16dc226b34f853ef14b626e85d04e081b022e20b00cd7d54f079ce9bbdd + checksum: 10c0/264e0613493b43552fc908f4ff87b8b445c0e6e075656649600e1b8a17a57ee03e960156fce7177646e4d2ddaf8e5ee616d76bd79929ff593e5c79e4e5e6c517 languageName: node linkType: hard @@ -4678,13 +4660,6 @@ __metadata: languageName: node linkType: hard -"diff@npm:5.0.0": - version: 5.0.0 - resolution: "diff@npm:5.0.0" - checksum: 10c0/08c5904779bbababcd31f1707657b1ad57f8a9b65e6f88d3fb501d09a965d5f8d73066898a7d3f35981f9e4101892c61d99175d421f3b759533213c253d91134 - languageName: node - linkType: hard - "diff@npm:^4.0.1": version: 4.0.2 resolution: "diff@npm:4.0.2" @@ -4692,6 +4667,13 @@ __metadata: languageName: node linkType: hard +"diff@npm:^5.2.0": + version: 5.2.0 + resolution: "diff@npm:5.2.0" + checksum: 10c0/aed0941f206fe261ecb258dc8d0ceea8abbde3ace5827518ff8d302f0fc9cc81ce116c4d8f379151171336caf0516b79e01abdc1ed1201b6440d895a66689eb4 + languageName: node + linkType: hard + "difflib@npm:^0.2.4": version: 0.2.4 resolution: "difflib@npm:0.2.4" @@ -4761,10 +4743,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.3.47, electron-to-chromium@npm:^1.4.668": - version: 1.4.756 - resolution: "electron-to-chromium@npm:1.4.756" - checksum: 10c0/c983c7d1b84f0bc73211f77504c3a4c58f2d01f55af640d230549eaca0a0667ad515672ddb2ae5c3f37762ca6a71aa20c2baaea0a63a61cb52415105c44b85c0 +"electron-to-chromium@npm:^1.3.47, electron-to-chromium@npm:^1.5.4": + version: 1.5.13 + resolution: "electron-to-chromium@npm:1.5.13" + checksum: 10c0/1d88ac39447e1d718c4296f92fe89836df4688daf2d362d6c49108136795f05a56dd9c950f1c6715e0395fa037c3b5f5ea686c543fdc90e6d74a005877c45022 languageName: node linkType: hard @@ -4784,8 +4766,8 @@ __metadata: linkType: hard "elliptic@npm:^6.5.2, elliptic@npm:^6.5.4": - version: 6.5.5 - resolution: "elliptic@npm:6.5.5" + version: 6.5.7 + resolution: "elliptic@npm:6.5.7" dependencies: bn.js: "npm:^4.11.9" brorand: "npm:^1.1.0" @@ -4794,7 +4776,7 @@ __metadata: inherits: "npm:^2.0.4" minimalistic-assert: "npm:^1.0.1" minimalistic-crypto-utils: "npm:^1.0.1" - checksum: 10c0/3e591e93783a1b66f234ebf5bd3a8a9a8e063a75073a35a671e03e3b25253b6e33ac121f7efe9b8808890fffb17b40596cc19d01e6e8d1fa13b9a56ff65597c8 + checksum: 10c0/799959b6c54ea3564e8961f35abdf8c77e37617f3051614b05ab1fb6a04ddb65bd1caa75ed1bae375b15dda312a0f79fed26ebe76ecf05c5a7af244152a601b8 languageName: node linkType: hard @@ -4987,13 +4969,6 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:4.0.0, escape-string-regexp@npm:^4.0.0": - version: 4.0.0 - resolution: "escape-string-regexp@npm:4.0.0" - checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 - languageName: node - linkType: hard - "escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" @@ -5001,6 +4976,13 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 + languageName: node + linkType: hard + "escodegen@npm:1.8.x": version: 1.8.1 resolution: "escodegen@npm:1.8.1" @@ -5031,10 +5013,10 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-no-only-tests@npm:^3.1.0": - version: 3.1.0 - resolution: "eslint-plugin-no-only-tests@npm:3.1.0" - checksum: 10c0/c710ae04094cfa4695c44efe8d5036eb881893157accf3564b96f3ee5626edef855c93ec1801557e888e390e1892775da79d9564e1a33b83941fba994725b9cd +"eslint-plugin-no-only-tests@npm:^3.3.0": + version: 3.3.0 + resolution: "eslint-plugin-no-only-tests@npm:3.3.0" + checksum: 10c0/a04425d9d3bcd745267168782eb12a3a712b8357264ddd4e204204318975c2c21e2c1efe68113181de908548a85762205b61d8f92ec9dc5e0a5ae54c0240a24d languageName: node linkType: hard @@ -5339,11 +5321,11 @@ __metadata: linkType: hard "ethereum-bloom-filters@npm:^1.0.6": - version: 1.1.0 - resolution: "ethereum-bloom-filters@npm:1.1.0" + version: 1.2.0 + resolution: "ethereum-bloom-filters@npm:1.2.0" dependencies: "@noble/hashes": "npm:^1.4.0" - checksum: 10c0/54b0b7a1fdf12fe02fc8f605f213d11ea026111b9d2af79ff58e8319c904d9d6cee77c62fe70bee62c4d0c7952caf58ebaf47a889d9e4199cf4da1a361a87b53 + checksum: 10c0/7a0ed420cb2e85f621042d78576eb4ddea535a57f3186e314160604b29c37bcd0d3561b03695971e3a96e9c9db402b87de7248a1ac640cbc3dda1b8077cf841f languageName: node linkType: hard @@ -5397,14 +5379,14 @@ __metadata: linkType: hard "ethereum-cryptography@npm:^2.0.0, ethereum-cryptography@npm:^2.1.2": - version: 2.1.3 - resolution: "ethereum-cryptography@npm:2.1.3" + version: 2.2.1 + resolution: "ethereum-cryptography@npm:2.2.1" dependencies: - "@noble/curves": "npm:1.3.0" - "@noble/hashes": "npm:1.3.3" - "@scure/bip32": "npm:1.3.3" - "@scure/bip39": "npm:1.2.2" - checksum: 10c0/a2f25ad5ffa44b4364b1540a57969ee6f1dd820aa08a446f40f31203fef54a09442a6c099e70e7c1485922f6391c4c45b90f2c401e04d88ac9cc4611b05e606f + "@noble/curves": "npm:1.4.2" + "@noble/hashes": "npm:1.4.0" + "@scure/bip32": "npm:1.4.0" + "@scure/bip39": "npm:1.3.0" + checksum: 10c0/c6c7626d393980577b57f709878b2eb91f270fe56116044b1d7afb70d5c519cddc0c072e8c05e4a335e05342eb64d9c3ab39d52f78bb75f76ad70817da9645ef languageName: node linkType: hard @@ -5639,7 +5621,7 @@ __metadata: languageName: node linkType: hard -"ethers@npm:^6.13.2": +"ethers@npm:^6.13.2, ethers@npm:^6.7.0": version: 6.13.2 resolution: "ethers@npm:6.13.2" dependencies: @@ -5654,21 +5636,6 @@ __metadata: languageName: node linkType: hard -"ethers@npm:^6.7.0": - version: 6.12.1 - resolution: "ethers@npm:6.12.1" - dependencies: - "@adraffy/ens-normalize": "npm:1.10.1" - "@noble/curves": "npm:1.2.0" - "@noble/hashes": "npm:1.3.2" - "@types/node": "npm:18.15.13" - aes-js: "npm:4.0.0-beta.5" - tslib: "npm:2.4.0" - ws: "npm:8.5.0" - checksum: 10c0/7686e1efdb0a831578f35d69188783c225de5a6fbb1b422327bc45cee04d49a2707e73c9342a6a5eb2870ce35668c71372737439ec3993d31d83f4a0e2446cc7 - languageName: node - linkType: hard - "ethjs-unit@npm:0.1.6": version: 0.1.6 resolution: "ethjs-unit@npm:0.1.6" @@ -5816,6 +5783,13 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.0.1 + resolution: "fast-uri@npm:3.0.1" + checksum: 10c0/3cd46d6006083b14ca61ffe9a05b8eef75ef87e9574b6f68f2e17ecf4daa7aaadeff44e3f0f7a0ef4e0f7e7c20fc07beec49ff14dc72d0b500f00386592f2d10 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" @@ -5861,16 +5835,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:5.0.0, find-up@npm:^5.0.0": - version: 5.0.0 - resolution: "find-up@npm:5.0.0" - dependencies: - locate-path: "npm:^6.0.0" - path-exists: "npm:^4.0.0" - checksum: 10c0/062c5a83a9c02f53cdd6d175a37ecf8f87ea5bbff1fdfb828f04bfa021441bc7583e8ebc0872a4c1baab96221fb8a8a275a19809fb93fbc40bd69ec35634069a - languageName: node - linkType: hard - "find-up@npm:^1.0.0": version: 1.1.2 resolution: "find-up@npm:1.1.2" @@ -5890,6 +5854,16 @@ __metadata: languageName: node linkType: hard +"find-up@npm:^5.0.0": + version: 5.0.0 + resolution: "find-up@npm:5.0.0" + dependencies: + locate-path: "npm:^6.0.0" + path-exists: "npm:^4.0.0" + checksum: 10c0/062c5a83a9c02f53cdd6d175a37ecf8f87ea5bbff1fdfb828f04bfa021441bc7583e8ebc0872a4c1baab96221fb8a8a275a19809fb93fbc40bd69ec35634069a + languageName: node + linkType: hard + "find-up@npm:^7.0.0": version: 7.0.0 resolution: "find-up@npm:7.0.0" @@ -5947,12 +5921,12 @@ __metadata: linkType: hard "foreground-child@npm:^3.1.0": - version: 3.1.1 - resolution: "foreground-child@npm:3.1.1" + version: 3.3.0 + resolution: "foreground-child@npm:3.3.0" dependencies: cross-spawn: "npm:^7.0.0" signal-exit: "npm:^4.0.1" - checksum: 10c0/9700a0285628abaeb37007c9a4d92bd49f67210f09067638774338e146c8e9c825c5c877f072b2f75f41dc6a2d0be8664f79ffc03f6576649f54a84fb9b47de0 + checksum: 10c0/028f1d41000553fcfa6c4bb5c372963bf3d9bf0b1f25a87d1a6253014343fb69dfb1b42d9625d7cf44c8ba429940f3d0ff718b62105d4d4a4f6ef8ca0a53faa2 languageName: node linkType: hard @@ -6312,31 +6286,19 @@ __metadata: languageName: node linkType: hard -"glob@npm:8.1.0, glob@npm:^8.0.3": - version: 8.1.0 - resolution: "glob@npm:8.1.0" - dependencies: - fs.realpath: "npm:^1.0.0" - inflight: "npm:^1.0.4" - inherits: "npm:2" - minimatch: "npm:^5.0.1" - once: "npm:^1.3.0" - checksum: 10c0/cb0b5cab17a59c57299376abe5646c7070f8acb89df5595b492dba3bfb43d301a46c01e5695f01154e6553168207cb60d4eaf07d3be4bc3eb9b0457c5c561d0f - languageName: node - linkType: hard - "glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.3.12 - resolution: "glob@npm:10.3.12" + version: 10.4.5 + resolution: "glob@npm:10.4.5" dependencies: foreground-child: "npm:^3.1.0" - jackspeak: "npm:^2.3.6" - minimatch: "npm:^9.0.1" - minipass: "npm:^7.0.4" - path-scurry: "npm:^1.10.2" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" bin: glob: dist/esm/bin.mjs - checksum: 10c0/f60cefdc1cf3f958b2bb5823e1b233727f04916d489dc4641d76914f016e6704421e06a83cbb68b0cb1cb9382298b7a88075b844ad2127fc9727ea22b18b0711 + checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e languageName: node linkType: hard @@ -6383,6 +6345,19 @@ __metadata: languageName: node linkType: hard +"glob@npm:^8.0.3, glob@npm:^8.1.0": + version: 8.1.0 + resolution: "glob@npm:8.1.0" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^5.0.1" + once: "npm:^1.3.0" + checksum: 10c0/cb0b5cab17a59c57299376abe5646c7070f8acb89df5595b492dba3bfb43d301a46c01e5695f01154e6553168207cb60d4eaf07d3be4bc3eb9b0457c5c561d0f + languageName: node + linkType: hard + "global-directory@npm:^4.0.1": version: 4.0.1 resolution: "global-directory@npm:4.0.1" @@ -6422,6 +6397,13 @@ __metadata: languageName: node linkType: hard +"globals@npm:^11.1.0": + version: 11.12.0 + resolution: "globals@npm:11.12.0" + checksum: 10c0/758f9f258e7b19226bd8d4af5d3b0dcf7038780fb23d82e6f98932c44e239f884847f1766e8fa9cc5635ccb3204f7fa7314d4408dd4002a5e8ea827b4018f0a1 + languageName: node + linkType: hard + "globals@npm:^14.0.0": version: 14.0.0 resolution: "globals@npm:14.0.0" @@ -6630,9 +6612,9 @@ __metadata: languageName: node linkType: hard -"hardhat@npm:^2.22.8": - version: 2.22.8 - resolution: "hardhat@npm:2.22.8" +"hardhat@npm:^2.22.9": + version: 2.22.9 + resolution: "hardhat@npm:2.22.9" dependencies: "@ethersproject/abi": "npm:^5.1.2" "@metamask/eth-sig-util": "npm:^4.0.0" @@ -6687,7 +6669,7 @@ __metadata: optional: true bin: hardhat: internal/cli/bootstrap.js - checksum: 10c0/0df99b42efba6942f30f3ef1e3b46012a8ff745fbf5a946dc7611690f9c13d29b79aff4ce71369911b610a31e84e7ac93fa797be25dc4a0f26dfc5cd94643f92 + checksum: 10c0/172a0ecab081c76b6da68f84297ccf24e5ad9e9ba3372b5c456d848f3de96d92ecbae7d0e80d9dfeca9a17773e30dc208ea45d5855594605db42bf915b749174 languageName: node linkType: hard @@ -6797,7 +6779,7 @@ __metadata: languageName: node linkType: hard -"he@npm:1.2.0": +"he@npm:^1.2.0": version: 1.2.0 resolution: "he@npm:1.2.0" bin: @@ -6938,12 +6920,12 @@ __metadata: linkType: hard "https-proxy-agent@npm:^7.0.1": - version: 7.0.4 - resolution: "https-proxy-agent@npm:7.0.4" + version: 7.0.5 + resolution: "https-proxy-agent@npm:7.0.5" dependencies: agent-base: "npm:^7.0.2" debug: "npm:4" - checksum: 10c0/bc4f7c38da32a5fc622450b6cb49a24ff596f9bd48dcedb52d2da3fa1c1a80e100fb506bd59b326c012f21c863c69b275c23de1a01d0b84db396822fdf25e52b + checksum: 10c0/2490e3acec397abeb88807db52cac59102d5ed758feee6df6112ab3ccd8325e8a1ce8bce6f4b66e5470eca102d31e425ace904242e4fa28dbe0c59c4bafa7b2c languageName: node linkType: hard @@ -6954,12 +6936,12 @@ __metadata: languageName: node linkType: hard -"husky@npm:^9.1.4": - version: 9.1.4 - resolution: "husky@npm:9.1.4" +"husky@npm:^9.1.5": + version: 9.1.5 + resolution: "husky@npm:9.1.5" bin: husky: bin.js - checksum: 10c0/f5185003bef9ad9ec3f40e821963e4c12409b993fdcab89e3d660bed7d8c9d8bfd399f05222e27e0ead6589601fb1bb08d1a589c51751a4ab0547ead3429b8de + checksum: 10c0/f42efb95a026303eb880898760f802d88409780dd72f17781d2dfc302177d4f80b641cf1f1694f53f6d97c536c7397684133d8c8fe4a4426f7460186a7d1c6b8 languageName: node linkType: hard @@ -6982,9 +6964,9 @@ __metadata: linkType: hard "ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.1": - version: 5.3.1 - resolution: "ignore@npm:5.3.1" - checksum: 10c0/703f7f45ffb2a27fb2c5a8db0c32e7dee66b33a225d28e8db4e1be6474795f606686a6e3bcc50e1aa12f2042db4c9d4a7d60af3250511de74620fbed052ea4cd + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 languageName: node linkType: hard @@ -7003,9 +6985,9 @@ __metadata: linkType: hard "immutable@npm:^4.0.0-rc.12": - version: 4.3.5 - resolution: "immutable@npm:4.3.5" - checksum: 10c0/63d2d7908241a955d18c7822fd2215b6e89ff5a1a33cc72cd475b013cbbdef7a705aa5170a51ce9f84a57f62fdddfaa34e7b5a14b33d8a43c65cc6a881d6e894 + version: 4.3.7 + resolution: "immutable@npm:4.3.7" + checksum: 10c0/9b099197081b22f6433003e34929da8ecddbbdc1474cdc8aa3b7669dee4adda349c06143de22def36016d1b6de5322b043eccd7a11db1dad2ca85dad4fff5435 languageName: node linkType: hard @@ -7187,11 +7169,11 @@ __metadata: linkType: hard "is-core-module@npm:^2.13.0": - version: 2.13.1 - resolution: "is-core-module@npm:2.13.1" + version: 2.15.1 + resolution: "is-core-module@npm:2.15.1" dependencies: - hasown: "npm:^2.0.0" - checksum: 10c0/2cba9903aaa52718f11c4896dabc189bab980870aae86a62dc0d5cedb546896770ee946fb14c84b7adf0735f5eaea4277243f1b95f5cefa90054f92fbcac2518 + hasown: "npm:^2.0.2" + checksum: 10c0/53432f10c69c40bfd2fa8914133a68709ff9498c86c3bf5fca3cdf3145a56fd2168cbf4a43b29843a6202a120a5f9c5ffba0a4322e1e3441739bc0b641682612 languageName: node linkType: hard @@ -7498,16 +7480,16 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.3.6": - version: 2.3.6 - resolution: "jackspeak@npm:2.3.6" +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" dependencies: "@isaacs/cliui": "npm:^8.0.2" "@pkgjs/parseargs": "npm:^0.11.0" dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 + checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 languageName: node linkType: hard @@ -7525,11 +7507,11 @@ __metadata: linkType: hard "jiti@npm:^1.19.1": - version: 1.21.0 - resolution: "jiti@npm:1.21.0" + version: 1.21.6 + resolution: "jiti@npm:1.21.6" bin: jiti: bin/jiti.js - checksum: 10c0/7f361219fe6c7a5e440d5f1dba4ab763a5538d2df8708cdc22561cf25ea3e44b837687931fca7cdd8cdd9f567300e90be989dd1321650045012d8f9ed6aab07f + checksum: 10c0/05b9ed58cd30d0c3ccd3c98209339e74f50abd9a17e716f65db46b6a35812103f6bde6e134be7124d01745586bca8cc5dae1d0d952267c3ebe55171949c32e56 languageName: node linkType: hard @@ -7566,7 +7548,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:4.1.0, js-yaml@npm:^4.1.0": +"js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" dependencies: @@ -7600,6 +7582,15 @@ __metadata: languageName: node linkType: hard +"jsesc@npm:^2.5.1": + version: 2.5.2 + resolution: "jsesc@npm:2.5.2" + bin: + jsesc: bin/jsesc + checksum: 10c0/dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88 + languageName: node + linkType: hard + "jsesc@npm:~0.5.0": version: 0.5.0 resolution: "jsesc@npm:0.5.0" @@ -7961,7 +7952,7 @@ __metadata: "@eslint/compat": "npm:^1.1.1" "@eslint/js": "npm:^9.9.0" "@nomicfoundation/hardhat-chai-matchers": "npm:^2.0.7" - "@nomicfoundation/hardhat-ethers": "npm:^3.0.6" + "@nomicfoundation/hardhat-ethers": "npm:^3.0.7" "@nomicfoundation/hardhat-ignition": "npm:^0.15.5" "@nomicfoundation/hardhat-ignition-ethers": "npm:^0.15.5" "@nomicfoundation/hardhat-network-helpers": "npm:^1.0.11" @@ -7976,30 +7967,31 @@ __metadata: "@types/eslint": "npm:^9.6.0" "@types/eslint__js": "npm:^8.42.3" "@types/mocha": "npm:10.0.7" - "@types/node": "npm:20.14.15" + "@types/node": "npm:20.16.1" bigint-conversion: "npm:^2.4.3" chai: "npm:^4.5.0" chalk: "npm:^4.1.2" dotenv: "npm:^16.4.5" eslint: "npm:^9.9.0" eslint-config-prettier: "npm:^9.1.0" - eslint-plugin-no-only-tests: "npm:^3.1.0" + eslint-plugin-no-only-tests: "npm:^3.3.0" eslint-plugin-prettier: "npm:^5.2.1" eslint-plugin-simple-import-sort: "npm:12.1.1" ethereumjs-util: "npm:^7.1.5" ethers: "npm:^6.13.2" glob: "npm:^11.0.0" globals: "npm:^15.9.0" - hardhat: "npm:^2.22.8" + hardhat: "npm:^2.22.9" hardhat-contract-sizer: "npm:^2.10.0" hardhat-gas-reporter: "npm:^1.0.10" hardhat-ignore-warnings: "npm:^0.2.11" hardhat-tracer: "npm:3.1.0" hardhat-watcher: "npm:2.5.0" - husky: "npm:^9.1.4" - lint-staged: "npm:^15.2.8" + husky: "npm:^9.1.5" + lint-staged: "npm:^15.2.9" openzeppelin-solidity: "npm:2.0.0" prettier: "npm:^3.3.3" + prettier-plugin-solidity: "npm:^1.4.1" solhint: "npm:^5.0.3" solhint-plugin-lido: "npm:^0.0.4" solidity-coverage: "npm:^0.8.12" @@ -8007,7 +7999,7 @@ __metadata: tsconfig-paths: "npm:^4.2.0" typechain: "npm:^8.3.2" typescript: "npm:^5.5.4" - typescript-eslint: "npm:^8.0.1" + typescript-eslint: "npm:^8.2.0" languageName: unknown linkType: soft @@ -8025,9 +8017,9 @@ __metadata: languageName: node linkType: hard -"lint-staged@npm:^15.2.8": - version: 15.2.8 - resolution: "lint-staged@npm:15.2.8" +"lint-staged@npm:^15.2.9": + version: 15.2.9 + resolution: "lint-staged@npm:15.2.9" dependencies: chalk: "npm:~5.3.0" commander: "npm:~12.1.0" @@ -8041,7 +8033,7 @@ __metadata: yaml: "npm:~2.5.0" bin: lint-staged: bin/lint-staged.js - checksum: 10c0/7d43f11f493d27951c746b4c077fed16ba954c0517cf2fd999034e9e7bf86fde506a797b23531a56a1fde4c24846e0f6583ce6db3bdfd42e92335b1aab367737 + checksum: 10c0/820c622378b62b826974af17f1747e2a4b0556e4fb99d101af89ad298d392ff079f580fdc576f16a27e975d726b95d73495fd524139402ff654c4649ef2f1a6a languageName: node linkType: hard @@ -8212,7 +8204,7 @@ __metadata: languageName: node linkType: hard -"log-symbols@npm:4.1.0": +"log-symbols@npm:^4.1.0": version: 4.1.0 resolution: "log-symbols@npm:4.1.0" dependencies: @@ -8263,9 +8255,9 @@ __metadata: linkType: hard "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": - version: 10.2.2 - resolution: "lru-cache@npm:10.2.2" - checksum: 10c0/402d31094335851220d0b00985084288136136992979d0e015f0f1697e15d1c86052d7d53ae86b614e5b058425606efffc6969a31a091085d7a2b80a8a1e26d6 + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb languageName: node linkType: hard @@ -8285,15 +8277,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^6.0.0": - version: 6.0.0 - resolution: "lru-cache@npm:6.0.0" - dependencies: - yallist: "npm:^4.0.0" - checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9 - languageName: node - linkType: hard - "lru_map@npm:^0.3.3": version: 0.3.3 resolution: "lru_map@npm:0.3.3" @@ -8418,17 +8401,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.4": - version: 4.0.5 - resolution: "micromatch@npm:4.0.5" - dependencies: - braces: "npm:^3.0.2" - picomatch: "npm:^2.3.1" - checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff - languageName: node - linkType: hard - -"micromatch@npm:~4.0.7": +"micromatch@npm:^4.0.4, micromatch@npm:~4.0.7": version: 4.0.7 resolution: "micromatch@npm:4.0.7" dependencies: @@ -8514,15 +8487,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:5.0.1": - version: 5.0.1 - resolution: "minimatch@npm:5.0.1" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10c0/baa60fc5839205f13d6c266d8ad4d160ae37c33f66b130b5640acac66deff84b934ac6307f5dc5e4b30362c51284817c12df7c9746ffb600b9009c581e0b1634 - languageName: node - linkType: hard - "minimatch@npm:^10.0.0": version: 10.0.1 resolution: "minimatch@npm:10.0.1" @@ -8532,7 +8496,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^5.0.1, minimatch@npm:^5.1.0": +"minimatch@npm:^5.0.1, minimatch@npm:^5.1.0, minimatch@npm:^5.1.6": version: 5.1.6 resolution: "minimatch@npm:5.1.6" dependencies: @@ -8541,12 +8505,12 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1, minimatch@npm:^9.0.4": - version: 9.0.4 - resolution: "minimatch@npm:9.0.4" +"minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" dependencies: brace-expansion: "npm:^2.0.1" - checksum: 10c0/2c16f21f50e64922864e560ff97c587d15fd491f65d92a677a344e970fe62aafdbeafe648965fa96d33c061b4d0eabfe0213466203dd793367e7f28658cf6414 + checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed languageName: node linkType: hard @@ -8624,14 +8588,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4": - version: 7.1.0 - resolution: "minipass@npm:7.1.0" - checksum: 10c0/6861c6ec9dc3cb99c745b287d92b2a8f409951852940205b4bb106faceb790544288622a0db7aa152f37793e2fc8f303628787883d9a679f2126605204feb97f - languageName: node - linkType: hard - -"minipass@npm:^7.1.2": +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": version: 7.1.2 resolution: "minipass@npm:7.1.2" checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557 @@ -8678,33 +8635,33 @@ __metadata: linkType: hard "mocha@npm:^10.0.0, mocha@npm:^10.2.0": - version: 10.4.0 - resolution: "mocha@npm:10.4.0" - dependencies: - ansi-colors: "npm:4.1.1" - browser-stdout: "npm:1.3.1" - chokidar: "npm:3.5.3" - debug: "npm:4.3.4" - diff: "npm:5.0.0" - escape-string-regexp: "npm:4.0.0" - find-up: "npm:5.0.0" - glob: "npm:8.1.0" - he: "npm:1.2.0" - js-yaml: "npm:4.1.0" - log-symbols: "npm:4.1.0" - minimatch: "npm:5.0.1" - ms: "npm:2.1.3" - serialize-javascript: "npm:6.0.0" - strip-json-comments: "npm:3.1.1" - supports-color: "npm:8.1.1" - workerpool: "npm:6.2.1" - yargs: "npm:16.2.0" - yargs-parser: "npm:20.2.4" - yargs-unparser: "npm:2.0.0" + version: 10.7.3 + resolution: "mocha@npm:10.7.3" + dependencies: + ansi-colors: "npm:^4.1.3" + browser-stdout: "npm:^1.3.1" + chokidar: "npm:^3.5.3" + debug: "npm:^4.3.5" + diff: "npm:^5.2.0" + escape-string-regexp: "npm:^4.0.0" + find-up: "npm:^5.0.0" + glob: "npm:^8.1.0" + he: "npm:^1.2.0" + js-yaml: "npm:^4.1.0" + log-symbols: "npm:^4.1.0" + minimatch: "npm:^5.1.6" + ms: "npm:^2.1.3" + serialize-javascript: "npm:^6.0.2" + strip-json-comments: "npm:^3.1.1" + supports-color: "npm:^8.1.1" + workerpool: "npm:^6.5.1" + yargs: "npm:^16.2.0" + yargs-parser: "npm:^20.2.9" + yargs-unparser: "npm:^2.0.0" bin: _mocha: bin/_mocha mocha: bin/mocha.js - checksum: 10c0/e572e9d8c164e98f64de7e9498608de042fd841c6a7441f456a5e216e9aed2299e2c568d9dc27f2be2de06521e6b2d1dd774ab58a243b1c7697d14aec2f0f7f7 + checksum: 10c0/76a205905ec626262d903954daca31ba8e0dd4347092f627b98b8508dcdb5b30be62ec8f7a405fab3b2e691bdc099721c3291b330c3ee85b8ec40d3d179f8728 languageName: node linkType: hard @@ -8736,7 +8693,7 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.3, ms@npm:^2.1.1": +"ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 @@ -8833,8 +8790,8 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 10.1.0 - resolution: "node-gyp@npm:10.1.0" + version: 10.2.0 + resolution: "node-gyp@npm:10.2.0" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" @@ -8842,13 +8799,13 @@ __metadata: graceful-fs: "npm:^4.2.6" make-fetch-happen: "npm:^13.0.0" nopt: "npm:^7.0.0" - proc-log: "npm:^3.0.0" + proc-log: "npm:^4.1.0" semver: "npm:^7.3.5" - tar: "npm:^6.1.2" + tar: "npm:^6.2.1" which: "npm:^4.0.0" bin: node-gyp: bin/node-gyp.js - checksum: 10c0/9cc821111ca244a01fb7f054db7523ab0a0cd837f665267eb962eb87695d71fb1e681f9e21464cc2fd7c05530dc4c81b810bca1a88f7d7186909b74477491a3c + checksum: 10c0/00630d67dbd09a45aee0a5d55c05e3916ca9e6d427ee4f7bc392d2d3dc5fad7449b21fc098dd38260a53d9dcc9c879b36704a1994235d4707e7271af7e9a835b languageName: node linkType: hard @@ -8861,10 +8818,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.14": - version: 2.0.14 - resolution: "node-releases@npm:2.0.14" - checksum: 10c0/199fc93773ae70ec9969bc6d5ac5b2bbd6eb986ed1907d751f411fef3ede0e4bfdb45ceb43711f8078bea237b6036db8b1bf208f6ff2b70c7d615afd157f3ab9 +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: 10c0/786ac9db9d7226339e1dc84bbb42007cb054a346bd9257e6aa154d294f01bc6a6cddb1348fa099f079be6580acbb470e3c048effd5f719325abd0179e566fd27 languageName: node linkType: hard @@ -8964,9 +8921,9 @@ __metadata: linkType: hard "object-inspect@npm:^1.13.1": - version: 1.13.1 - resolution: "object-inspect@npm:1.13.1" - checksum: 10c0/fad603f408e345c82e946abdf4bfd774260a5ed3e5997a0b057c44153ac32c7271ff19e3a5ae39c858da683ba045ccac2f65245c12763ce4e8594f818f4a648d + version: 1.13.2 + resolution: "object-inspect@npm:1.13.2" + checksum: 10c0/b97835b4c91ec37b5fd71add84f21c3f1047d1d155d00c0fcd6699516c256d4fcc6ff17a1aced873197fe447f91a3964178fd2a67a1ee2120cdaf60e81a050b4 languageName: node linkType: hard @@ -9319,13 +9276,13 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.10.2": - version: 1.10.2 - resolution: "path-scurry@npm:1.10.2" +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" dependencies: lru-cache: "npm:^10.2.0" minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - checksum: 10c0/d723777fbf9627f201e64656680f66ebd940957eebacf780e6cce1c2919c29c116678b2d7dbf8821b3a2caa758d125f4444005ccec886a25c8f324504e48e601 + checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d languageName: node linkType: hard @@ -9384,10 +9341,10 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0": - version: 1.0.0 - resolution: "picocolors@npm:1.0.0" - checksum: 10c0/20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7 +"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1": + version: 1.0.1 + resolution: "picocolors@npm:1.0.1" + checksum: 10c0/c63cdad2bf812ef0d66c8db29583802355d4ca67b9285d846f390cc15c2f6ccb94e8cb7eb6a6e97fc5990a6d3ad4ae42d86c84d3146e667c739a4234ed50d400 languageName: node linkType: hard @@ -9488,6 +9445,18 @@ __metadata: languageName: node linkType: hard +"prettier-plugin-solidity@npm:^1.4.1": + version: 1.4.1 + resolution: "prettier-plugin-solidity@npm:1.4.1" + dependencies: + "@solidity-parser/parser": "npm:^0.18.0" + semver: "npm:^7.5.4" + peerDependencies: + prettier: ">=2.3.0" + checksum: 10c0/5ea7631fe01002319b87bf493e96b7b1cdc442fe4faebf227a4d5accb953140af6b3f63a330de53b1139b56e0ff8de6f055b84c902b75ba331824302d604418d + languageName: node + linkType: hard + "prettier@npm:^2.3.1, prettier@npm:^2.8.3": version: 2.8.8 resolution: "prettier@npm:2.8.8" @@ -9513,14 +9482,7 @@ __metadata: languageName: node linkType: hard -"proc-log@npm:^3.0.0": - version: 3.0.0 - resolution: "proc-log@npm:3.0.0" - checksum: 10c0/f66430e4ff947dbb996058f6fd22de2c66612ae1a89b097744e17fb18a4e8e7a86db99eda52ccf15e53f00b63f4ec0b0911581ff2aac0355b625c8eac509b0dc - languageName: node - linkType: hard - -"proc-log@npm:^4.2.0": +"proc-log@npm:^4.1.0, proc-log@npm:^4.2.0": version: 4.2.0 resolution: "proc-log@npm:4.2.0" checksum: 10c0/17db4757c2a5c44c1e545170e6c70a26f7de58feb985091fb1763f5081cab3d01b181fb2dd240c9f4a4255a1d9227d163d5771b7e69c9e49a561692db865efb9 @@ -9616,11 +9578,11 @@ __metadata: linkType: hard "qs@npm:^6.4.0": - version: 6.12.1 - resolution: "qs@npm:6.12.1" + version: 6.13.0 + resolution: "qs@npm:6.13.0" dependencies: side-channel: "npm:^1.0.6" - checksum: 10c0/439e6d7c6583e7c69f2cab2c39c55b97db7ce576e4c7c469082b938b7fc8746e8d547baacb69b4cd2b6666484776c3f4840ad7163a4c5326300b0afa0acdd84b + checksum: 10c0/62372cdeec24dc83a9fb240b7533c0fdcf0c5f7e0b83343edd7310f0ab4c8205a5e7c56406531f2e47e1b4878a3821d652be4192c841de5b032ca83619d8f860 languageName: node linkType: hard @@ -10263,23 +10225,12 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.6.0": - version: 7.6.0 - resolution: "semver@npm:7.6.0" - dependencies: - lru-cache: "npm:^6.0.0" - bin: - semver: bin/semver.js - checksum: 10c0/fbfe717094ace0aa8d6332d7ef5ce727259815bd8d8815700853f4faf23aacbd7192522f0dc5af6df52ef4fa85a355ebd2f5d39f554bd028200d6cf481ab9b53 - languageName: node - linkType: hard - -"semver@npm:^7.6.2": - version: 7.6.2 - resolution: "semver@npm:7.6.2" +"semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2": + version: 7.6.3 + resolution: "semver@npm:7.6.3" bin: semver: bin/semver.js - checksum: 10c0/97d3441e97ace8be4b1976433d1c32658f6afaff09f143e52c593bae7eef33de19e3e369c88bd985ce1042c6f441c80c6803078d1de2a9988080b66684cbb30c + checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf languageName: node linkType: hard @@ -10292,12 +10243,12 @@ __metadata: languageName: node linkType: hard -"serialize-javascript@npm:6.0.0": - version: 6.0.0 - resolution: "serialize-javascript@npm:6.0.0" +"serialize-javascript@npm:^6.0.2": + version: 6.0.2 + resolution: "serialize-javascript@npm:6.0.2" dependencies: randombytes: "npm:^2.1.0" - checksum: 10c0/73104922ef0a919064346eea21caab99de1a019a1f5fb54a7daa7fcabc39e83b387a2a363e52a889598c3b1bcf507c4b2a7b26df76e991a310657af20eea2e7c + checksum: 10c0/2dd09ef4b65a1289ba24a788b1423a035581bef60817bea1f01eda8e3bda623f86357665fe7ac1b50f6d4f583f97db9615b3f07b2a2e8cbcb75033965f771dd2 languageName: node linkType: hard @@ -10492,17 +10443,17 @@ __metadata: linkType: hard "socks-proxy-agent@npm:^8.0.3": - version: 8.0.3 - resolution: "socks-proxy-agent@npm:8.0.3" + version: 8.0.4 + resolution: "socks-proxy-agent@npm:8.0.4" dependencies: agent-base: "npm:^7.1.1" debug: "npm:^4.3.4" - socks: "npm:^2.7.1" - checksum: 10c0/4950529affd8ccd6951575e21c1b7be8531b24d924aa4df3ee32df506af34b618c4e50d261f4cc603f1bfd8d426915b7d629966c8ce45b05fb5ad8c8b9a6459d + socks: "npm:^2.8.3" + checksum: 10c0/345593bb21b95b0508e63e703c84da11549f0a2657d6b4e3ee3612c312cb3a907eac10e53b23ede3557c6601d63252103494caa306b66560f43af7b98f53957a languageName: node linkType: hard -"socks@npm:^2.7.1": +"socks@npm:^2.8.3": version: 2.8.3 resolution: "socks@npm:2.8.3" dependencies: @@ -10793,9 +10744,9 @@ __metadata: linkType: hard "spdx-license-ids@npm:^3.0.0": - version: 3.0.17 - resolution: "spdx-license-ids@npm:3.0.17" - checksum: 10c0/ddf9477b5afc70f1a7d3bf91f0b8e8a1c1b0fa65d2d9a8b5c991b1a2ba91b693d8b9749700119d5ce7f3fbf307ac421087ff43d321db472605e98a5804f80eac + version: 3.0.20 + resolution: "spdx-license-ids@npm:3.0.20" + checksum: 10c0/bdff7534fad6ef59be49becda1edc3fb7f5b3d6f296a715516ab9d972b8ad59af2c34b2003e01db8970d4c673d185ff696ba74c6b61d3bf327e2b3eac22c297c languageName: node linkType: hard @@ -10933,13 +10884,13 @@ __metadata: linkType: hard "string-width@npm:^7.0.0": - version: 7.1.0 - resolution: "string-width@npm:7.1.0" + version: 7.2.0 + resolution: "string-width@npm:7.2.0" dependencies: emoji-regex: "npm:^10.3.0" get-east-asian-width: "npm:^1.0.0" strip-ansi: "npm:^7.1.0" - checksum: 10c0/68a99fbc3bd3d8eb42886ff38dce819767dee55f606f74dfa4687a07dfd21262745d9683df0aa53bf81a5dd47c13da921a501925b974bec66a7ddd634fef0634 + checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9 languageName: node linkType: hard @@ -11070,7 +11021,7 @@ __metadata: languageName: node linkType: hard -"strip-json-comments@npm:3.1.1, strip-json-comments@npm:^3.1.1": +"strip-json-comments@npm:^3.1.1": version: 3.1.1 resolution: "strip-json-comments@npm:3.1.1" checksum: 10c0/9681a6257b925a7fa0f285851c0e613cc934a50661fa7bb41ca9cbbff89686bb4a0ee366e6ecedc4daafd01e83eee0720111ab294366fe7c185e935475ebcecd @@ -11084,15 +11035,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:8.1.1": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: "npm:^4.0.0" - checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 - languageName: node - linkType: hard - "supports-color@npm:^2.0.0": version: 2.0.0 resolution: "supports-color@npm:2.0.0" @@ -11127,6 +11069,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^8.1.1": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 + languageName: node + linkType: hard + "supports-preserve-symlinks-flag@npm:^1.0.0": version: 1.0.0 resolution: "supports-preserve-symlinks-flag@npm:1.0.0" @@ -11215,7 +11166,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:^6.1.11, tar@npm:^6.1.2": +"tar@npm:^6.1.11, tar@npm:^6.2.1": version: 6.2.1 resolution: "tar@npm:6.2.1" dependencies: @@ -11537,14 +11488,7 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:^4.0.0": - version: 4.0.8 - resolution: "type-detect@npm:4.0.8" - checksum: 10c0/8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd - languageName: node - linkType: hard - -"type-detect@npm:^4.1.0": +"type-detect@npm:^4.0.0, type-detect@npm:^4.1.0": version: 4.1.0 resolution: "type-detect@npm:4.1.0" checksum: 10c0/df8157ca3f5d311edc22885abc134e18ff8ffbc93d6a9848af5b682730ca6a5a44499259750197250479c5331a8a75b5537529df5ec410622041650a7f293e2a @@ -11653,17 +11597,17 @@ __metadata: languageName: node linkType: hard -"typescript-eslint@npm:^8.0.1": - version: 8.0.1 - resolution: "typescript-eslint@npm:8.0.1" +"typescript-eslint@npm:^8.2.0": + version: 8.2.0 + resolution: "typescript-eslint@npm:8.2.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.0.1" - "@typescript-eslint/parser": "npm:8.0.1" - "@typescript-eslint/utils": "npm:8.0.1" + "@typescript-eslint/eslint-plugin": "npm:8.2.0" + "@typescript-eslint/parser": "npm:8.2.0" + "@typescript-eslint/utils": "npm:8.2.0" peerDependenciesMeta: typescript: optional: true - checksum: 10c0/dc9df2dd82863b98720b7555c1fa6c2724055a252ce5940655187667253b717be8697bb798742f23701ee6efcd743d5556f00ab9a3af24a0e735df1e8b24e24a + checksum: 10c0/545569026b3da15625ae827844ce6c529c033286807b8adeb1652bef83f1c8ce900253fc5c0813600145ae4f1ba9cc265e4731902bbb9227d1e7331db9d82637 languageName: node linkType: hard @@ -11702,11 +11646,11 @@ __metadata: linkType: hard "uglify-js@npm:^3.1.4": - version: 3.17.4 - resolution: "uglify-js@npm:3.17.4" + version: 3.19.2 + resolution: "uglify-js@npm:3.19.2" bin: uglifyjs: bin/uglifyjs - checksum: 10c0/8b7fcdca69deb284fed7d2025b73eb747ce37f9aca6af53422844f46427152d5440601b6e2a033e77856a2f0591e4167153d5a21b68674ad11f662034ec13ced + checksum: 10c0/51dbe1304a91cac5daa01f6a2d4ecd545fab7b7d0625e11590b923e95a6d2263b3481dcea974abfc0282b33d2c76f74f1196a992df07eae0847175bc39ea45bb languageName: node linkType: hard @@ -11722,10 +11666,10 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~5.26.4": - version: 5.26.5 - resolution: "undici-types@npm:5.26.5" - checksum: 10c0/bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501 +"undici-types@npm:~6.19.2": + version: 6.19.8 + resolution: "undici-types@npm:6.19.8" + checksum: 10c0/078afa5990fba110f6824823ace86073b4638f1d5112ee26e790155f481f2a868cc3e0615505b6f4282bdf74a3d8caad715fd809e870c2bb0704e3ea6082f344 languageName: node linkType: hard @@ -11791,21 +11735,21 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.13": - version: 1.0.15 - resolution: "update-browserslist-db@npm:1.0.15" +"update-browserslist-db@npm:^1.1.0": + version: 1.1.0 + resolution: "update-browserslist-db@npm:1.1.0" dependencies: escalade: "npm:^3.1.2" - picocolors: "npm:^1.0.0" + picocolors: "npm:^1.0.1" peerDependencies: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 10c0/c5f67dc68aba9a37701a14199e57e22f20c579411d386f47b4d81f6e3f06fd3ec256310594f4f9d6b01bc1cfb93cb1ebb1a1da70c4fa28720bc1d030f55bb8a1 + checksum: 10c0/a7452de47785842736fb71547651c5bbe5b4dc1e3722ccf48a704b7b34e4dcf633991eaa8e4a6a517ffb738b3252eede3773bef673ef9021baa26b056d63a5b9 languageName: node linkType: hard -"uri-js@npm:^4.2.2, uri-js@npm:^4.4.1": +"uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" dependencies: @@ -12132,10 +12076,10 @@ __metadata: languageName: node linkType: hard -"workerpool@npm:6.2.1": - version: 6.2.1 - resolution: "workerpool@npm:6.2.1" - checksum: 10c0/f0efd2d74eafd58eaeb36d7d85837d080f75c52b64893cff317b66257dd308e5c9f85ef0b12904f6c7f24ed2365bc3cfeba1f1d16aa736d84d6ef8156ae37c80 +"workerpool@npm:^6.5.1": + version: 6.5.1 + resolution: "workerpool@npm:6.5.1" + checksum: 10c0/58e8e969782292cb3a7bfba823f1179a7615250a0cefb4841d5166234db1880a3d0fe83a31dd8d648329ec92c2d0cd1890ad9ec9e53674bb36ca43e9753cdeac languageName: node linkType: hard @@ -12228,33 +12172,18 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.5.0": - version: 8.5.0 - resolution: "ws@npm:8.5.0" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 10c0/0baeee03e97865accda8fad51e8e5fa17d19b8e264529efdf662bbba2acc1c7f1de8316287e6df5cb639231a96009e6d5234b57e6ff36ee2d04e49a0995fec2f - languageName: node - linkType: hard - "ws@npm:^5.1.1": - version: 5.2.3 - resolution: "ws@npm:5.2.3" + version: 5.2.4 + resolution: "ws@npm:5.2.4" dependencies: async-limiter: "npm:~1.0.0" - checksum: 10c0/3f329b29a893c660b01be81654c9bca422a0de3396e644aae165e4e998e74b2b713adcbba876f183cd74a4f488376cbb7442d1c87455084d69fce1e2f25ef088 + checksum: 10c0/14e84e4209f86ab68b01b9ebf42c88f81f26a64ff4886ef65d27c734c9b90b8d7e84712da3c3f7a922a4ab58bf0b96544d32ae28ebbd620fcda3027dd5bc7604 languageName: node linkType: hard "ws@npm:^7.4.6": - version: 7.5.9 - resolution: "ws@npm:7.5.9" + version: 7.5.10 + resolution: "ws@npm:7.5.10" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ^5.0.2 @@ -12263,7 +12192,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10c0/aec4ef4eb65821a7dde7b44790f8699cfafb7978c9b080f6d7a98a7f8fc0ce674c027073a78574c94786ba7112cc90fa2cc94fc224ceba4d4b1030cff9662494 + checksum: 10c0/bd7d5f4aaf04fae7960c23dcb6c6375d525e00f795dd20b9385902bd008c40a94d3db3ce97d878acc7573df852056ca546328b27b39f47609f80fb22a0a9b61d languageName: node linkType: hard @@ -12355,13 +12284,6 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:20.2.4": - version: 20.2.4 - resolution: "yargs-parser@npm:20.2.4" - checksum: 10c0/08dc341f0b9f940c2fffc1d1decf3be00e28cabd2b578a694901eccc7dcd10577f10c6aa1b040fdd9a68b2042515a60f18476543bccacf9f3ce2c8534cd87435 - languageName: node - linkType: hard - "yargs-parser@npm:^2.4.1": version: 2.4.1 resolution: "yargs-parser@npm:2.4.1" @@ -12372,7 +12294,7 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^20.2.2": +"yargs-parser@npm:^20.2.2, yargs-parser@npm:^20.2.9": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" checksum: 10c0/0685a8e58bbfb57fab6aefe03c6da904a59769bd803a722bb098bd5b0f29d274a1357762c7258fb487512811b8063fb5d2824a3415a0a4540598335b3b086c72 @@ -12386,7 +12308,7 @@ __metadata: languageName: node linkType: hard -"yargs-unparser@npm:2.0.0": +"yargs-unparser@npm:^2.0.0": version: 2.0.0 resolution: "yargs-unparser@npm:2.0.0" dependencies: @@ -12398,7 +12320,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:16.2.0": +"yargs@npm:^16.2.0": version: 16.2.0 resolution: "yargs@npm:16.2.0" dependencies: @@ -12465,8 +12387,8 @@ __metadata: linkType: hard "yocto-queue@npm:^1.0.0": - version: 1.0.0 - resolution: "yocto-queue@npm:1.0.0" - checksum: 10c0/856117aa15cf5103d2a2fb173f0ab4acb12b4b4d0ed3ab249fdbbf612e55d1cadfd27a6110940e24746fb0a78cf640b522cc8bca76f30a3b00b66e90cf82abe0 + version: 1.1.1 + resolution: "yocto-queue@npm:1.1.1" + checksum: 10c0/cb287fe5e6acfa82690acb43c283de34e945c571a78a939774f6eaba7c285bacdf6c90fbc16ce530060863984c906d2b4c6ceb069c94d1e0a06d5f2b458e2a92 languageName: node linkType: hard