From 4f4a917c6130e997a7f5efe78285bf235acc6120 Mon Sep 17 00:00:00 2001 From: soloseng <102702451+soloseng@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:38:55 -0500 Subject: [PATCH] WIP inheritance issues ? --- .../common/PrecompilesOverrideV2.sol | 72 +++++++ .../contracts-0.8/common/UsingRegistry2.sol | 156 ++++++++++++++ .../contracts-0.8/common/UsingRegistryV2.sol | 200 ++++++++++++++++++ .../devchain/e2e/common/EpochManager.t.sol | 6 +- .../e2e/common/FeeCurrencyDirectory.t.sol | 4 +- .../protocol/test-sol/devchain/e2e/utils.sol | 7 +- .../migration/IntegrationValidators.t.sol | 4 +- .../devchain/migration/Migration.t.sol | 6 +- .../test-sol/unit/common/EpochManager.t.sol | 6 +- .../unit/common/EpochManagerEnabler.t.sol | 6 +- .../unit/common/FeeCurrencyDirectory.t.sol | 15 +- .../test-sol/unit/common/ProxyFactory08.t.sol | 4 +- .../protocol/test-sol/utils/WhenL2-08.sol | 11 + packages/protocol/test-sol/utils08.sol | 51 ++++- 14 files changed, 520 insertions(+), 28 deletions(-) create mode 100644 packages/protocol/contracts-0.8/common/PrecompilesOverrideV2.sol create mode 100644 packages/protocol/contracts-0.8/common/UsingRegistry2.sol create mode 100644 packages/protocol/contracts-0.8/common/UsingRegistryV2.sol create mode 100644 packages/protocol/test-sol/utils/WhenL2-08.sol diff --git a/packages/protocol/contracts-0.8/common/PrecompilesOverrideV2.sol b/packages/protocol/contracts-0.8/common/PrecompilesOverrideV2.sol new file mode 100644 index 00000000000..d3bf0a75337 --- /dev/null +++ b/packages/protocol/contracts-0.8/common/PrecompilesOverrideV2.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity >=0.8.7 <0.8.20; + +import "../../contracts/common/interfaces/ICeloVersionedContract.sol"; +import "../../contracts-0.8/common/IsL2Check.sol"; + +import "./UsingPrecompiles.sol"; +import "./UsingRegistryV2.sol"; + +/** + * @title PrecompilesOverride Contract + * @notice This contract allows for a smoother transition from L1 to L2 + * by abstracting away the usingPrecompile contract, and taking care of the L1 to L2 swtiching logic. + **/ +contract PrecompilesOverrideV2 is UsingPrecompiles, UsingRegistryV2 { + /** + * @notice Returns the epoch number at a block. + * @param blockNumber Block number where epoch number is calculated. + * @return Epoch number. + */ + function getEpochNumberOfBlock(uint256 blockNumber) public view override returns (uint256) { + if (isL2()) { + return getEpochManager().getEpochNumberOfBlock(blockNumber); + } else { + return epochNumberOfBlock(blockNumber, getEpochSize()); + } + } + + /** + * @notice Returns the epoch number at a block. + * @return Current epoch number. + */ + function getEpochNumber() public view override returns (uint256) { + return getEpochNumberOfBlock(block.number); + } + + /** + * @notice Gets a validator signer address from the current validator set. + * @param index Index of requested validator in the validator set. + * @return Address of validator signer at the requested index. + */ + function validatorSignerAddressFromCurrentSet( + uint256 index + ) public view override returns (address) { + if (isL2()) { + return getEpochManager().getElectedSignerByIndex(index); + } else { + return super.validatorSignerAddressFromCurrentSet(index); + } + } + + /** + * @notice Gets a validator address from the current validator set. + * @param index Index of requested validator in the validator set. + * @return Address of validator at the requested index. + */ + function validatorAddressFromCurrentSet(uint256 index) public view onlyL2 returns (address) { + return getEpochManager().getElectedAccountByIndex(index); + } + + /** + * @notice Gets the size of the current elected validator set. + * @return Size of the current elected validator set. + */ + function numberValidatorsInCurrentSet() public view override returns (uint256) { + if (isL2()) { + return getEpochManager().numberOfElectedInCurrentSet(); + } else { + return super.numberValidatorsInCurrentSet(); + } + } +} diff --git a/packages/protocol/contracts-0.8/common/UsingRegistry2.sol b/packages/protocol/contracts-0.8/common/UsingRegistry2.sol new file mode 100644 index 00000000000..a9bfcc8d407 --- /dev/null +++ b/packages/protocol/contracts-0.8/common/UsingRegistry2.sol @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity >=0.8.0 <0.8.20; + +// Note: This is not an exact copy of UsingRegistry or UsingRegistryV2 in the contract's folder +// because Mento's interfaces still don't support Solidity 0.8 + +import "@openzeppelin/contracts8/access/Ownable.sol"; +import "@openzeppelin/contracts8/token/ERC20/IERC20.sol"; + +import "../../contracts/common/interfaces/IRegistry.sol"; +import "../../contracts/common/interfaces/IAccounts.sol"; +import "../../contracts/common/interfaces/IEpochManager.sol"; +import "../../contracts/common/interfaces/IFreezer.sol"; +import "../../contracts/common/interfaces/ICeloUnreleasedTreasury.sol"; +import "../../contracts/common/interfaces/IFeeCurrencyWhitelist.sol"; +import "../../contracts/common/interfaces/IFeeHandlerSeller.sol"; +import "../../contracts/common/interfaces/IEpochManager.sol"; +import "../../contracts/governance/interfaces/IGovernance.sol"; +import "../../contracts/governance/interfaces/ILockedGold.sol"; +import "../../contracts/governance/interfaces/ILockedCelo.sol"; +import "../../contracts/governance/interfaces/IValidators.sol"; +import "../../contracts/governance/interfaces/IElection.sol"; +import "../../contracts/governance/interfaces/IEpochRewards.sol"; +import "../../contracts/stability/interfaces/ISortedOracles.sol"; + +import "./interfaces/IScoreReader.sol"; + +contract UsingRegistryy is Ownable { + // solhint-disable state-visibility + bytes32 constant ACCOUNTS_REGISTRY_ID = keccak256(abi.encodePacked("Accounts")); + bytes32 constant ATTESTATIONS_REGISTRY_ID = keccak256(abi.encodePacked("Attestations")); + bytes32 constant DOWNTIME_SLASHER_REGISTRY_ID = keccak256(abi.encodePacked("DowntimeSlasher")); + bytes32 constant DOUBLE_SIGNING_SLASHER_REGISTRY_ID = + keccak256(abi.encodePacked("DoubleSigningSlasher")); + bytes32 constant ELECTION_REGISTRY_ID = keccak256(abi.encodePacked("Election")); + bytes32 constant EPOCH_REWARDS_REGISTRY_ID = keccak256(abi.encodePacked("EpochRewards")); + bytes32 constant EXCHANGE_REGISTRY_ID = keccak256(abi.encodePacked("Exchange")); + bytes32 constant FEE_CURRENCY_WHITELIST_REGISTRY_ID = + keccak256(abi.encodePacked("FeeCurrencyWhitelist")); + bytes32 constant FREEZER_REGISTRY_ID = keccak256(abi.encodePacked("Freezer")); + bytes32 constant GOLD_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("GoldToken")); + bytes32 constant GOVERNANCE_REGISTRY_ID = keccak256(abi.encodePacked("Governance")); + bytes32 constant GOVERNANCE_SLASHER_REGISTRY_ID = + keccak256(abi.encodePacked("GovernanceSlasher")); + bytes32 constant LOCKED_GOLD_REGISTRY_ID = keccak256(abi.encodePacked("LockedGold")); + bytes32 constant RESERVE_REGISTRY_ID = keccak256(abi.encodePacked("Reserve")); + bytes32 constant RANDOM_REGISTRY_ID = keccak256(abi.encodePacked("Random")); + bytes32 constant SORTED_ORACLES_REGISTRY_ID = keccak256(abi.encodePacked("SortedOracles")); + bytes32 constant STABLE_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("StableToken")); + bytes32 constant VALIDATORS_REGISTRY_ID = keccak256(abi.encodePacked("Validators")); + bytes32 constant MENTOFEEHANDLERSELLER_REGISTRY_ID = + keccak256(abi.encodePacked("MentoFeeHandlerSeller")); + bytes32 constant CELO_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("CeloToken")); + bytes32 constant LOCKED_CELO_REGISTRY_ID = keccak256(abi.encodePacked("LockedCelo")); + bytes32 constant CELO_UNRELEASED_TREASURY_REGISTRY_ID = + keccak256(abi.encodePacked("CeloUnreleasedTreasury")); + bytes32 constant EPOCH_MANAGER_ENABLER_REGISTRY_ID = + keccak256(abi.encodePacked("EpochManagerEnabler")); + bytes32 constant EPOCH_MANAGER_REGISTRY_ID = keccak256(abi.encodePacked("EpochManager")); + bytes32 constant SCORE_MANAGER_REGISTRY_ID = keccak256(abi.encodePacked("ScoreManager")); + // solhint-enable state-visibility + + IRegistry public registry; + + event RegistrySet(address indexed registryAddress); + + modifier onlyRegisteredContract(bytes32 identifierHash) { + require(registry.getAddressForOrDie(identifierHash) == msg.sender, "only registered contract"); + _; + } + + modifier onlyRegisteredContracts(bytes32[] memory identifierHashes) { + require(registry.isOneOf(identifierHashes, msg.sender), "only registered contracts"); + _; + } + + /** + * @notice Updates the address pointing to a Registry contract. + * @param registryAddress The address of a registry contract for routing to other contracts. + */ + function setRegistry(address registryAddress) public onlyOwner { + require(registryAddress != address(0), "Cannot register the null address"); + registry = IRegistry(registryAddress); + emit RegistrySet(registryAddress); + } + + function getGoldToken() internal view returns (IERC20) { + return IERC20(registry.getAddressForOrDie(GOLD_TOKEN_REGISTRY_ID)); + } + + function getCeloToken() internal view returns (IERC20) { + return IERC20(registry.getAddressForOrDie(CELO_TOKEN_REGISTRY_ID)); + } + + function getFreezer() internal view returns (IFreezer) { + return IFreezer(registry.getAddressForOrDie(FREEZER_REGISTRY_ID)); + } + + function getSortedOracles() internal view returns (ISortedOracles) { + return ISortedOracles(registry.getAddressForOrDie(SORTED_ORACLES_REGISTRY_ID)); + } + + function getFeeCurrencyWhitelist() internal view returns (IFeeCurrencyWhitelist) { + return IFeeCurrencyWhitelist(registry.getAddressForOrDie(FEE_CURRENCY_WHITELIST_REGISTRY_ID)); + } + + function getLockedGold() internal view returns (ILockedGold) { + return ILockedGold(registry.getAddressForOrDie(LOCKED_GOLD_REGISTRY_ID)); + } + + function getLockedCelo() internal view returns (ILockedCelo) { + return ILockedCelo(registry.getAddressForOrDie(LOCKED_CELO_REGISTRY_ID)); + } + + // Current version of Mento doesn't support 0.8 + function getStableToken() internal view returns (address) { + return registry.getAddressForOrDie(STABLE_TOKEN_REGISTRY_ID); + } + + function getMentoFeeHandlerSeller() internal view returns (IFeeHandlerSeller) { + return IFeeHandlerSeller(registry.getAddressForOrDie(MENTOFEEHANDLERSELLER_REGISTRY_ID)); + } + + function getAccounts() internal view returns (IAccounts) { + return IAccounts(registry.getAddressForOrDie(ACCOUNTS_REGISTRY_ID)); + } + + function getValidators() internal view returns (IValidators) { + return IValidators(registry.getAddressForOrDie(VALIDATORS_REGISTRY_ID)); + } + + function getElection() internal view returns (IElection) { + return IElection(registry.getAddressForOrDie(ELECTION_REGISTRY_ID)); + } + + function getEpochRewards() internal view returns (IEpochRewards) { + return IEpochRewards(registry.getAddressForOrDie(EPOCH_REWARDS_REGISTRY_ID)); + } + + function getGovernance() internal view returns (IGovernance) { + return IGovernance(registry.getAddressForOrDie(GOVERNANCE_REGISTRY_ID)); + } + + function getCeloUnreleasedTreasury() internal view returns (ICeloUnreleasedTreasury) { + return + ICeloUnreleasedTreasury(registry.getAddressForOrDie(CELO_UNRELEASED_TREASURY_REGISTRY_ID)); + } + + function getEpochManager() internal view returns (IEpochManager) { + return IEpochManager(registry.getAddressForOrDie(EPOCH_MANAGER_REGISTRY_ID)); + } + + function getScoreReader() internal view returns (IScoreReader) { + return IScoreReader(registry.getAddressForOrDie(SCORE_MANAGER_REGISTRY_ID)); + } +} diff --git a/packages/protocol/contracts-0.8/common/UsingRegistryV2.sol b/packages/protocol/contracts-0.8/common/UsingRegistryV2.sol new file mode 100644 index 00000000000..deea520916d --- /dev/null +++ b/packages/protocol/contracts-0.8/common/UsingRegistryV2.sol @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity >=0.8.0 <0.8.20; + +import "@openzeppelin/contracts8/access/Ownable.sol"; +import "@openzeppelin/contracts8/token/ERC20/IERC20.sol"; + +import "../../contracts/common/interfaces/IAccounts.sol"; +import "../../contracts/common/interfaces/IEpochManager.sol"; +import "../../contracts/common/interfaces/IFeeCurrencyWhitelist.sol"; +import "../../contracts/common/interfaces/IFreezer.sol"; +import "../../contracts/common/interfaces/IRegistry.sol"; +import "../../contracts/common/interfaces/ICeloUnreleasedTreasury.sol"; + +import "../../contracts/governance/interfaces/IElection.sol"; +import "../../contracts/governance/interfaces/IEpochRewards.sol"; +import "../../contracts/governance/interfaces/IGovernance.sol"; +import "../../contracts/governance/interfaces/ILockedGold.sol"; +import "../../contracts/governance/interfaces/ILockedCelo.sol"; +import "../../contracts/governance/interfaces/IValidators.sol"; + +import "../../contracts/identity/interfaces/IRandom.sol"; +import "../../contracts/identity/interfaces/IAttestations.sol"; +import "../../contracts/identity/interfaces/IFederatedAttestations.sol"; + +// import "../../lib/mento-core/contracts/interfaces/IExchange.sol"; +// import "../../lib/mento-core/contracts/interfaces/IReserve.sol"; +// import "../../lib/mento-core/contracts/interfaces/IStableToken.sol"; +import "../../contracts/stability/interfaces/ISortedOracles.sol"; + +contract UsingRegistryV2 { + address internal constant registryAddress = 0x000000000000000000000000000000000000ce10; + IRegistry public constant registryContract = IRegistry(registryAddress); + + bytes32 internal constant ACCOUNTS_REGISTRY_ID = keccak256(abi.encodePacked("Accounts")); + bytes32 internal constant ATTESTATIONS_REGISTRY_ID = keccak256(abi.encodePacked("Attestations")); + bytes32 internal constant DOWNTIME_SLASHER_REGISTRY_ID = + keccak256(abi.encodePacked("DowntimeSlasher")); + bytes32 internal constant DOUBLE_SIGNING_SLASHER_REGISTRY_ID = + keccak256(abi.encodePacked("DoubleSigningSlasher")); + bytes32 internal constant ELECTION_REGISTRY_ID = keccak256(abi.encodePacked("Election")); + bytes32 internal constant EXCHANGE_REGISTRY_ID = keccak256(abi.encodePacked("Exchange")); + bytes32 internal constant EXCHANGE_EURO_REGISTRY_ID = keccak256(abi.encodePacked("ExchangeEUR")); + bytes32 internal constant EXCHANGE_REAL_REGISTRY_ID = keccak256(abi.encodePacked("ExchangeBRL")); + + bytes32 internal constant FEE_CURRENCY_WHITELIST_REGISTRY_ID = + keccak256(abi.encodePacked("FeeCurrencyWhitelist")); + bytes32 internal constant FEDERATED_ATTESTATIONS_REGISTRY_ID = + keccak256(abi.encodePacked("FederatedAttestations")); + bytes32 internal constant FREEZER_REGISTRY_ID = keccak256(abi.encodePacked("Freezer")); + bytes32 internal constant GOLD_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("GoldToken")); + bytes32 internal constant GOVERNANCE_REGISTRY_ID = keccak256(abi.encodePacked("Governance")); + bytes32 internal constant GOVERNANCE_SLASHER_REGISTRY_ID = + keccak256(abi.encodePacked("GovernanceSlasher")); + bytes32 internal constant LOCKED_GOLD_REGISTRY_ID = keccak256(abi.encodePacked("LockedGold")); + bytes32 internal constant RESERVE_REGISTRY_ID = keccak256(abi.encodePacked("Reserve")); + bytes32 internal constant RANDOM_REGISTRY_ID = keccak256(abi.encodePacked("Random")); + bytes32 internal constant SORTED_ORACLES_REGISTRY_ID = + keccak256(abi.encodePacked("SortedOracles")); + bytes32 internal constant STABLE_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("StableToken")); + bytes32 internal constant STABLE_EURO_TOKEN_REGISTRY_ID = + keccak256(abi.encodePacked("StableTokenEUR")); + bytes32 internal constant STABLE_REAL_TOKEN_REGISTRY_ID = + keccak256(abi.encodePacked("StableTokenBRL")); + bytes32 internal constant VALIDATORS_REGISTRY_ID = keccak256(abi.encodePacked("Validators")); + bytes32 internal constant CELO_UNRELEASED_TREASURY_REGISTRY_ID = + keccak256(abi.encodePacked("CeloUnreleasedTreasury")); + + bytes32 internal constant CELO_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("CeloToken")); + bytes32 internal constant LOCKED_CELO_REGISTRY_ID = keccak256(abi.encodePacked("LockedCelo")); + bytes32 internal constant EPOCH_REWARDS_REGISTRY_ID = keccak256(abi.encodePacked("EpochRewards")); + bytes32 internal constant EPOCH_MANAGER_ENABLER_REGISTRY_ID = + keccak256(abi.encodePacked("EpochManagerEnabler")); + bytes32 internal constant EPOCH_MANAGER_REGISTRY_ID = keccak256(abi.encodePacked("EpochManager")); + + modifier onlyRegisteredContract(bytes32 identifierHash) { + require( + registryContract.getAddressForOrDie(identifierHash) == msg.sender, + "only registered contract" + ); + _; + } + + modifier onlyRegisteredContracts(bytes32[] memory identifierHashes) { + require(registryContract.isOneOf(identifierHashes, msg.sender), "only registered contracts"); + _; + } + + function getAccounts() internal view returns (IAccounts) { + return IAccounts(registryContract.getAddressForOrDie(ACCOUNTS_REGISTRY_ID)); + } + + function getAttestations() internal view returns (IAttestations) { + return IAttestations(registryContract.getAddressForOrDie(ATTESTATIONS_REGISTRY_ID)); + } + + function getElection() internal view returns (IElection) { + return IElection(registryContract.getAddressForOrDie(ELECTION_REGISTRY_ID)); + } + + // function getExchange() internal view returns (IExchange) { + // return IExchange(registryContract.getAddressForOrDie(EXCHANGE_REGISTRY_ID)); + // } + + // function getExchangeDollar() internal view returns (IExchange) { + // return getExchange(); + // } + + // function getExchangeEuro() internal view returns (IExchange) { + // return IExchange(registryContract.getAddressForOrDie(EXCHANGE_EURO_REGISTRY_ID)); + // } + + // function getExchangeREAL() internal view returns (IExchange) { + // return IExchange(registryContract.getAddressForOrDie(EXCHANGE_REAL_REGISTRY_ID)); + // } + + function getFeeCurrencyWhitelistRegistry() internal view returns (IFeeCurrencyWhitelist) { + return + IFeeCurrencyWhitelist( + registryContract.getAddressForOrDie(FEE_CURRENCY_WHITELIST_REGISTRY_ID) + ); + } + + function getFederatedAttestations() internal view returns (IFederatedAttestations) { + return + IFederatedAttestations( + registryContract.getAddressForOrDie(FEDERATED_ATTESTATIONS_REGISTRY_ID) + ); + } + + function getFreezer() internal view returns (IFreezer) { + return IFreezer(registryContract.getAddressForOrDie(FREEZER_REGISTRY_ID)); + } + + function getGoldToken() internal view returns (IERC20) { + return IERC20(registryContract.getAddressForOrDie(GOLD_TOKEN_REGISTRY_ID)); + } + + function getCeloToken() internal view returns (IERC20) { + return IERC20(registryContract.getAddressForOrDie(CELO_TOKEN_REGISTRY_ID)); + } + + function getGovernance() internal view returns (IGovernance) { + return IGovernance(registryContract.getAddressForOrDie(GOVERNANCE_REGISTRY_ID)); + } + + function getLockedGold() internal view returns (ILockedGold) { + return ILockedGold(registryContract.getAddressForOrDie(LOCKED_GOLD_REGISTRY_ID)); + } + + function getLockedCelo() internal view returns (ILockedCelo) { + return ILockedCelo(registryContract.getAddressForOrDie(LOCKED_CELO_REGISTRY_ID)); + } + + function getRandom() internal view returns (IRandom) { + return IRandom(registryContract.getAddressForOrDie(RANDOM_REGISTRY_ID)); + } + + // function getReserve() internal view returns (IReserve) { + // return IReserve(registryContract.getAddressForOrDie(RESERVE_REGISTRY_ID)); + // } + + function getSortedOracles() internal view returns (ISortedOracles) { + return ISortedOracles(registryContract.getAddressForOrDie(SORTED_ORACLES_REGISTRY_ID)); + } + + // function getStableToken() internal view returns (IStableToken) { + // return IStableToken(registryContract.getAddressForOrDie(STABLE_TOKEN_REGISTRY_ID)); + // } + + // function getStableDollarToken() internal view returns (IStableToken) { + // return getStableToken(); + // } + + // function getStableEuroToken() internal view returns (IStableToken) { + // return IStableToken(registryContract.getAddressForOrDie(STABLE_EURO_TOKEN_REGISTRY_ID)); + // } + + // function getStableRealToken() internal view returns (IStableToken) { + // return IStableToken(registryContract.getAddressForOrDie(STABLE_REAL_TOKEN_REGISTRY_ID)); + // } + + function getValidators() internal view returns (IValidators) { + return IValidators(registryContract.getAddressForOrDie(VALIDATORS_REGISTRY_ID)); + } + + function getCeloUnreleasedTreasury() internal view returns (ICeloUnreleasedTreasury) { + return + ICeloUnreleasedTreasury( + registryContract.getAddressForOrDie(CELO_UNRELEASED_TREASURY_REGISTRY_ID) + ); + } + + function getEpochRewards() internal view returns (IEpochRewards) { + return IEpochRewards(registryContract.getAddressForOrDie(EPOCH_REWARDS_REGISTRY_ID)); + } + + function getEpochManager() internal view returns (IEpochManager) { + return IEpochManager(registryContract.getAddressForOrDie(EPOCH_MANAGER_REGISTRY_ID)); + } +} diff --git a/packages/protocol/test-sol/devchain/e2e/common/EpochManager.t.sol b/packages/protocol/test-sol/devchain/e2e/common/EpochManager.t.sol index 6283865af02..02fbb11ebf4 100644 --- a/packages/protocol/test-sol/devchain/e2e/common/EpochManager.t.sol +++ b/packages/protocol/test-sol/devchain/e2e/common/EpochManager.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.7 <0.8.20; -import "celo-foundry-8/Test.sol"; +// import "celo-foundry-8/Test.sol"; import { Devchain } from "@test-sol/devchain/e2e/utils.sol"; -import { Utils08 } from "@test-sol/utils08.sol"; +// import { Utils08 } from "@test-sol/utils08.sol"; import { IEpochManager } from "@celo-contracts/common/interfaces/IEpochManager.sol"; @@ -12,7 +12,7 @@ import "@test-sol/utils/ECDSAHelper08.sol"; import "@openzeppelin/contracts8/utils/structs/EnumerableSet.sol"; import { console } from "forge-std/console.sol"; -contract E2E_EpochManager is Test, Devchain, Utils08, ECDSAHelper08 { +contract E2E_EpochManager is Devchain, ECDSAHelper08 { using EnumerableSet for EnumerableSet.AddressSet; struct VoterWithPK { diff --git a/packages/protocol/test-sol/devchain/e2e/common/FeeCurrencyDirectory.t.sol b/packages/protocol/test-sol/devchain/e2e/common/FeeCurrencyDirectory.t.sol index f613eb2574a..bebf0ed4f44 100644 --- a/packages/protocol/test-sol/devchain/e2e/common/FeeCurrencyDirectory.t.sol +++ b/packages/protocol/test-sol/devchain/e2e/common/FeeCurrencyDirectory.t.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.7 <0.8.20; -import "celo-foundry-8/Test.sol"; +// import "celo-foundry-8/Test.sol"; import { Devchain } from "@test-sol/devchain/e2e/utils.sol"; import "@celo-contracts-8/common/FeeCurrencyDirectory.sol"; -contract E2EDemo is Test, Devchain { +contract E2EDemo is Devchain { function test_ShouldAllowOwnerSetCurrencyConfig() public { address token = address(1); uint256 intrinsicGas = 21000; diff --git a/packages/protocol/test-sol/devchain/e2e/utils.sol b/packages/protocol/test-sol/devchain/e2e/utils.sol index 0e84cfafa26..0c6798dbcb4 100644 --- a/packages/protocol/test-sol/devchain/e2e/utils.sol +++ b/packages/protocol/test-sol/devchain/e2e/utils.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.7 <0.8.20; -import "@celo-contracts-8/common/UsingRegistry.sol"; +// import "@celo-contracts-8/common/UsingRegistry2.sol"; import "@celo-contracts/common/interfaces/IRegistry.sol"; import { IEpochManager } from "@celo-contracts/common/interfaces/IEpochManager.sol"; import { IAccounts } from "@celo-contracts/common/interfaces/IAccounts.sol"; @@ -15,9 +15,10 @@ import "@celo-contracts-8/common/FeeCurrencyDirectory.sol"; import "@celo-contracts/stability/interfaces/ISortedOracles.sol"; import "@celo-contracts/common/interfaces/ICeloUnreleasedTreasury.sol"; -import { TestConstants } from "@test-sol/constants.sol"; +// import { TestConstants } from "@test-sol/constants.sol"; +import "@test-sol/utils08.sol"; -contract Devchain is UsingRegistry, TestConstants { +contract Devchain is Utils08 { // Used in exceptional circumstances when a contract is not in UsingRegistry.sol IRegistry devchainRegistry = IRegistry(REGISTRY_ADDRESS); diff --git a/packages/protocol/test-sol/devchain/migration/IntegrationValidators.t.sol b/packages/protocol/test-sol/devchain/migration/IntegrationValidators.t.sol index 2ba650dffe7..24f89201956 100644 --- a/packages/protocol/test-sol/devchain/migration/IntegrationValidators.t.sol +++ b/packages/protocol/test-sol/devchain/migration/IntegrationValidators.t.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.7 <0.8.20; -import "celo-foundry-8/Test.sol"; +// import "celo-foundry-8/Test.sol"; import { Devchain } from "@test-sol/devchain/e2e/utils.sol"; -contract IntegrationsValidators is Test, Devchain { +contract IntegrationsValidators is Devchain { function test_deaffiliateWorskWithEpochManager() public { vm.prank(election.electValidatorAccounts()[0]); validators.deaffiliate(); diff --git a/packages/protocol/test-sol/devchain/migration/Migration.t.sol b/packages/protocol/test-sol/devchain/migration/Migration.t.sol index bfe56896280..9caa8da42d5 100644 --- a/packages/protocol/test-sol/devchain/migration/Migration.t.sol +++ b/packages/protocol/test-sol/devchain/migration/Migration.t.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0 <0.8.20; -import "celo-foundry-8/Test.sol"; +// import "celo-foundry-8/Test.sol"; -import { Utils08 } from "@test-sol/utils08.sol"; -import { TestConstants } from "@test-sol/constants.sol"; +// import { Utils08 } from "@test-sol/utils08.sol"; +// import { TestConstants } from "@test-sol/constants.sol"; import { MigrationsConstants } from "@migrations-sol/constants.sol"; import { FeeCurrencyDirectory } from "@celo-contracts-8/common/FeeCurrencyDirectory.sol"; diff --git a/packages/protocol/test-sol/unit/common/EpochManager.t.sol b/packages/protocol/test-sol/unit/common/EpochManager.t.sol index bebd3999b10..2a9083bb553 100644 --- a/packages/protocol/test-sol/unit/common/EpochManager.t.sol +++ b/packages/protocol/test-sol/unit/common/EpochManager.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.7 <0.8.20; -import "celo-foundry-8/Test.sol"; +// import "celo-foundry-8/Test.sol"; import "@celo-contracts-8/common/mocks/EpochManager_WithMocks.sol"; import "@celo-contracts-8/stability/test/MockStableToken.sol"; import "@celo-contracts-8/common/test/MockCeloToken.sol"; @@ -9,7 +9,7 @@ import "@celo-contracts/common/interfaces/ICeloToken.sol"; import "@celo-contracts-8/common/ScoreManager.sol"; import { ICeloUnreleasedTreasury } from "@celo-contracts/common/interfaces/ICeloUnreleasedTreasury.sol"; -import { TestConstants } from "@test-sol/constants.sol"; +// import { TestConstants } from "@test-sol/constants.sol"; import { Utils08 } from "@test-sol/utils08.sol"; import "@celo-contracts/stability/test/MockSortedOracles.sol"; @@ -26,7 +26,7 @@ import { ValidatorsMock } from "@test-sol/unit/governance/validators/mocks/Valid import { MockCeloUnreleasedTreasury } from "@celo-contracts-8/common/test/MockCeloUnreleasedTreasury.sol"; import { console } from "forge-std/console.sol"; -contract EpochManagerTest is Test, TestConstants, Utils08 { +contract EpochManagerTest is Utils08 { EpochManager_WithMocks epochManager; MockSortedOracles sortedOracles; diff --git a/packages/protocol/test-sol/unit/common/EpochManagerEnabler.t.sol b/packages/protocol/test-sol/unit/common/EpochManagerEnabler.t.sol index 3e91fc2e121..320598d9618 100644 --- a/packages/protocol/test-sol/unit/common/EpochManagerEnabler.t.sol +++ b/packages/protocol/test-sol/unit/common/EpochManagerEnabler.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0 <0.8.20; -import "celo-foundry-8/Test.sol"; +// import "celo-foundry-8/Test.sol"; import "@celo-contracts-8/common/EpochManager.sol"; import { EpochManagerEnablerMock } from "@test-sol/mocks/EpochManagerEnablerMock.sol"; @@ -10,7 +10,7 @@ import { CeloUnreleasedTreasury } from "@celo-contracts-8/common/CeloUnreleasedT import { ICeloUnreleasedTreasury } from "@celo-contracts/common/interfaces/ICeloUnreleasedTreasury.sol"; import { IAccounts } from "@celo-contracts/common/interfaces/IAccounts.sol"; -import { TestConstants } from "@test-sol/constants.sol"; +// import { TestConstants } from "@test-sol/constants.sol"; import { Utils08 } from "@test-sol/utils08.sol"; import "@celo-contracts/common/interfaces/IRegistry.sol"; @@ -20,7 +20,7 @@ import { ValidatorsMock } from "@test-sol/unit/governance/validators/mocks/Valid import { MockCeloUnreleasedTreasury } from "@celo-contracts-8/common/test/MockCeloUnreleasedTreasury.sol"; import "@celo-contracts-8/common/test/MockCeloToken.sol"; -contract EpochManagerEnablerTest is Test, TestConstants, Utils08 { +contract EpochManagerEnablerTest is Utils08 { EpochManager epochManager; EpochManagerEnablerMock epochManagerEnabler; MockCeloUnreleasedTreasury celoUnreleasedTreasury; diff --git a/packages/protocol/test-sol/unit/common/FeeCurrencyDirectory.t.sol b/packages/protocol/test-sol/unit/common/FeeCurrencyDirectory.t.sol index fd4161cfba5..0cd6b598bce 100644 --- a/packages/protocol/test-sol/unit/common/FeeCurrencyDirectory.t.sol +++ b/packages/protocol/test-sol/unit/common/FeeCurrencyDirectory.t.sol @@ -1,17 +1,20 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.7 <0.8.20; -import "celo-foundry-8/Test.sol"; +import { Utils08 } from "@test-sol/utils08.sol"; +import "@test-sol/utils/WhenL2-08.sol"; + import "@celo-contracts-8/common/FeeCurrencyDirectory.sol"; import "@celo-contracts-8/common/mocks/MockOracle.sol"; -contract FeeCurrencyDirectoryTestBase is Test { +contract FeeCurrencyDirectoryTest is Utils08 { FeeCurrencyDirectory directory; MockOracle oracle; address nonOwner; address owner; function setUp() public virtual { + super.setUp(); owner = address(this); nonOwner = actor("nonOwner"); oracle = new MockOracle(); @@ -21,7 +24,9 @@ contract FeeCurrencyDirectoryTestBase is Test { } } -contract TestSetCurrencyConfig is FeeCurrencyDirectoryTestBase { +contract FeeCurrencyDirectoryTest_L2 is FeeCurrencyDirectoryTest, WhenL2 {} + +contract TestSetCurrencyConfig is FeeCurrencyDirectoryTest { function test_ShouldAllowOwnerSetCurrencyConfig() public { address token = address(1); uint256 intrinsicGas = 21000; @@ -63,7 +68,7 @@ contract TestSetCurrencyConfig is FeeCurrencyDirectoryTestBase { } } -contract TestRemoveCurrencies is FeeCurrencyDirectoryTestBase { +contract TestRemoveCurrencies is FeeCurrencyDirectoryTest { function setUp() public override { super.setUp(); address token = address(4); @@ -99,7 +104,7 @@ contract TestRemoveCurrencies is FeeCurrencyDirectoryTestBase { } } -contract TestGetExchangeRate is FeeCurrencyDirectoryTestBase { +contract TestGetExchangeRate is FeeCurrencyDirectoryTest { address token; function setUp() public override { diff --git a/packages/protocol/test-sol/unit/common/ProxyFactory08.t.sol b/packages/protocol/test-sol/unit/common/ProxyFactory08.t.sol index c290e570b67..bab9e029569 100644 --- a/packages/protocol/test-sol/unit/common/ProxyFactory08.t.sol +++ b/packages/protocol/test-sol/unit/common/ProxyFactory08.t.sol @@ -1,12 +1,12 @@ pragma solidity ^0.8.15; -import "celo-foundry-8/Test.sol"; +// import "celo-foundry-8/Test.sol"; import "@celo-contracts-8/common/ProxyFactory08.sol"; import "@celo-contracts/common/interfaces/IProxy.sol"; import { Utils08 } from "@test-sol/utils08.sol"; -contract ProxyFactoryTest is Test, Utils08 { +contract ProxyFactoryTest is Utils08 { ProxyFactory08 proxyFactory08; bytes proxyInitCode; address constant owner = address(0xAA963FC97281d9632d96700aB62A4D1340F9a28a); diff --git a/packages/protocol/test-sol/utils/WhenL2-08.sol b/packages/protocol/test-sol/utils/WhenL2-08.sol new file mode 100644 index 00000000000..ec8af5f5e5f --- /dev/null +++ b/packages/protocol/test-sol/utils/WhenL2-08.sol @@ -0,0 +1,11 @@ +pragma solidity >=0.5.13 <0.9.0; +pragma experimental ABIEncoderV2; + +import "@test-sol/utils08.sol"; + +contract WhenL2 is Utils08 { + function setUp() public { + super.setUp(); + whenL2WithEpochManagerInitialization(); + } +} diff --git a/packages/protocol/test-sol/utils08.sol b/packages/protocol/test-sol/utils08.sol index c9495b72a23..7f633642b87 100644 --- a/packages/protocol/test-sol/utils08.sol +++ b/packages/protocol/test-sol/utils08.sol @@ -3,9 +3,33 @@ pragma solidity >=0.5.13 <0.9.0; import "celo-foundry-8/Test.sol"; import { TestConstants } from "@test-sol/constants.sol"; -contract Utils08 is TestConstants { +// import "@celo-contracts-8/common/EpochManager.sol"; +import "@test-sol/unit/common/mocks/MockEpochManager.sol"; +import "@celo-contracts/common/interfaces/IRegistry.sol"; +import "@celo-contracts-8/common/IsL2Check.sol"; +import "@celo-contracts-8/common/PrecompilesOverrideV2.sol"; + +contract Utils08 is Test, TestConstants, IsL2Check, PrecompilesOverrideV2 { + IRegistry registry; + MockEpochManager public epochManager; uint256 public constant secondsInOneBlock = 5; + function setUp() public { + setupRegistry(); + setupEpochManager(); + } + + function setupRegistry() public { + deployCodeTo("Registry.sol", abi.encode(false), REGISTRY_ADDRESS); + registry = IRegistry(REGISTRY_ADDRESS); + } + + function setupEpochManager() public { + epochManager = new MockEpochManager(); + + registry.setAddressFor(EpochManagerContract, address(epochManager)); + } + function timeTravel(Vm vm, uint256 timeDelta) public { vm.warp(block.timestamp + timeDelta); } @@ -29,7 +53,16 @@ contract Utils08 is TestConstants { timeTravel(vm, n * DAY); } - function whenL2(Vm vm) public { + function travelNEpoch(Vm vm, uint256 n) public { + if (isL2()) { + travelNL2Epoch(vm, n); + } else { + // blockTravel((n * ph.epochSize()) + 1); + travelEpochL1(vm); + } + } + + function whenL2() public { vm.etch(0x4200000000000000000000000000000000000018, abi.encodePacked(bytes1(0x01))); } @@ -44,4 +77,18 @@ contract Utils08 is TestConstants { function compareStrings(string memory a, string memory b) public pure returns (bool) { return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b)))); } + + function whenL2WithEpochManagerInitialization() internal { + uint256 l1EpochNumber = getEpochNumber(); + address epochManagerEnabler = actor("EpochManagerEnabler"); + registry.setAddressFor(EpochManagerContract, address(epochManager)); + + address[] memory _elected = new address[](2); + _elected[0] = actor("validator"); + _elected[1] = actor("otherValidator"); + + whenL2(); + vm.prank(epochManagerEnabler); + epochManager.initializeSystem(l1EpochNumber, block.number, _elected); + } }