diff --git a/packages/protocol/contracts-0.8/common/CeloUnreleasedTreasury.sol b/packages/protocol/contracts-0.8/common/CeloUnreleasedTreasury.sol index 38889d88c32..b5ab2252a7e 100644 --- a/packages/protocol/contracts-0.8/common/CeloUnreleasedTreasury.sol +++ b/packages/protocol/contracts-0.8/common/CeloUnreleasedTreasury.sol @@ -5,17 +5,32 @@ import "@openzeppelin/contracts8/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts8/utils/math/Math.sol"; import "./UsingRegistry.sol"; -import "../common/IsL2Check.sol"; import "../../contracts/common/Initializable.sol"; import "./interfaces/ICeloUnreleasedTreasuryInitializer.sol"; /** * @title Contract for unreleased Celo tokens. + * @notice This contract is not allowed to receive transfers of CELO, + * to avoid miscalculating the epoch rewards and to prevent any malicious actor + * from routing stolen fund through the epoch reward distribution. */ -contract CeloUnreleasedTreasury is UsingRegistry, ReentrancyGuard, Initializable, IsL2Check { +contract CeloUnreleasedTreasury is + ICeloUnreleasedTreasuryInitializer, + UsingRegistry, + ReentrancyGuard, + Initializable +{ + bool internal hasAlreadyReleased; + + // Remaining epoch rewards to distribute. + uint256 internal remainingBalanceToRelease; + event Released(address indexed to, uint256 amount); + /** + * @notice Only allows EpochManager to call. + */ modifier onlyEpochManager() { require( msg.sender == registry.getAddressForOrDie(EPOCH_MANAGER_REGISTRY_ID), @@ -28,12 +43,11 @@ contract CeloUnreleasedTreasury is UsingRegistry, ReentrancyGuard, Initializable * @notice Sets initialized == true on implementation contracts * @param test Set to true to skip implementation initialization */ - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice A constructor for initialising a new instance of a CeloUnreleasedTreasury contract. * @param registryAddress The address of the registry core smart contract. - */ function initialize(address registryAddress) external initializer { _transferOwnership(msg.sender); @@ -46,11 +60,31 @@ contract CeloUnreleasedTreasury is UsingRegistry, ReentrancyGuard, Initializable * @param amount The amount to release. */ function release(address to, uint256 amount) external onlyEpochManager { - require(address(this).balance >= amount, "Insufficient balance."); + if (!hasAlreadyReleased) { + remainingBalanceToRelease = address(this).balance; + hasAlreadyReleased = true; + } + + require(remainingBalanceToRelease >= amount, "Insufficient balance."); + remainingBalanceToRelease -= amount; require(getCeloToken().transfer(to, amount), "CELO transfer failed."); + emit Released(to, amount); } + /** + * @notice Returns the remaining balance this contract has left to release. + * @dev This uses internal accounting of the released balance, + * to avoid recounting CELO that was transferred back to this contract. + */ + function getRemainingBalanceToRelease() external view returns (uint256) { + if (!hasAlreadyReleased) { + return address(this).balance; + } else { + return remainingBalanceToRelease; + } + } + /** * @notice Returns the storage, major, minor, and patch version of the contract. * @return Storage version of the contract. diff --git a/packages/protocol/contracts-0.8/common/EpochManager.sol b/packages/protocol/contracts-0.8/common/EpochManager.sol index 966540c90d3..e467588a033 100644 --- a/packages/protocol/contracts-0.8/common/EpochManager.sol +++ b/packages/protocol/contracts-0.8/common/EpochManager.sol @@ -14,6 +14,12 @@ import "../../contracts/common/interfaces/IEpochManager.sol"; import "../../contracts/common/interfaces/ICeloVersionedContract.sol"; import "./interfaces/IEpochManagerInitializer.sol"; +/** + * @title Contract used for managing CELO L2 epoch and elections. + * @dev DESIGN_DESICION: we assume that the first epoch on the L2 starts as soon as the system is initialized + * to minimize amount of "limbo blocks" the network should stop relatively close to an epoch number (but with enough time) + * to have time to call the function `EpochInitializer.migrateEpochAndValidators()` + */ contract EpochManager is Initializable, UsingRegistry, @@ -105,6 +111,9 @@ contract EpochManager is uint256 delegatedPayment ); + /** + * @notice Throws if called by other than EpochManagerEnabler contract. + */ modifier onlyEpochManagerEnabler() { require( msg.sender == registry.getAddressForOrDie(EPOCH_MANAGER_ENABLER_REGISTRY_ID), @@ -113,6 +122,9 @@ contract EpochManager is _; } + /** + * @notice Throws if called when EpochManager system has not yet been initalized. + */ modifier onlySystemAlreadyInitialized() { require(systemAlreadyInitialized(), "Epoch system not initialized"); _; @@ -122,7 +134,7 @@ contract EpochManager is * @notice Sets initialized == true on implementation contracts * @param test Set to true to skip implementation initialization */ - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice Used in place of the constructor to allow the contract to be upgradable via proxy. @@ -136,10 +148,6 @@ contract EpochManager is setOracleAddress(registry.getAddressForOrDie(SORTED_ORACLES_REGISTRY_ID)); } - // DESIGNDESICION(XXX): we assume that the first epoch on the L2 starts as soon as the system is initialized - // to minimize amount of "limbo blocks" the network should stop relatively close to an epoch number (but with enough time) - // to have time to call the function EpochInitializer.migrateEpochAndValidators() - /** * @notice Initializes the EpochManager system, allowing it to start processing epoch * and distributing the epoch rewards. @@ -398,7 +406,11 @@ contract EpochManager is } /** - * @notice Returns the epoch info of the specified epoch, for current epoch. + * @notice Returns the epoch info for the current epoch. + * @return firstEpoch The first block of the current epoch. + * @return lastBlock The last block of the current epoch. + * @return startTimestamp The starting timestamp of the current epoch. + * @return rewardsBlock The reward block of the current epoch. */ function getCurrentEpoch() external diff --git a/packages/protocol/contracts-0.8/common/EpochManagerEnabler.sol b/packages/protocol/contracts-0.8/common/EpochManagerEnabler.sol index 8069d13a6f7..cd15299f441 100644 --- a/packages/protocol/contracts-0.8/common/EpochManagerEnabler.sol +++ b/packages/protocol/contracts-0.8/common/EpochManagerEnabler.sol @@ -10,6 +10,9 @@ import "../../contracts/governance/interfaces/IEpochRewards.sol"; import "../../contracts/common/interfaces/IEpochManagerEnabler.sol"; import "./interfaces/IEpochManagerEnablerInitializer.sol"; +/** + * @title Contract Used to initialize the EpochManager system after L2 transition. + */ contract EpochManagerEnabler is Initializable, UsingRegistry, @@ -29,7 +32,7 @@ contract EpochManagerEnabler is * @notice Sets initialized == true on implementation contracts * @param test Set to true to skip implementation initialization */ - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice Used in place of the constructor to allow the contract to be upgradable via proxy. @@ -66,7 +69,6 @@ contract EpochManagerEnabler is _setFirstBlockOfEpoch(); for (uint256 i = 0; i < numberElectedValidators; i++) { - // TODO: document how much gas this takes for 110 signers address validatorAccountAddress = getAccounts().validatorSignerToAccount( validatorSignerAddressFromCurrentSet(i) ); @@ -93,6 +95,10 @@ contract EpochManagerEnabler is return (1, 1, 0, 0); } + /** + * @notice Sets the first block of the current epoch. + * @dev Only callable on L1. + */ function _setFirstBlockOfEpoch() internal onlyL1 { uint256 blocksSinceEpochBlock = block.number % getEpochSize(); uint256 epochBlock = block.number - blocksSinceEpochBlock; diff --git a/packages/protocol/contracts-0.8/common/FeeCurrencyDirectory.sol b/packages/protocol/contracts-0.8/common/FeeCurrencyDirectory.sol index 9fe5d392c48..68a1638d774 100644 --- a/packages/protocol/contracts-0.8/common/FeeCurrencyDirectory.sol +++ b/packages/protocol/contracts-0.8/common/FeeCurrencyDirectory.sol @@ -16,7 +16,7 @@ contract FeeCurrencyDirectory is mapping(address => CurrencyConfig) public currencies; address[] private currencyList; - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice Initializes the contract with the owner set. diff --git a/packages/protocol/contracts-0.8/common/GasPriceMinimum.sol b/packages/protocol/contracts-0.8/common/GasPriceMinimum.sol index 05d3551a971..4a30ce92d3d 100644 --- a/packages/protocol/contracts-0.8/common/GasPriceMinimum.sol +++ b/packages/protocol/contracts-0.8/common/GasPriceMinimum.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.7 <0.8.20; import "@openzeppelin/contracts8/access/Ownable.sol"; @@ -23,20 +23,19 @@ contract GasPriceMinimum is IsL2Check, CalledByVm { - // TODO add IGasPriceMinimum using FixidityLib for FixidityLib.Fraction; - uint256 public deprecated_gasPriceMinimum; - uint256 public gasPriceMinimumFloor; + uint256 private deprecated_gasPriceMinimum; + uint256 private deprecated_gasPriceMinimumFloor; // Block congestion level targeted by the gas price minimum calculation. - FixidityLib.Fraction public targetDensity; + FixidityLib.Fraction private deprecated_targetDensity; // Speed of gas price minimum adjustment due to congestion. - FixidityLib.Fraction public adjustmentSpeed; + FixidityLib.Fraction private deprecated_adjustmentSpeed; - uint256 public baseFeeOpCodeActivationBlock; - uint256 public constant ABSOLUTE_MINIMAL_GAS_PRICE = 1; + uint256 private deprecated_baseFeeOpCodeActivationBlock; + uint256 private constant ABSOLUTE_MINIMAL_GAS_PRICE = 1; event TargetDensitySet(uint256 targetDensity); event GasPriceMinimumFloorSet(uint256 gasPriceMinimumFloor); @@ -48,7 +47,7 @@ contract GasPriceMinimum is * @notice Sets initialized == true on implementation contracts * @param test Set to true to skip implementation initialization */ - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice Used in place of the constructor to allow the contract to be upgradable via proxy. @@ -112,7 +111,7 @@ contract GasPriceMinimum is * @param tokenAddress The currency the gas price should be in (defaults to Celo). * @return current gas price minimum in the requested currency */ - function getGasPriceMinimum(address tokenAddress) external view returns (uint256) { + function getGasPriceMinimum(address tokenAddress) external view onlyL1 returns (uint256) { return Math.max(_getGasPriceMinimum(tokenAddress), ABSOLUTE_MINIMAL_GAS_PRICE); } /** @@ -123,7 +122,7 @@ contract GasPriceMinimum is * @return Patch version of the contract. */ function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) { - return (1, 2, 0, 2); + return (1, 2, 1, 0); } /** @@ -132,8 +131,11 @@ contract GasPriceMinimum is * @dev Value is expected to be < 1. */ function setAdjustmentSpeed(uint256 _adjustmentSpeed) public onlyOwner onlyL1 { - adjustmentSpeed = FixidityLib.wrap(_adjustmentSpeed); - require(adjustmentSpeed.lt(FixidityLib.fixed1()), "adjustment speed must be smaller than 1"); + deprecated_adjustmentSpeed = FixidityLib.wrap(_adjustmentSpeed); + require( + deprecated_adjustmentSpeed.lt(FixidityLib.fixed1()), + "adjustment speed must be smaller than 1" + ); emit AdjustmentSpeedSet(_adjustmentSpeed); } @@ -143,8 +145,11 @@ contract GasPriceMinimum is * @dev Value is expected to be < 1. */ function setTargetDensity(uint256 _targetDensity) public onlyOwner onlyL1 { - targetDensity = FixidityLib.wrap(_targetDensity); - require(targetDensity.lt(FixidityLib.fixed1()), "target density must be smaller than 1"); + deprecated_targetDensity = FixidityLib.wrap(_targetDensity); + require( + deprecated_targetDensity.lt(FixidityLib.fixed1()), + "target density must be smaller than 1" + ); emit TargetDensitySet(_targetDensity); } @@ -155,12 +160,19 @@ contract GasPriceMinimum is */ function setGasPriceMinimumFloor(uint256 _gasPriceMinimumFloor) public onlyOwner onlyL1 { require(_gasPriceMinimumFloor > 0, "gas price minimum floor must be greater than zero"); - gasPriceMinimumFloor = _gasPriceMinimumFloor; + deprecated_gasPriceMinimumFloor = _gasPriceMinimumFloor; emit GasPriceMinimumFloorSet(_gasPriceMinimumFloor); } - function gasPriceMinimum() public view returns (uint256) { - if (baseFeeOpCodeActivationBlock > 0 && block.number >= baseFeeOpCodeActivationBlock) { + /** + * @notice Returns the gas price minimum. + * @return The gas price minimum. + */ + function gasPriceMinimum() public view onlyL1 returns (uint256) { + if ( + deprecated_baseFeeOpCodeActivationBlock > 0 && + block.number >= deprecated_baseFeeOpCodeActivationBlock + ) { return block.basefee; } else { return deprecated_gasPriceMinimum; @@ -179,25 +191,60 @@ contract GasPriceMinimum is function getUpdatedGasPriceMinimum( uint256 blockGasTotal, uint256 blockGasLimit - ) public view returns (uint256) { + ) public view onlyL1 returns (uint256) { FixidityLib.Fraction memory blockDensity = FixidityLib.newFixedFraction( blockGasTotal, blockGasLimit ); - bool densityGreaterThanTarget = blockDensity.gt(targetDensity); + bool densityGreaterThanTarget = blockDensity.gt(deprecated_targetDensity); FixidityLib.Fraction memory densityDelta = densityGreaterThanTarget - ? blockDensity.subtract(targetDensity) - : targetDensity.subtract(blockDensity); + ? blockDensity.subtract(deprecated_targetDensity) + : deprecated_targetDensity.subtract(blockDensity); FixidityLib.Fraction memory adjustment = densityGreaterThanTarget - ? FixidityLib.fixed1().add(adjustmentSpeed.multiply(densityDelta)) - : FixidityLib.fixed1().subtract(adjustmentSpeed.multiply(densityDelta)); + ? FixidityLib.fixed1().add(deprecated_adjustmentSpeed.multiply(densityDelta)) + : FixidityLib.fixed1().subtract(deprecated_adjustmentSpeed.multiply(densityDelta)); uint256 newGasPriceMinimum = adjustment .multiply(FixidityLib.newFixed(gasPriceMinimum())) .add(FixidityLib.fixed1()) .fromFixed(); - return newGasPriceMinimum >= gasPriceMinimumFloor ? newGasPriceMinimum : gasPriceMinimumFloor; + return + newGasPriceMinimum >= deprecated_gasPriceMinimumFloor + ? newGasPriceMinimum + : deprecated_gasPriceMinimumFloor; + } + + /** + * @notice Returns the gas price minimum floor. + * @return The gas price minimum floor. + */ + function gasPriceMinimumFloor() external view onlyL1 returns (uint256) { + return deprecated_gasPriceMinimumFloor; + } + + /** + * @notice Returns the target density. + * @return The target density. + */ + function targetDensity() external view onlyL1 returns (uint256) { + return deprecated_targetDensity.unwrap(); + } + + /** + * @notice Returns the adjustment speed. + * @return The adjustment speed. + */ + function adjustmentSpeed() external view onlyL1 returns (uint256) { + return deprecated_adjustmentSpeed.unwrap(); + } + + /** + * @notice Returns the basefee opcode activation block. + * @return The basefee opcode activation block. + */ + function baseFeeOpCodeActivationBlock() external view onlyL1 returns (uint256) { + return deprecated_baseFeeOpCodeActivationBlock; } /** @@ -213,7 +260,7 @@ contract GasPriceMinimum is allowZero || _baseFeeOpCodeActivationBlock > 0, "baseFee opCode activation block must be greater than zero" ); - baseFeeOpCodeActivationBlock = _baseFeeOpCodeActivationBlock; + deprecated_baseFeeOpCodeActivationBlock = _baseFeeOpCodeActivationBlock; emit BaseFeeOpCodeActivationBlockSet(_baseFeeOpCodeActivationBlock); } diff --git a/packages/protocol/contracts-0.8/common/IsL2Check.sol b/packages/protocol/contracts-0.8/common/IsL2Check.sol index 2ca68460b8b..1ed706c08f5 100644 --- a/packages/protocol/contracts-0.8/common/IsL2Check.sol +++ b/packages/protocol/contracts-0.8/common/IsL2Check.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.5.13 <0.8.20; /** @@ -6,11 +7,17 @@ pragma solidity >=0.5.13 <0.8.20; contract IsL2Check { address constant proxyAdminAddress = 0x4200000000000000000000000000000000000018; + /** + * @notice Throws if called on L2. + */ modifier onlyL1() { allowOnlyL1(); _; } + /** + * @notice Throws if called on L1. + */ modifier onlyL2() { if (!isL2()) { revert("This method is not supported in L1."); @@ -18,6 +25,10 @@ contract IsL2Check { _; } + /** + * @notice Checks to see if current network is Celo L2. + * @return Whether or not the current network is a Celo L2. + */ function isL2() internal view returns (bool) { uint32 size; address _addr = proxyAdminAddress; @@ -27,6 +38,10 @@ contract IsL2Check { return (size > 0); } + /** + * @notice Used to restrict usage of the parent function to L1 execution. + * @dev Reverts if called on a Celo L2 network. + */ function allowOnlyL1() internal view { if (isL2()) { revert("This method is no longer supported in L2."); diff --git a/packages/protocol/contracts-0.8/common/MentoFeeCurrencyAdapter.sol b/packages/protocol/contracts-0.8/common/MentoFeeCurrencyAdapter.sol index 47f29504417..fa76f743478 100644 --- a/packages/protocol/contracts-0.8/common/MentoFeeCurrencyAdapter.sol +++ b/packages/protocol/contracts-0.8/common/MentoFeeCurrencyAdapter.sol @@ -14,7 +14,7 @@ contract MentoFeeCurrencyAdapter is IOracle, Initializable, Ownable { mapping(address => MentoCurrencyConfig) public currencies; address[] private currencyList; - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice Initializes the contract with the owner set. diff --git a/packages/protocol/contracts-0.8/common/PrecompilesOverride.sol b/packages/protocol/contracts-0.8/common/PrecompilesOverride.sol index 058b947e86d..5fe623d8b0a 100644 --- a/packages/protocol/contracts-0.8/common/PrecompilesOverride.sol +++ b/packages/protocol/contracts-0.8/common/PrecompilesOverride.sol @@ -45,7 +45,7 @@ contract PrecompilesOverride is UsingPrecompiles, UsingRegistry { if (isL2()) { return getEpochManager().getElectedSignerByIndex(index); } else { - super.validatorSignerAddressFromCurrentSet(index); + return super.validatorSignerAddressFromCurrentSet(index); } } @@ -54,7 +54,6 @@ contract PrecompilesOverride is UsingPrecompiles, UsingRegistry { * @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); } diff --git a/packages/protocol/contracts-0.8/common/ScoreManager.sol b/packages/protocol/contracts-0.8/common/ScoreManager.sol index 0f491a20ea0..6888a2c433b 100644 --- a/packages/protocol/contracts-0.8/common/ScoreManager.sol +++ b/packages/protocol/contracts-0.8/common/ScoreManager.sol @@ -8,6 +8,12 @@ import "@openzeppelin/contracts8/access/Ownable.sol"; import "../../contracts/common/interfaces/IScoreManagerGovernance.sol"; import "../../contracts/common/interfaces/IScoreManager.sol"; +/** + * @title ScoreManager contract + * @notice This contract updates the score of validators and validator groups on L2. + * This replaces the previous method of calculating scores based on validator uptime + * with a governable score. + */ contract ScoreManager is Initializable, Ownable, @@ -21,7 +27,7 @@ contract ScoreManager is } uint256 private constant FIXED1_UINT = 1e24; - uint256 public constant ZERO_FIXED1_UINT = FIXED1_UINT + 1; + uint256 public constant ZERO_SCORE = FIXED1_UINT + 1; mapping(address => uint256) public groupScores; mapping(address => uint256) public validatorScores; @@ -31,6 +37,9 @@ contract ScoreManager is event ValidatorScoreSet(address indexed validator, uint256 score); event ScoreManagerSetterSet(address indexed scoreManagerSetter); + /** + * @notice Reverts if msg.sender is not authorized to update score. + */ modifier onlyAuthorizedToUpdateScore() { require( msg.sender == owner() || scoreManagerSetter == msg.sender, @@ -43,7 +52,7 @@ contract ScoreManager is * @notice Sets initialized == true on implementation contracts * @param test Set to true to skip implementation initialization */ - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice Used in place of the constructor to allow the contract to be upgradable via proxy. @@ -52,42 +61,59 @@ contract ScoreManager is _transferOwnership(msg.sender); } + /** + * @notice Sets the group score for a specified group. + * @param group The address of the group whose score will be updated. + * @param score The new score of the group to be updated. + * @dev Set value to `ZERO_SCORE` to set score to zero. + */ function setGroupScore(address group, uint256 score) external onlyAuthorizedToUpdateScore { - require( - score <= ZERO_FIXED1_UINT, - "Score must be less than or equal to 1e24 or ZERO_FIXED1_UINT." - ); - groupScores[group] = score; - + groupScores[group] = checkScore(score); emit GroupScoreSet(group, score); } + /** + * @notice Sets the score for a specified validator. + * @param validator The address of the validator whose score will be updated. + * @param score The new score of the validator to be updated. + * @dev Set value to `ZERO_SCORE` to set score to zero. + */ function setValidatorScore( address validator, uint256 score ) external onlyAuthorizedToUpdateScore { - require( - score <= ZERO_FIXED1_UINT, - "Score must be less than or equal to 1e24 or ZERO_FIXED1_UINT." - ); - validatorScores[validator] = score; - + validatorScores[validator] = checkScore(score); emit ValidatorScoreSet(validator, score); } + /** + * @notice Sets the whitelisted address allowed to set validator and group scores. + * @param _scoreManagerSetter Address of whitelisted score setter. + */ function setScoreManagerSetter(address _scoreManagerSetter) external onlyOwner { scoreManagerSetter = _scoreManagerSetter; emit ScoreManagerSetterSet(_scoreManagerSetter); } + /** + * @notice Returns the score of the specified group. + * @param group The address of the group of interest. + */ function getGroupScore(address group) external view returns (uint256) { return getScore(groupScores[group]); } + /** + * @notice Returns the score of the specified validator. + * @param validator The address of the validator of interest. + */ function getValidatorScore(address validator) external view returns (uint256) { return getScore(validatorScores[validator]); } + /** + * @notice Returns the address of the whitelisted score setter. + */ function getScoreManagerSetter() external view returns (address) { return scoreManagerSetter; } @@ -103,12 +129,32 @@ contract ScoreManager is return (1, 1, 0, 0); } + /** + * @notice Returns the actual score based on the input value. + * @param score The value from `validatorScores` or `groupScores` mappings. + * @dev To set the score to 100% by default when the contract is first initialized + * or when new groups or validators are added, the default score of 0 returns 1e24. + * To encode a score value of 0 we use the magic number ZERO_SCORE = (1e24)+1. + */ function getScore(uint256 score) internal pure returns (uint256) { if (score == 0) { return FIXED1_UINT; - } else if (score == ZERO_FIXED1_UINT) { + } else if (score == ZERO_SCORE) { return 0; } return score; } + + /** + * @notice Checks if the score is valid and returns the score. + * @param score The score to be checked. + */ + function checkScore(uint256 score) internal pure returns (uint256) { + if (score == 0) { + return ZERO_SCORE; + } + + require(score <= FIXED1_UINT, "Score must be less than or equal to 1e24."); + return score; + } } diff --git a/packages/protocol/contracts-0.8/common/interfaces/IGasPriceMinimum.sol b/packages/protocol/contracts-0.8/common/interfaces/IGasPriceMinimum.sol index 5443840e3ed..24d89284c42 100644 --- a/packages/protocol/contracts-0.8/common/interfaces/IGasPriceMinimum.sol +++ b/packages/protocol/contracts-0.8/common/interfaces/IGasPriceMinimum.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.5.13 <0.9.0; // TODO add to GasPrice diff --git a/packages/protocol/contracts-0.8/common/interfaces/IGasPriceMinimumInitializer.sol b/packages/protocol/contracts-0.8/common/interfaces/IGasPriceMinimumInitializer.sol index a5e0f2bbac1..046cf9faf98 100644 --- a/packages/protocol/contracts-0.8/common/interfaces/IGasPriceMinimumInitializer.sol +++ b/packages/protocol/contracts-0.8/common/interfaces/IGasPriceMinimumInitializer.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.5.13 <0.9.0; interface IGasPriceMinimumInitializer { diff --git a/packages/protocol/contracts-0.8/common/linkedlists/AddressLinkedList.sol b/packages/protocol/contracts-0.8/common/linkedlists/AddressLinkedList.sol index 10d7988372e..ce0c4e9fa43 100644 --- a/packages/protocol/contracts-0.8/common/linkedlists/AddressLinkedList.sol +++ b/packages/protocol/contracts-0.8/common/linkedlists/AddressLinkedList.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.0 <0.8.20; import "@openzeppelin/contracts8/utils/math/SafeMath.sol"; diff --git a/packages/protocol/contracts-0.8/common/linkedlists/IntegerSortedLinkedList.sol b/packages/protocol/contracts-0.8/common/linkedlists/IntegerSortedLinkedList.sol index 25afaeb8c49..baf51f3c303 100644 --- a/packages/protocol/contracts-0.8/common/linkedlists/IntegerSortedLinkedList.sol +++ b/packages/protocol/contracts-0.8/common/linkedlists/IntegerSortedLinkedList.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.0 <0.8.20; import "@openzeppelin/contracts8/utils/math/SafeMath.sol"; diff --git a/packages/protocol/contracts-0.8/common/linkedlists/LinkedList.sol b/packages/protocol/contracts-0.8/common/linkedlists/LinkedList.sol index a8aef19478a..de386a113ea 100644 --- a/packages/protocol/contracts-0.8/common/linkedlists/LinkedList.sol +++ b/packages/protocol/contracts-0.8/common/linkedlists/LinkedList.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.0 <0.8.20; import "@openzeppelin/contracts8/utils/math/SafeMath.sol"; diff --git a/packages/protocol/contracts-0.8/common/linkedlists/SortedLinkedList.sol b/packages/protocol/contracts-0.8/common/linkedlists/SortedLinkedList.sol index c030435cb3a..4ce7b23b846 100644 --- a/packages/protocol/contracts-0.8/common/linkedlists/SortedLinkedList.sol +++ b/packages/protocol/contracts-0.8/common/linkedlists/SortedLinkedList.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.0 <0.8.20; import "@openzeppelin/contracts8/utils/math/SafeMath.sol"; diff --git a/packages/protocol/contracts-0.8/common/linkedlists/SortedLinkedListWithMedian.sol b/packages/protocol/contracts-0.8/common/linkedlists/SortedLinkedListWithMedian.sol index cded44b9d5d..6093b47466d 100644 --- a/packages/protocol/contracts-0.8/common/linkedlists/SortedLinkedListWithMedian.sol +++ b/packages/protocol/contracts-0.8/common/linkedlists/SortedLinkedListWithMedian.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.0 <0.8.20; import "@openzeppelin/contracts8/utils/math/SafeMath.sol"; diff --git a/packages/protocol/contracts-0.8/common/mocks/MockAccounts.sol b/packages/protocol/contracts-0.8/common/mocks/MockAccounts.sol index 51ead07c279..61a08312b20 100644 --- a/packages/protocol/contracts-0.8/common/mocks/MockAccounts.sol +++ b/packages/protocol/contracts-0.8/common/mocks/MockAccounts.sol @@ -20,7 +20,7 @@ contract MockAccounts { accountToSigner[account] = signer; } - function getValidatorSigner(address account) external returns (address) { + function getValidatorSigner(address account) external view returns (address) { return accountToSigner[account]; } diff --git a/packages/protocol/contracts-0.8/common/test/MockCeloToken.sol b/packages/protocol/contracts-0.8/common/test/MockCeloToken.sol index b412f134a22..0c85c62cf80 100644 --- a/packages/protocol/contracts-0.8/common/test/MockCeloToken.sol +++ b/packages/protocol/contracts-0.8/common/test/MockCeloToken.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.0 <0.9.0; // solhint-disable no-unused-vars diff --git a/packages/protocol/contracts-0.8/common/test/MockCeloUnreleasedTreasury.sol b/packages/protocol/contracts-0.8/common/test/MockCeloUnreleasedTreasury.sol index da5b78af65d..0adbec9dd61 100644 --- a/packages/protocol/contracts-0.8/common/test/MockCeloUnreleasedTreasury.sol +++ b/packages/protocol/contracts-0.8/common/test/MockCeloUnreleasedTreasury.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.0 <0.9.0; // solhint-disable no-unused-vars @@ -8,8 +9,28 @@ import "../UsingRegistry.sol"; * @title A mock CeloUnreleasedTreasury for testing. */ contract MockCeloUnreleasedTreasury is ICeloUnreleasedTreasury, UsingRegistry { + bool internal hasAlreadyReleased; + uint256 internal remainingTreasure; function release(address to, uint256 amount) external { - require(address(this).balance >= amount, "Insufficient balance."); + if (!hasAlreadyReleased) { + remainingTreasure = address(this).balance; + hasAlreadyReleased = true; + } + + require(remainingTreasure >= amount, "Insufficient balance."); require(getCeloToken().transfer(to, amount), "CELO transfer failed."); + remainingTreasure -= amount; + } + + function getRemainingBalanceToRelease() external view returns (uint256) { + remainingTreasure; + } + + function setRemainingTreasure(uint256 _amount) public { + remainingTreasure = _amount; + } + + function setFirstRelease(bool _hasAlreadyReleased) public { + hasAlreadyReleased = _hasAlreadyReleased; } } diff --git a/packages/protocol/contracts-0.8/common/test/MockEpochManager.sol b/packages/protocol/contracts-0.8/common/test/MockEpochManager.sol index 27168f0f2ca..daea1606d2d 100644 --- a/packages/protocol/contracts-0.8/common/test/MockEpochManager.sol +++ b/packages/protocol/contracts-0.8/common/test/MockEpochManager.sol @@ -71,9 +71,9 @@ contract MockEpochManager is IEpochManager { function startNextEpochProcess() external {} function finishNextEpochProcess( - address[] calldata groups, - address[] calldata lessers, - address[] calldata greaters + address[] calldata, + address[] calldata, + address[] calldata ) external { epochs[currentEpochNumber].lastBlock = block.number - 1; @@ -150,7 +150,7 @@ contract MockEpochManager is IEpochManager { } function getEpochByBlockNumber( - uint256 _blockNumber + uint256 ) external view returns (uint256, uint256, uint256, uint256) { return (0, 0, 0, 0); } diff --git a/packages/protocol/contracts-0.8/common/test/MockRegistry.sol b/packages/protocol/contracts-0.8/common/test/MockRegistry.sol index eb42d084be4..7b50f86119d 100644 --- a/packages/protocol/contracts-0.8/common/test/MockRegistry.sol +++ b/packages/protocol/contracts-0.8/common/test/MockRegistry.sol @@ -22,7 +22,7 @@ contract MockRegistry is IRegistry, IRegistryInitializer, Ownable, Initializable * @notice Sets initialized == true on implementation contracts * @param test Set to true to skip implementation initialization */ - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice Used in place of the constructor to allow the contract to be upgradable via proxy. diff --git a/packages/protocol/contracts-0.8/governance/Validators.sol b/packages/protocol/contracts-0.8/governance/Validators.sol index 6d03bb2021a..7a744edf9ee 100644 --- a/packages/protocol/contracts-0.8/governance/Validators.sol +++ b/packages/protocol/contracts-0.8/governance/Validators.sol @@ -172,7 +172,7 @@ contract Validators is * @notice Sets initialized == true on implementation contracts * @param test Set to true to skip implementation initialization */ - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice Used in place of the constructor to allow the contract to be upgradable via proxy. @@ -250,17 +250,13 @@ contract Validators is * @return True upon success. * @dev Fails if the account is already a validator or validator group. * @dev Fails if the account does not have sufficient Locked Gold. + * @dev Fails on L2. Use registerValidatorNoBls instead. */ function registerValidator( bytes calldata ecdsaPublicKey, bytes calldata blsPublicKey, bytes calldata blsPop - ) - external - nonReentrant - onlyL1 // For L2, use registerValidatorNoBls - returns (bool) - { + ) external nonReentrant onlyL1 returns (bool) { address account = getAccounts().validatorSignerToAccount(msg.sender); _isRegistrationAllowed(account); require(!isValidator(account) && !isValidatorGroup(account), "Already registered"); @@ -652,7 +648,7 @@ contract Validators is // to allow `EpochManager` to mint. /** * @notice Allows the EpochManager contract to mint stable token for itself. - * @param amount The amount to be minted. + * @param amount The amount of stableToken to be minted. */ function mintStableToEpochManager( uint256 amount @@ -733,6 +729,12 @@ contract Validators is return topValidators; } + /** + * @notice Retreives the top validator accounts of the specified group. + * @param account The address of the validator group. + * @param n The number of members to return. + * @return The accounts of the top n group members for a particular group. + */ function getTopGroupValidatorsAccounts( address account, uint256 n @@ -1305,7 +1307,7 @@ contract Validators is emit ValidatorScoreUpdated(account, validators[account].score.unwrap(), epochScore.unwrap()); } - function _isRegistrationAllowed(address account) private returns (bool) { + function _isRegistrationAllowed(address account) private { require( !getElection().allowedToVoteOverMaxNumberOfGroups(account), "Cannot vote for more than max number of groups" diff --git a/packages/protocol/contracts-0.8/governance/test/EpochRewardsMock.sol b/packages/protocol/contracts-0.8/governance/test/EpochRewardsMock.sol index e8557b05758..df4e8e592a8 100644 --- a/packages/protocol/contracts-0.8/governance/test/EpochRewardsMock.sol +++ b/packages/protocol/contracts-0.8/governance/test/EpochRewardsMock.sol @@ -21,13 +21,11 @@ contract EpochRewardsMock08 is IEpochRewards { function updateTargetVotingYield() external {} - function getRewardsMultiplier( - uint256 targetGoldTotalSupplyIncrease - ) external view returns (uint256) { + function getRewardsMultiplier(uint256) external pure returns (uint256) { return 0; } - function isReserveLow() external view returns (bool) { + function isReserveLow() external pure returns (bool) { return false; } function calculateTargetEpochRewards() @@ -37,22 +35,22 @@ contract EpochRewardsMock08 is IEpochRewards { { return (perValidatorReward, totalRewardsVoter, totalRewardsCommunity, totalRewardsCarbonFund); } - function getTargetVotingYieldParameters() external view returns (uint256, uint256, uint256) { + function getTargetVotingYieldParameters() external pure returns (uint256, uint256, uint256) { return (0, 0, 0); } - function getRewardsMultiplierParameters() external view returns (uint256, uint256, uint256) { + function getRewardsMultiplierParameters() external pure returns (uint256, uint256, uint256) { return (0, 0, 0); } - function getCommunityRewardFraction() external view returns (uint256) { + function getCommunityRewardFraction() external pure returns (uint256) { return 0; } - function getCarbonOffsettingFraction() external view returns (uint256) { + function getCarbonOffsettingFraction() external pure returns (uint256) { return 0; } - function getTargetVotingGoldFraction() external view returns (uint256) { + function getTargetVotingGoldFraction() external pure returns (uint256) { return 0; } - function getRewardsMultiplier() external view returns (uint256) { + function getRewardsMultiplier() external pure returns (uint256) { return 0; } diff --git a/packages/protocol/contracts-0.8/governance/test/IMockValidators.sol b/packages/protocol/contracts-0.8/governance/test/IMockValidators.sol index 71a27e1a115..9dd67b7857f 100644 --- a/packages/protocol/contracts-0.8/governance/test/IMockValidators.sol +++ b/packages/protocol/contracts-0.8/governance/test/IMockValidators.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.7 <0.8.20; interface IMockValidators { diff --git a/packages/protocol/contracts-0.8/stability/FeeCurrencyAdapter.sol b/packages/protocol/contracts-0.8/stability/FeeCurrencyAdapter.sol index 642d1603579..4db6fbc5d66 100644 --- a/packages/protocol/contracts-0.8/stability/FeeCurrencyAdapter.sol +++ b/packages/protocol/contracts-0.8/stability/FeeCurrencyAdapter.sol @@ -31,7 +31,7 @@ contract FeeCurrencyAdapter is Initializable, CalledByVm, IFeeCurrencyAdapter { * @notice Sets initialized == true on implementation contracts * @param test Set to true to skip implementation initialization */ - constructor(bool test) public Initializable(test) {} + constructor(bool test) Initializable(test) {} /** * @notice Used in place of the constructor to allow the contract to be upgradable via proxy. diff --git a/packages/protocol/contracts-0.8/stability/interfaces/IDecimals.sol b/packages/protocol/contracts-0.8/stability/interfaces/IDecimals.sol index 2b68b9f8060..27d86e9740a 100644 --- a/packages/protocol/contracts-0.8/stability/interfaces/IDecimals.sol +++ b/packages/protocol/contracts-0.8/stability/interfaces/IDecimals.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.13; interface IDecimals { diff --git a/packages/protocol/contracts-0.8/stability/interfaces/IFeeCurrency.sol b/packages/protocol/contracts-0.8/stability/interfaces/IFeeCurrency.sol index e8c800a3c93..7dac6e50932 100644 --- a/packages/protocol/contracts-0.8/stability/interfaces/IFeeCurrency.sol +++ b/packages/protocol/contracts-0.8/stability/interfaces/IFeeCurrency.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.13; import "@openzeppelin/contracts8/token/ERC20/IERC20.sol"; diff --git a/packages/protocol/contracts-0.8/stability/test/MockStableToken.sol b/packages/protocol/contracts-0.8/stability/test/MockStableToken.sol index 26c8e940a23..579abfeec43 100644 --- a/packages/protocol/contracts-0.8/stability/test/MockStableToken.sol +++ b/packages/protocol/contracts-0.8/stability/test/MockStableToken.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.0 <0.9.0; // solhint-disable no-unused-vars @@ -19,7 +20,7 @@ contract MockStableToken08 { // Stored as units. Value can be found using unitsToValue(). mapping(address => uint256) public balances; - constructor() public { + constructor() { setInflationFactor(FixidityLib.fixed1().unwrap()); } diff --git a/packages/protocol/contracts/SolidityPrecompiles.sol b/packages/protocol/contracts/SolidityPrecompiles.sol deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/packages/protocol/contracts/common/Accounts.sol b/packages/protocol/contracts/common/Accounts.sol index a0f505b3ca7..edd7a47624d 100644 --- a/packages/protocol/contracts/common/Accounts.sol +++ b/packages/protocol/contracts/common/Accounts.sol @@ -132,6 +132,9 @@ contract Accounts is _setEip712DomainSeparator(); } + /** + * @notice Sets the EIP712 domain separator for the Celo Accounts abstraction. + */ function setEip712DomainSeparator() external { _setEip712DomainSeparator(); } diff --git a/packages/protocol/contracts/common/Blockable.sol b/packages/protocol/contracts/common/Blockable.sol index 34f0903e7a8..90b0617ea1a 100644 --- a/packages/protocol/contracts/common/Blockable.sol +++ b/packages/protocol/contracts/common/Blockable.sol @@ -15,21 +15,28 @@ contract Blockable is IBlockable { event BlockedBySet(address indexed _blockedBy); - /// @notice Modifier to ensure the function is only executed when the contract is not blocked. - /// @dev Reverts with an error if the contract is blocked. + /** + * @notice Modifier to ensure the function is only executed when the contract is not blocked. + * @dev Reverts with an error if the contract is blocked. + */ modifier onlyWhenNotBlocked() { require(!_isBlocked(), "Contract is blocked from performing this action"); _; } - /// @notice Checks if the contract is currently blocked. - /// @return Returns true if the contract is blocked, otherwise false. - /// @dev The function returns false if no blocking contract has been set. + /** + * @notice Checks if the contract is currently blocked. + * @return Returns true if the contract is blocked, otherwise false. + * @dev The function returns false if no blocking contract has been set. + */ function isBlocked() external view returns (bool) { return _isBlocked(); } - function getBlockedbyContract() public view returns (address blockedBy) { + /** + * @notice Returns the address of the contract imposing the block. + */ + function getBlockedByContract() public view returns (address blockedBy) { bytes32 blockedByPosition = BLOCKEDBY_POSITION; assembly { blockedBy := sload(blockedByPosition) @@ -37,6 +44,10 @@ contract Blockable is IBlockable { return blockedBy; } + /** + * @notice Sets the address of the contract allowed to impose a block. + * @param _blockedBy The address of the contract that will impose a block. + */ function _setBlockedBy(address _blockedBy) internal { bytes32 blockedByPosition = BLOCKEDBY_POSITION; assembly { @@ -46,10 +57,13 @@ contract Blockable is IBlockable { emit BlockedBySet(_blockedBy); } + /** + * @notice Checks if the contract is currently blocked. + */ function _isBlocked() internal view returns (bool) { - if (getBlockedbyContract() == address(0)) { + if (getBlockedByContract() == address(0)) { return false; } - return IBlocker(getBlockedbyContract()).isBlocked(); + return IBlocker(getBlockedByContract()).isBlocked(); } } diff --git a/packages/protocol/contracts/common/FeeCurrencyWhitelist.sol b/packages/protocol/contracts/common/FeeCurrencyWhitelist.sol index b0dc16ef56d..2f2adb88aaa 100644 --- a/packages/protocol/contracts/common/FeeCurrencyWhitelist.sol +++ b/packages/protocol/contracts/common/FeeCurrencyWhitelist.sol @@ -3,10 +3,9 @@ pragma solidity ^0.5.13; import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; import "./interfaces/IFeeCurrencyWhitelist.sol"; - import "../common/Initializable.sol"; - import "../common/interfaces/ICeloVersionedContract.sol"; +import "../../contracts-0.8/common/IsL2Check.sol"; /** * @title Holds a whitelist of the ERC20+ tokens that can be used to pay for gas @@ -16,10 +15,11 @@ contract FeeCurrencyWhitelist is IFeeCurrencyWhitelist, Ownable, Initializable, - ICeloVersionedContract + ICeloVersionedContract, + IsL2Check { // Array of all the tokens enabled - address[] public whitelist; + address[] private deprecated_whitelist; event FeeCurrencyWhitelisted(address token); @@ -42,16 +42,28 @@ contract FeeCurrencyWhitelist is * @dev Add a token to the whitelist * @param tokenAddress The address of the token to add. */ - function addToken(address tokenAddress) external onlyOwner { - whitelist.push(tokenAddress); + function addToken(address tokenAddress) external onlyOwner onlyL1 { + deprecated_whitelist.push(tokenAddress); emit FeeCurrencyWhitelisted(tokenAddress); } /** * @return a list of all tokens enabled as gas fee currency. + * @dev Once Celo becomes an L2, use the FeeCurrencyDirectory contract + * instead. + */ + function getWhitelist() external view onlyL1 returns (address[] memory) { + return deprecated_whitelist; + } + + /** + * @notice Gets the whitelist item at the specified index. + * @return Address of a token in the whitelist. + * @dev Once Celo becomes an L2, use the FeeCurrencyDirectory contract + * instead. */ - function getWhitelist() external view returns (address[] memory) { - return whitelist; + function whitelist(uint256 index) external view onlyL1 returns (address) { + return deprecated_whitelist[index]; } /** @@ -62,7 +74,7 @@ contract FeeCurrencyWhitelist is * @return Patch version of the contract. */ function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) { - return (1, 1, 1, 0); + return (1, 1, 2, 0); } /** @@ -71,11 +83,11 @@ contract FeeCurrencyWhitelist is * @param tokenAddress The address of the token to remove. * @param index The index of the token in the whitelist array. */ - function removeToken(address tokenAddress, uint256 index) public onlyOwner { - require(whitelist[index] == tokenAddress, "Index does not match"); - uint256 length = whitelist.length; - whitelist[index] = whitelist[length - 1]; - whitelist.pop(); + function removeToken(address tokenAddress, uint256 index) public onlyOwner onlyL1 { + require(deprecated_whitelist[index] == tokenAddress, "Index does not match"); + uint256 length = deprecated_whitelist.length; + deprecated_whitelist[index] = deprecated_whitelist[length - 1]; + deprecated_whitelist.pop(); emit FeeCurrencyWhitelistRemoved(tokenAddress); } } diff --git a/packages/protocol/contracts/common/FeeHandler.sol b/packages/protocol/contracts/common/FeeHandler.sol index e3cff9b25cb..35ef8dceeb1 100644 --- a/packages/protocol/contracts/common/FeeHandler.sol +++ b/packages/protocol/contracts/common/FeeHandler.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.5.13; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; @@ -489,7 +490,7 @@ contract FeeHandler is return balanceToBurn; } - function checkTotalBeneficiary() internal { + function checkTotalBeneficiary() internal view { require( getTotalFractionOfOtherBeneficiariesAndCarbonFixidity().lt(FixidityLib.fixed1()), "Total beneficiaries fraction must be less than 1" @@ -664,7 +665,7 @@ contract FeeHandler is FixidityLib.Fraction memory thisTokenFraction, FixidityLib.Fraction memory totalFractionOfOtherBeneficiariesAndCarbonFixidity, uint256 toDistribute - ) private returns (uint256) { + ) private pure returns (uint256) { FixidityLib.Fraction memory proportionOfThisToken = thisTokenFraction.divide( totalFractionOfOtherBeneficiariesAndCarbonFixidity ); @@ -681,9 +682,6 @@ contract FeeHandler is ignoreRenaming_carbonFeeBeneficiary != address(0), "Can't distribute to the zero address" ); - IERC20 token = IERC20(tokenAddress); - uint256 tokenBalance = token.balanceOf(address(this)); - TokenState storage tokenState = tokenStates[tokenAddress]; FixidityLib.Fraction @@ -762,7 +760,6 @@ contract FeeHandler is // new handle // tokenAddresses should not contain the Celo address function _handle(address[] memory tokenAddresses) private { - address celoToken = getCeloTokenAddress(); // Celo doesn't have to be exchanged for anything for (uint256 i = 0; i < tokenAddresses.length; i++) { address token = tokenAddresses[i]; diff --git a/packages/protocol/contracts/common/GoldToken.sol b/packages/protocol/contracts/common/GoldToken.sol index 742c8cd9f4f..501774f24fa 100644 --- a/packages/protocol/contracts/common/GoldToken.sol +++ b/packages/protocol/contracts/common/GoldToken.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.5.13; import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; @@ -10,7 +11,6 @@ import "./Initializable.sol"; import "./interfaces/ICeloToken.sol"; import "./interfaces/ICeloTokenInitializer.sol"; import "./interfaces/ICeloVersionedContract.sol"; -import "./interfaces/ICeloUnreleasedTreasury.sol"; import "../../contracts-0.8/common/IsL2Check.sol"; contract GoldToken is @@ -270,8 +270,7 @@ contract GoldToken is */ function allocatedSupply() public view returns (uint256) { if (isL2()) { - return - CELO_SUPPLY_CAP - registry.getAddressForOrDie(CELO_UNRELEASED_TREASURY_REGISTRY_ID).balance; + return CELO_SUPPLY_CAP - getCeloUnreleasedTreasury().getRemainingBalanceToRelease(); } else { return totalSupply(); } diff --git a/packages/protocol/contracts/common/PrecompilesOverride.sol b/packages/protocol/contracts/common/PrecompilesOverride.sol index 262152a55b4..5be5a83ce29 100644 --- a/packages/protocol/contracts/common/PrecompilesOverride.sol +++ b/packages/protocol/contracts/common/PrecompilesOverride.sol @@ -51,7 +51,6 @@ contract PrecompilesOverride is UsingPrecompiles, UsingRegistry { * @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); } diff --git a/packages/protocol/contracts/common/interfaces/IBlockable.sol b/packages/protocol/contracts/common/interfaces/IBlockable.sol index c6663fbbaf1..0f2ad5516e5 100644 --- a/packages/protocol/contracts/common/interfaces/IBlockable.sol +++ b/packages/protocol/contracts/common/interfaces/IBlockable.sol @@ -3,5 +3,5 @@ pragma solidity >=0.5.13 <0.9.0; interface IBlockable { function setBlockedByContract(address _blockedBy) external; function isBlocked() external view returns (bool); - function getBlockedbyContract() external view returns (address); + function getBlockedByContract() external view returns (address); } diff --git a/packages/protocol/contracts/common/interfaces/ICeloUnreleasedTreasury.sol b/packages/protocol/contracts/common/interfaces/ICeloUnreleasedTreasury.sol index b561ba11cb4..e14b9bf536c 100644 --- a/packages/protocol/contracts/common/interfaces/ICeloUnreleasedTreasury.sol +++ b/packages/protocol/contracts/common/interfaces/ICeloUnreleasedTreasury.sol @@ -8,4 +8,6 @@ interface ICeloUnreleasedTreasury { * @param amount The amount to release. */ function release(address to, uint256 amount) external; + + function getRemainingBalanceToRelease() external view returns (uint256); } diff --git a/packages/protocol/contracts/common/interfaces/IFeeHandlerSeller.sol b/packages/protocol/contracts/common/interfaces/IFeeHandlerSeller.sol index deb41a2ee15..fa3437c8222 100644 --- a/packages/protocol/contracts/common/interfaces/IFeeHandlerSeller.sol +++ b/packages/protocol/contracts/common/interfaces/IFeeHandlerSeller.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.5.13 <0.9.0; interface IFeeHandlerSeller { diff --git a/packages/protocol/contracts/common/interfaces/IProxy.sol b/packages/protocol/contracts/common/interfaces/IProxy.sol index dd4f9dffb7e..bdcabc09d8f 100644 --- a/packages/protocol/contracts/common/interfaces/IProxy.sol +++ b/packages/protocol/contracts/common/interfaces/IProxy.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.5.13 <0.9.0; interface IProxy { diff --git a/packages/protocol/contracts/common/libraries/ReentrancyGuard.sol b/packages/protocol/contracts/common/libraries/ReentrancyGuard.sol index 8c48a49c652..5364754c495 100644 --- a/packages/protocol/contracts/common/libraries/ReentrancyGuard.sol +++ b/packages/protocol/contracts/common/libraries/ReentrancyGuard.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.5.13 <0.8.20; /** diff --git a/packages/protocol/contracts/governance/BlockchainParameters.sol b/packages/protocol/contracts/governance/BlockchainParameters.sol index 31777090d76..45bebda1704 100644 --- a/packages/protocol/contracts/governance/BlockchainParameters.sol +++ b/packages/protocol/contracts/governance/BlockchainParameters.sol @@ -28,9 +28,9 @@ contract BlockchainParameters is Ownable, Initializable, UsingPrecompiles { } ClientVersion private minimumClientVersion; // obsolete - uint256 public blockGasLimit; - uint256 public intrinsicGasForAlternativeFeeCurrency; - LookbackWindow public uptimeLookbackWindow; + uint256 private deprecated_blockGasLimit; + uint256 private deprecated_intrinsicGasForAlternativeFeeCurrency; + LookbackWindow private uptimeLookbackWindow; event IntrinsicGasForAlternativeFeeCurrencySet(uint256 gas); event BlockGasLimitSet(uint256 limit); @@ -67,7 +67,7 @@ contract BlockchainParameters is Ownable, Initializable, UsingPrecompiles { * @return Patch version of the contract. */ function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) { - return (1, 3, 0, 1); + return (1, 3, 1, 0); } /** @@ -75,7 +75,7 @@ contract BlockchainParameters is Ownable, Initializable, UsingPrecompiles { * @param gasLimit New block gas limit. */ function setBlockGasLimit(uint256 gasLimit) public onlyOwner onlyL1 { - blockGasLimit = gasLimit; + deprecated_blockGasLimit = gasLimit; emit BlockGasLimitSet(gasLimit); } @@ -84,7 +84,7 @@ contract BlockchainParameters is Ownable, Initializable, UsingPrecompiles { * @param gas Intrinsic gas for non-gold gas currencies. */ function setIntrinsicGasForAlternativeFeeCurrency(uint256 gas) public onlyOwner onlyL1 { - intrinsicGasForAlternativeFeeCurrency = gas; + deprecated_intrinsicGasForAlternativeFeeCurrency = gas; emit IntrinsicGasForAlternativeFeeCurrencySet(gas); } @@ -116,6 +116,26 @@ contract BlockchainParameters is Ownable, Initializable, UsingPrecompiles { require(lookbackWindow != 0, "UptimeLookbackWindow is not initialized"); } + /** + * @notice Gets the Celo L1 block gas limit. + * @return The block gas limit. + * @dev Once Celo becomes an L2, query Optimism's L1 SystemConfig contract + * instead. + */ + function blockGasLimit() public view onlyL1 returns (uint256) { + return deprecated_blockGasLimit; + } + + /** + * @notice Gets the intrinsic gas paid for transactions using alternative fee + * currencies. + * @return The intrinsic gas for alternative fee currencies. + * @dev Once Celo becomes an L2, query the FeeCurrencyDirectory instead. + */ + function intrinsicGasForAlternativeFeeCurrency() public view onlyL1 returns (uint256) { + return deprecated_intrinsicGasForAlternativeFeeCurrency; + } + /** * @notice Gets the uptime lookback window. */ diff --git a/packages/protocol/contracts/governance/Election.sol b/packages/protocol/contracts/governance/Election.sol index f95e2ead23a..3db4ec170ae 100644 --- a/packages/protocol/contracts/governance/Election.sol +++ b/packages/protocol/contracts/governance/Election.sol @@ -17,6 +17,9 @@ import "../common/libraries/ReentrancyGuard.sol"; import "../common/Blockable.sol"; import "../common/PrecompilesOverride.sol"; +/** + * @title Manages the validator election process. + */ contract Election is IElection, ICeloVersionedContract, @@ -153,6 +156,12 @@ contract Election is ); event EpochRewardsDistributedToVoters(address indexed group, uint256 value); + /** + * @notice - On L1, ensures the function is called via the consensus client. + * - On L2, ensures the function is called by the permitted address. + * @param permittedAddress The address permitted to call permissioned + * functions on L2. + */ modifier onlyVmOrPermitted(address permittedAddress) { if (isL2()) require(msg.sender == permittedAddress, "Only permitted address can call"); else { @@ -428,9 +437,11 @@ contract Election is return value; } - /// @notice Sets the address of the blocking contract. - /// @param _blockedBy The address of the contract that will determine if this contract is blocked. - /// @dev Can only be called by the owner of the contract. + /** + * @notice Sets the address of the blocking contract. + * @param _blockedBy The address of the contract that will determine if this contract is blocked. + * @dev Can only be called by the owner of the contract. + */ function setBlockedByContract(address _blockedBy) external onlyOwner { _setBlockedBy(_blockedBy); } diff --git a/packages/protocol/contracts/governance/Governance.sol b/packages/protocol/contracts/governance/Governance.sol index e03ac17459d..2459183314c 100644 --- a/packages/protocol/contracts/governance/Governance.sol +++ b/packages/protocol/contracts/governance/Governance.sol @@ -207,21 +207,38 @@ contract Governance is event HotfixRecordReset(bytes32 indexed hash); + /** + * @notice Ensures a hotfix can be executed only once. + * @param hash Hash of the hotfix. + * @dev Reverts if the hotfix has already been executed. + */ modifier hotfixNotExecuted(bytes32 hash) { require(!hotfixes[hash].executed, "hotfix already executed"); _; } + /** + * @notice Ensures function can only be called by the approver address. + */ modifier onlyApprover() { require(msg.sender == approver, "msg.sender not approver"); _; } + /** + * @notice Ensures function can only be called by the LockedGold contract. + */ modifier onlyLockedGold() { require(msg.sender == address(getLockedGold()), "msg.sender not lockedGold"); _; } + /** + * @notice Ensures a hotfix cannot be executed after the time limit. + * @param hash Hash of the hotfix. + * @dev Reverts if the hotfix time limit has been reached, or the hotfix is + * not prepared yet. + */ modifier hotfixTimedOut(bytes32 hash) { require(hotfixes[hash].executionTimeLimit > 0, "hotfix not prepared"); require(hotfixes[hash].executionTimeLimit < now, "hotfix execution time limit not reached"); @@ -327,6 +344,11 @@ contract Governance is emit SecurityCouncilSet(_council); } + /** + * @notice Sets the time window during which a hotfix has to be executed. + * @param timeWindow The time (in seconds) during which a hotfix can be + * executed after it has been prepared. + */ function setHotfixExecutionTimeWindow(uint256 timeWindow) external onlyOwner { require(timeWindow > 0, "Execution time window cannot be zero"); hotfixExecutionTimeWindow = timeWindow; diff --git a/packages/protocol/contracts/governance/test/MockElection.sol b/packages/protocol/contracts/governance/test/MockElection.sol index b698df5ea5c..b3ea2717fe2 100644 --- a/packages/protocol/contracts/governance/test/MockElection.sol +++ b/packages/protocol/contracts/governance/test/MockElection.sol @@ -35,23 +35,23 @@ contract MockElection is IsL2Check { electedValidators = _electedValidators; } - function vote(address, uint256, address, address) external returns (bool) { + function vote(address, uint256, address, address) external pure returns (bool) { return true; } - function activate(address) external returns (bool) { + function activate(address) external pure returns (bool) { return true; } - function revokeAllActive(address, address, address, uint256) external returns (bool) { + function revokeAllActive(address, address, address, uint256) external pure returns (bool) { return true; } - function revokeActive(address, uint256, address, address, uint256) external returns (bool) { + function revokeActive(address, uint256, address, address, uint256) external pure returns (bool) { return true; } - function revokePending(address, uint256, address, address, uint256) external returns (bool) { + function revokePending(address, uint256, address, address, uint256) external pure returns (bool) { return true; } @@ -74,7 +74,7 @@ contract MockElection is IsL2Check { return active; } - function getTotalVotesByAccount(address) external view returns (uint256) { + function getTotalVotesByAccount(address) external pure returns (uint256) { return 0; } @@ -91,8 +91,8 @@ contract MockElection is IsL2Check { function getGroupEpochRewardsBasedOnScore( address group, - uint256 totalEpochRewards, - uint256 groupScore + uint256, + uint256 ) external view returns (uint256) { return groupRewardsBasedOnScore[group]; } @@ -101,12 +101,7 @@ contract MockElection is IsL2Check { groupRewardsBasedOnScore[group] = groupRewards; } - function distributeEpochRewards( - address group, - uint256 value, - address lesser, - address greater - ) external { + function distributeEpochRewards(address group, uint256 value, address, address) external { distributedEpochRewards[group] = value; } diff --git a/packages/protocol/contracts/governance/test/MockGovernance.sol b/packages/protocol/contracts/governance/test/MockGovernance.sol index 29888c3adb4..936f1a42175 100644 --- a/packages/protocol/contracts/governance/test/MockGovernance.sol +++ b/packages/protocol/contracts/governance/test/MockGovernance.sol @@ -27,22 +27,16 @@ contract MockGovernance is IGovernance { removeVotesCalledFor[account] = maxAmountAllowed; } - function setConstitution(address destination, bytes4 functionId, uint256 threshold) external { + function setConstitution(address, bytes4, uint256) external { revert("not implemented"); } - function votePartially( - uint256 proposalId, - uint256 index, - uint256 yesVotes, - uint256 noVotes, - uint256 abstainVotes - ) external returns (bool) { + function votePartially(uint256, uint256, uint256, uint256, uint256) external returns (bool) { return true; } function getProposal( - uint256 proposalId + uint256 ) external view returns (address, uint256, uint256, uint256, string memory, uint256, bool) { return (address(0), 0, 0, 0, "", 0, false); } diff --git a/packages/protocol/contracts/governance/test/MockLockedGold.sol b/packages/protocol/contracts/governance/test/MockLockedGold.sol index c0cc60c20e8..6b52c329eeb 100644 --- a/packages/protocol/contracts/governance/test/MockLockedGold.sol +++ b/packages/protocol/contracts/governance/test/MockLockedGold.sol @@ -115,10 +115,7 @@ contract MockLockedGold is ILockedGold { return totalGovernancePower[account]; } - function getPendingWithdrawal( - address account, - uint256 index - ) external view returns (uint256, uint256) { + function getPendingWithdrawal(address, uint256) external view returns (uint256, uint256) { return (0, 0); } @@ -126,7 +123,7 @@ contract MockLockedGold is ILockedGold { return 0; } - function getAccountNonvotingLockedGold(address account) external view returns (uint256) { + function getAccountNonvotingLockedGold(address) external view returns (uint256) { return 0; } diff --git a/packages/protocol/contracts/governance/test/MockValidators.sol b/packages/protocol/contracts/governance/test/MockValidators.sol index 2d8a8630026..9b7f27d4802 100644 --- a/packages/protocol/contracts/governance/test/MockValidators.sol +++ b/packages/protocol/contracts/governance/test/MockValidators.sol @@ -169,7 +169,7 @@ contract MockValidators is IValidators, IsL2Check { revert("Method not implemented in mock"); } - function registerValidatorNoBls(bytes calldata ecdsaPublicKey) external returns (bool) { + function registerValidatorNoBls(bytes calldata) external returns (bool) { revert("Method not implemented in mock"); } function removeMember(address) external returns (bool) { @@ -208,7 +208,7 @@ contract MockValidators is IValidators, IsL2Check { revert("Method not implemented in mock"); } - function setDowntimeGracePeriod(uint256 value) external { + function setDowntimeGracePeriod(uint256) external { revert("Method not implemented in mock"); } @@ -304,11 +304,7 @@ contract MockValidators is IValidators, IsL2Check { revert("Method not implemented in mock"); } - function computeEpochReward( - address account, - uint256 score, - uint256 maxPayment - ) external view returns (uint256) { + function computeEpochReward(address account, uint256, uint256) external view returns (uint256) { return epochRewards[account]; } @@ -331,7 +327,7 @@ contract MockValidators is IValidators, IsL2Check { } function getValidator( - address account + address ) external view returns (bytes memory, bytes memory, address, uint256, address) { revert("Method not implemented in mock"); } diff --git a/packages/protocol/contracts/identity/IdentityProxyHub.sol b/packages/protocol/contracts/identity/IdentityProxyHub.sol index 5c8f98be223..608c1ea6281 100644 --- a/packages/protocol/contracts/identity/IdentityProxyHub.sol +++ b/packages/protocol/contracts/identity/IdentityProxyHub.sol @@ -103,10 +103,7 @@ contract IdentityProxyHub is UsingRegistry, ICeloVersionedContract { for (uint256 i = 0; i < addresses.length; i++) { address otherAddr = addresses[i]; if (otherAddr != addr) { - (uint32 otherCompleted, uint32 _requested) = attestations.getAttestationStats( - identifier, - otherAddr - ); + (uint32 otherCompleted, ) = attestations.getAttestationStats(identifier, otherAddr); hasMostCompletions = hasMostCompletions && otherCompleted <= completed; } } diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index 8062d6b9612..41ffdbc1d22 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -23,9 +23,9 @@ contract Random is using SafeMath for uint256; /* Stores most recent commitment per address */ - mapping(address => bytes32) public commitments; + mapping(address => bytes32) private deprecated_commitments; - uint256 public randomnessBlockRetentionWindow; + uint256 private deprecated_randomnessBlockRetentionWindow; mapping(uint256 => bytes32) private history; uint256 private historyFirst; @@ -77,6 +77,20 @@ contract Random is return _getBlockRandomness(block.number, block.number); } + /** + * @notice Returns the most recent commitment by a validator. + * @param addr Address of the validator. + * @return The validator's most recent commitment. + * @dev The Random system will be deprecated once Celo becomes an L2. + */ + function commitments(address addr) external view onlyL1 returns (bytes32) { + return deprecated_commitments[addr]; + } + + function randomnessBlockRetentionWindow() external view onlyL1 returns (uint256) { + return deprecated_randomnessBlockRetentionWindow; + } + /** * @notice Get randomness values of previous blocks. * @param blockNumber The number of block whose randomness value we want to know. @@ -95,7 +109,7 @@ contract Random is * @return Patch version of the contract. */ function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) { - return (1, 1, 1, 1); + return (1, 1, 2, 0); } /** @@ -105,7 +119,7 @@ contract Random is */ function setRandomnessBlockRetentionWindow(uint256 value) public onlyL1 onlyOwner { require(value > 0, "randomnessBlockRetetionWindow cannot be zero"); - randomnessBlockRetentionWindow = value; + deprecated_randomnessBlockRetentionWindow = value; emit RandomnessBlockRetentionWindowSet(value); } @@ -133,11 +147,11 @@ contract Random is require(newCommitment != computeCommitment(0), "cannot commit zero randomness"); // ensure revealed randomness matches previous commitment - if (commitments[proposer] != 0) { + if (deprecated_commitments[proposer] != 0) { require(randomness != 0, "randomness cannot be zero if there is a previous commitment"); bytes32 expectedCommitment = computeCommitment(randomness); require( - expectedCommitment == commitments[proposer], + expectedCommitment == deprecated_commitments[proposer], "commitment didn't match the posted randomness" ); } else { @@ -148,7 +162,7 @@ contract Random is uint256 blockNumber = block.number == 0 ? 0 : block.number.sub(1); addRandomness(block.number, keccak256(abi.encodePacked(history[blockNumber], randomness))); - commitments[proposer] = newCommitment; + deprecated_commitments[proposer] = newCommitment; } /** @@ -170,16 +184,16 @@ contract Random is if (historySize == 0) { historyFirst = blockNumber; historySize = 1; - } else if (historySize > randomnessBlockRetentionWindow) { + } else if (historySize > deprecated_randomnessBlockRetentionWindow) { deleteHistoryIfNotLastEpochBlock(historyFirst); deleteHistoryIfNotLastEpochBlock(historyFirst.add(1)); historyFirst = historyFirst.add(2); historySize = historySize.sub(1); - } else if (historySize == randomnessBlockRetentionWindow) { + } else if (historySize == deprecated_randomnessBlockRetentionWindow) { deleteHistoryIfNotLastEpochBlock(historyFirst); historyFirst = historyFirst.add(1); } else { - // historySize < randomnessBlockRetentionWindow + // historySize < deprecated_randomnessBlockRetentionWindow historySize = historySize.add(1); } } @@ -206,8 +220,8 @@ contract Random is require( blockNumber == lastEpochBlock || (blockNumber > cur.sub(historySize) && - (randomnessBlockRetentionWindow >= cur || - blockNumber > cur.sub(randomnessBlockRetentionWindow))), + (deprecated_randomnessBlockRetentionWindow >= cur || + blockNumber > cur.sub(deprecated_randomnessBlockRetentionWindow))), "Cannot query randomness older than the stored history" ); return history[blockNumber]; 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 4ffc7ba037b..6283865af02 100644 --- a/packages/protocol/test-sol/devchain/e2e/common/EpochManager.t.sol +++ b/packages/protocol/test-sol/devchain/e2e/common/EpochManager.t.sol @@ -43,8 +43,6 @@ contract E2E_EpochManager is Test, Devchain, Utils08, ECDSAHelper08 { EnumerableSet.AddressSet internal electedGroupsHelper; function setUp() public virtual { - uint256 totalVotes = election.getTotalVotes(); - epochManagerOwner = Ownable(address(epochManager)).owner(); epochManagerEnabler = registry.getAddressForOrDie(EPOCH_MANAGER_ENABLER_REGISTRY_ID); firstElected = getValidators().getRegisteredValidators(); @@ -96,9 +94,10 @@ contract E2E_EpochManager is Test, Devchain, Utils08, ECDSAHelper08 { } function getLessersAndGreaters( - address[] memory groups + address[] memory _groups ) internal + view returns ( address[] memory lessers, address[] memory greaters, @@ -106,26 +105,24 @@ contract E2E_EpochManager is Test, Devchain, Utils08, ECDSAHelper08 { ) { (, , uint256 maxTotalRewards, , ) = epochManager.getEpochProcessingState(); - uint256 totalRewards = 0; - (, groupWithVotes) = getGroupsWithVotes(); - lessers = new address[](groups.length); - greaters = new address[](groups.length); + lessers = new address[](_groups.length); + greaters = new address[](_groups.length); - uint256[] memory rewards = new uint256[](groups.length); + uint256[] memory rewards = new uint256[](_groups.length); - for (uint256 i = 0; i < groups.length; i++) { - uint256 groupScore = scoreManager.getGroupScore(groups[i]); + for (uint256 i = 0; i < _groups.length; i++) { + uint256 _groupScore = scoreManager.getGroupScore(_groups[i]); rewards[i] = election.getGroupEpochRewardsBasedOnScore( - groups[i], + _groups[i], maxTotalRewards, - groupScore + _groupScore ); } - for (uint256 i = 0; i < groups.length; i++) { + for (uint256 i = 0; i < _groups.length; i++) { for (uint256 j = 0; j < groupWithVotes.length; j++) { - if (groupWithVotes[j].group == groups[i]) { + if (groupWithVotes[j].group == _groups[i]) { groupWithVotes[j].votes += rewards[i]; break; } @@ -136,7 +133,7 @@ contract E2E_EpochManager is Test, Devchain, Utils08, ECDSAHelper08 { address greater = address(0); for (uint256 j = 0; j < groupWithVotes.length; j++) { - if (groupWithVotes[j].group == groups[i]) { + if (groupWithVotes[j].group == _groups[i]) { greater = j == 0 ? address(0) : groupWithVotes[j - 1].group; lesser = j == groupWithVotes.length - 1 ? address(0) : groupWithVotes[j + 1].group; break; @@ -150,6 +147,7 @@ contract E2E_EpochManager is Test, Devchain, Utils08, ECDSAHelper08 { function getGroupsWithVotes() internal + view returns (address[] memory groupsInOrder, GroupWithVotes[] memory groupWithVotes) { uint256[] memory votesTotal; @@ -162,7 +160,7 @@ contract E2E_EpochManager is Test, Devchain, Utils08, ECDSAHelper08 { } // Bubble sort algorithm since it is a small array - function sort(GroupWithVotes[] memory items) internal { + function sort(GroupWithVotes[] memory items) internal pure { uint length = items.length; for (uint i = 0; i < length; i++) { for (uint j = 0; j < length - 1; j++) { @@ -178,7 +176,6 @@ contract E2E_EpochManager is Test, Devchain, Utils08, ECDSAHelper08 { function assertGroupWithVotes(GroupWithVotes[] memory groupWithVotes) internal { for (uint256 i = 0; i < groupWithVotes.length; i++) { - uint256 expected = election.getTotalVotesForGroup(groupWithVotes[i].group); assertEq(election.getTotalVotesForGroup(groupWithVotes[i].group), groupWithVotes[i].votes); } } @@ -237,7 +234,7 @@ contract E2E_EpochManager is Test, Devchain, Utils08, ECDSAHelper08 { scoreManager.setGroupScore(newValidatorGroup, groupScore[3]); } - function getValidatorGroupsFromElected() internal returns (address[] memory) { + function getValidatorGroupsFromElected() internal view returns (address[] memory) { address[] memory elected = epochManager.getElectedAccounts(); address[] memory validatorGroups = new address[](elected.length); for (uint256 i = 0; i < elected.length; i++) { @@ -343,12 +340,7 @@ contract E2E_EpochManager_GetCurrentEpoch is E2E_EpochManager { function test_Revert_WhenSystemNotInitialized() public { vm.expectRevert("Epoch system not initialized"); - ( - uint256 firstBlock, - uint256 lastBlock, - uint256 startTimestamp, - uint256 rewardsBlock - ) = epochManager.getCurrentEpoch(); + epochManager.getCurrentEpoch(); } function test_ReturnExpectedValues() public { @@ -478,9 +470,7 @@ contract E2E_EpochManager_FinishNextEpochProcess is E2E_EpochManager { function test_shouldFinishNextEpochProcessing() public { address[] memory lessers; address[] memory greaters; - address[] memory groupsEligible; GroupWithVotes[] memory groupWithVotes; - uint256[] memory groupActiveBalances; (lessers, greaters, groupWithVotes) = getLessersAndGreaters(groups); uint256 currentEpoch = epochManager.getCurrentEpochNumber(); @@ -497,8 +487,6 @@ contract E2E_EpochManager_FinishNextEpochProcess is E2E_EpochManager { assertEq(currentEpoch + 1, epochManager.getCurrentEpochNumber()); - address[] memory newlyElected = epochManager.getElectedAccounts(); - for (uint256 i = 0; i < currentlyElected.length; i++) { assertEq(originalyElected.contains(currentlyElected[i]), true); } @@ -564,7 +552,7 @@ contract E2E_EpochManager_FinishNextEpochProcess is E2E_EpochManager { assertGroupWithVotes(groupWithVotes); ( - uint256 status, + , uint256 perValidatorReward, uint256 totalRewardsVoter, uint256 totalRewardsCommunity, @@ -621,9 +609,7 @@ contract E2E_GasTest_Setup is E2E_EpochManager { address[] memory lessers; address[] memory greaters; - address[] memory groupsEligible; GroupWithVotes[] memory groupWithVotes; - uint256[] memory groupActiveBalances; (lessers, greaters, groupWithVotes) = getLessersAndGreaters(groups); uint256 currentEpoch = epochManager.getCurrentEpochNumber(); @@ -640,8 +626,6 @@ contract E2E_GasTest_Setup is E2E_EpochManager { assertEq(currentEpoch + 1, epochManager.getCurrentEpochNumber()); - address[] memory newlyElected = epochManager.getElectedAccounts(); - for (uint256 i = 0; i < currentlyElected.length; i++) { assertEq(originalyElected.contains(currentlyElected[i]), true); } @@ -666,10 +650,7 @@ contract E2E_GasTest_Setup is E2E_EpochManager { } for (uint256 i = 0; i < validatorGroupCount; i++) { - (address newValidatorGroup, address newValidator) = registerNewValidatorGroupWithValidator( - i, - validatorPerGroupCount - ); + registerNewValidatorGroupWithValidator(i, validatorPerGroupCount); } timeTravel(vm, epochDuration + 1); @@ -781,9 +762,7 @@ contract E2E_FinishNextEpochProcess_Split is E2E_GasTest_Setup { address[] memory lessers; address[] memory greaters; - address[] memory groupsEligible; GroupWithVotes[] memory groupWithVotes; - uint256[] memory groupActiveBalances; (lessers, greaters, groupWithVotes) = getLessersAndGreaters(groups); uint256 currentEpoch = epochManager.getCurrentEpochNumber(); @@ -803,8 +782,6 @@ contract E2E_FinishNextEpochProcess_Split is E2E_GasTest_Setup { assertEq(currentEpoch + 1, epochManager.getCurrentEpochNumber()); - address[] memory newlyElected = epochManager.getElectedAccounts(); - for (uint256 i = 0; i < currentlyElected.length; i++) { assertEq(originalyElected.contains(currentlyElected[i]), true); } @@ -835,10 +812,7 @@ contract E2E_FinishNextEpochProcess_Split is E2E_GasTest_Setup { uint256 validatorPerGroupCount = 2; for (uint256 i = 0; i < validatorGroupCount; i++) { - (address newValidatorGroup, address newValidator) = registerNewValidatorGroupWithValidator( - i, - validatorPerGroupCount - ); + registerNewValidatorGroupWithValidator(i, validatorPerGroupCount); } timeTravel(vm, epochDuration + 1); diff --git a/packages/protocol/test-sol/devchain/migration/Migration.t.sol b/packages/protocol/test-sol/devchain/migration/Migration.t.sol index 14dafb5bd09..cb6d01f99e6 100644 --- a/packages/protocol/test-sol/devchain/migration/Migration.t.sol +++ b/packages/protocol/test-sol/devchain/migration/Migration.t.sol @@ -22,6 +22,8 @@ import "@celo-contracts/governance/interfaces/IValidators.sol"; import "@celo-contracts-8/common/interfaces/IPrecompiles.sol"; import "@celo-contracts-8/common/interfaces/IScoreManager.sol"; +import "@openzeppelin/contracts8/token/ERC20/IERC20.sol"; + contract IntegrationTest is Test, TestConstants, Utils08 { IRegistry registry = IRegistry(REGISTRY_ADDRESS); @@ -236,6 +238,19 @@ contract EpochManagerIntegrationTest is IntegrationTest, MigrationsConstants { epochManager.initializeSystem(100, block.number, firstElected); } + function test_Reverts_whenTransferingCeloToUnreleasedTreasury() public { + _MockL2Migration(validatorsList); + + blockTravel(vm, 43200); + timeTravel(vm, DAY); + + IERC20 _celoToken = IERC20(address(celoToken)); + vm.prank(randomAddress); + + (bool success, ) = address(unreleasedTreasury).call{ value: 50000 ether }(""); + assertFalse(success); + } + function test_SetsCurrentRewardBlock() public { _MockL2Migration(validatorsList); @@ -245,8 +260,9 @@ contract EpochManagerIntegrationTest is IntegrationTest, MigrationsConstants { epochManager.startNextEpochProcess(); (, , , uint256 _currentRewardsBlock) = epochManager.getCurrentEpoch(); - + (uint256 status, , , , ) = epochManager.getEpochProcessingState(); assertEq(_currentRewardsBlock, block.number); + assertEq(status, 1); } function _MockL2Migration(address[] memory _validatorsList) internal { diff --git a/packages/protocol/test-sol/integration/CompileValidatorMock.t.sol b/packages/protocol/test-sol/integration/CompileValidatorMock.t.sol index a4a8aa9930f..7fbc16ca0c1 100644 --- a/packages/protocol/test-sol/integration/CompileValidatorMock.t.sol +++ b/packages/protocol/test-sol/integration/CompileValidatorMock.t.sol @@ -8,7 +8,7 @@ import "forge-std/console.sol"; import "@test-sol/unit/governance/validators/mocks/ValidatorsMock.sol"; contract CompileValidatorMock is Test { - function test_nop() public { + function test_nop() public view { console.log("nop"); } } diff --git a/packages/protocol/test-sol/integration/RevokeCeloAfterL2Transition.sol b/packages/protocol/test-sol/integration/RevokeCeloAfterL2Transition.sol index 13e4fb9ba05..76cc5245074 100644 --- a/packages/protocol/test-sol/integration/RevokeCeloAfterL2Transition.sol +++ b/packages/protocol/test-sol/integration/RevokeCeloAfterL2Transition.sol @@ -302,7 +302,7 @@ contract RevokeCeloAfterL2Transition is Test, TestConstants, ECDSAHelper, Utils epochManager.initializeSystem(l1EpochNumber, block.number, _elected); } - function _registerValidatorGroupHelper(address _group, uint256 numMembers) internal { + function _registerValidatorGroupHelper(address _group, uint256) internal { vm.startPrank(_group); if (!accounts.isAccount(_group)) { accounts.createAccount(); @@ -485,10 +485,7 @@ contract RevokeCeloAfterL2TransitionTest is RevokeCeloAfterL2Transition { address _validator, uint256 signerPk ) internal returns (bytes memory) { - (bytes memory _ecdsaPubKey, uint8 v, bytes32 r, bytes32 s) = _generateEcdsaPubKeyWithSigner( - _validator, - signerPk - ); + (bytes memory _ecdsaPubKey, , , ) = _generateEcdsaPubKeyWithSigner(_validator, signerPk); ph.mockSuccess(ph.PROOF_OF_POSSESSION(), abi.encodePacked(_validator, blsPublicKey, blsPop)); diff --git a/packages/protocol/test-sol/unit/common/Blockable.t.sol b/packages/protocol/test-sol/unit/common/Blockable.t.sol index 0ec65176398..8eb0c78a124 100644 --- a/packages/protocol/test-sol/unit/common/Blockable.t.sol +++ b/packages/protocol/test-sol/unit/common/Blockable.t.sol @@ -26,7 +26,7 @@ contract BlockableMock is Blockable, Ownable { } contract TestBlockable is BlockableMock { - function functionToBeBlocked() public onlyWhenNotBlocked { + function functionToBeBlocked() public view onlyWhenNotBlocked { return; } } @@ -48,7 +48,7 @@ contract BlockableTest is Test { contract BlockableTest_setBlockable is BlockableTest { function test_setBlockable() public { blockable.setBlockedByContract(address(blocker)); - assert(blockable.getBlockedbyContract() == address(blocker)); + assert(blockable.getBlockedByContract() == address(blocker)); } function test_Reverts_WhenNotCalledByOwner() public { @@ -65,7 +65,7 @@ contract BlockableTest_setBlockable is BlockableTest { } contract BlockableTest_isBlocked is BlockableTest { - function test_isFalse_WhenBlockableNotSet() public { + function test_isFalse_WhenBlockableNotSet() public view { assert(blockable.isBlocked() == false); } @@ -92,7 +92,7 @@ contract BlockableTest_onlyWhenNotBlocked is BlockableTest { blockableWithFunction.functionToBeBlocked(); } - function test_callsucceeds_WhenNotBlocked() public { + function test_callsucceeds_WhenNotBlocked() public view { blockableWithFunction.functionToBeBlocked(); } } diff --git a/packages/protocol/test-sol/unit/common/CeloUnreleasedTreasury.t.sol b/packages/protocol/test-sol/unit/common/CeloUnreleasedTreasury.t.sol index 396044b7bf9..7f5b6ab8179 100644 --- a/packages/protocol/test-sol/unit/common/CeloUnreleasedTreasury.t.sol +++ b/packages/protocol/test-sol/unit/common/CeloUnreleasedTreasury.t.sol @@ -62,8 +62,9 @@ contract CeloUnreleasedTreasuryTest is Test, TestConstants, IsL2Check { deployCodeTo("Registry.sol", abi.encode(false), REGISTRY_ADDRESS); registry = IRegistry(REGISTRY_ADDRESS); - deployCodeTo("GoldToken.sol", abi.encode(false), celoTokenAddress); + deployCodeTo("GoldToken.sol", abi.encode(true), celoTokenAddress); celoToken = ICeloToken(celoTokenAddress); + celoToken.initialize(REGISTRY_ADDRESS); // Using a mock contract, as foundry does not allow for library linking when using deployCodeTo governance = new MockGovernance(); @@ -80,7 +81,7 @@ contract CeloUnreleasedTreasuryTest is Test, TestConstants, IsL2Check { assertEq(celoToken.allocatedSupply(), L1_MINTED_CELO_SUPPLY, "total supply incorrect."); } - function newCeloUnreleasedTreasury() internal returns (CeloUnreleasedTreasury) { + function newCeloUnreleasedTreasury() internal { vm.warp(block.timestamp + l2StartTime); vm.prank(celoDistributionOwner); celoUnreleasedTreasury = new CeloUnreleasedTreasury(true); @@ -156,3 +157,39 @@ contract CeloUnreleasedTreasuryTest_release is CeloUnreleasedTreasuryTest { celoUnreleasedTreasury.release(randomAddress, 4); } } +contract CeloUnreleasedTreasuryTest_getRemainingBalanceToRelease is CeloUnreleasedTreasuryTest { + uint256 _startingBalance; + function setUp() public override { + super.setUp(); + newCeloUnreleasedTreasury(); + _startingBalance = address(celoUnreleasedTreasury).balance; + } + + function test_ShouldReturnContractBalanceBeforeFirstRelease() public { + uint256 _remainingBalance = celoUnreleasedTreasury.getRemainingBalanceToRelease(); + + assertEq(_startingBalance, _remainingBalance); + } + + function test_ShouldReturnRemainingBalanceToReleaseAfterFirstRelease() public { + vm.prank(epochManagerAddress); + + celoUnreleasedTreasury.release(randomAddress, 4); + uint256 _remainingBalance = celoUnreleasedTreasury.getRemainingBalanceToRelease(); + assertEq(_remainingBalance, _startingBalance - 4); + } + + function test_RemainingBalanceToReleaseShouldRemainUnchangedAfterCeloTransferBackToContract() + public + { + vm.prank(epochManagerAddress); + + celoUnreleasedTreasury.release(randomAddress, 4); + uint256 _remainingBalanceBeforeTransfer = celoUnreleasedTreasury.getRemainingBalanceToRelease(); + assertEq(_remainingBalanceBeforeTransfer, _startingBalance - 4); + // set the contract balance to mock a CELO token transfer + vm.deal(address(celoUnreleasedTreasury), L2_INITIAL_STASH_BALANCE); + uint256 _remainingBalanceAfterTransfer = celoUnreleasedTreasury.getRemainingBalanceToRelease(); + assertEq(_remainingBalanceAfterTransfer, _remainingBalanceBeforeTransfer); + } +} diff --git a/packages/protocol/test-sol/unit/common/EpochManager.t.sol b/packages/protocol/test-sol/unit/common/EpochManager.t.sol index ee81e5a7044..bdc0de7048b 100644 --- a/packages/protocol/test-sol/unit/common/EpochManager.t.sol +++ b/packages/protocol/test-sol/unit/common/EpochManager.t.sol @@ -7,7 +7,6 @@ import "@celo-contracts-8/stability/test/MockStableToken.sol"; import "@celo-contracts-8/common/test/MockCeloToken.sol"; import "@celo-contracts/common/interfaces/ICeloToken.sol"; import "@celo-contracts-8/common/ScoreManager.sol"; -import { CeloUnreleasedTreasury } from "@celo-contracts-8/common/CeloUnreleasedTreasury.sol"; import { ICeloUnreleasedTreasury } from "@celo-contracts/common/interfaces/ICeloUnreleasedTreasury.sol"; import { TestConstants } from "@test-sol/constants.sol"; @@ -170,6 +169,7 @@ contract EpochManagerTest is Test, TestConstants, Utils08 { function getGroupsWithLessersAndGreaters() public + view returns (address[] memory, address[] memory, address[] memory) { address[] memory groups = new address[](1); @@ -304,7 +304,6 @@ contract EpochManagerTest_startNextEpochProcess is EpochManagerTest { function test_ShouldMintTotalValidatorStableRewardsToEpochManager() public { initializeEpochManagerSystem(); - uint256 beforeBalance = stableToken.balanceOf(address(epochManager)); epochManager.startNextEpochProcess(); assertEq(validators.mintedStable(), validator1Reward + validator2Reward); @@ -312,7 +311,6 @@ contract EpochManagerTest_startNextEpochProcess is EpochManagerTest { function test_ShouldReleaseCorrectAmountToReserve() public { initializeEpochManagerSystem(); - uint256 reserveBalanceBefore = celoToken.balanceOf(reserveAddress); epochManager.startNextEpochProcess(); uint256 reserveBalanceAfter = celoToken.balanceOf(reserveAddress); assertEq( @@ -687,18 +685,12 @@ contract EpochManagerTest_setToProcessGroups is EpochManagerTest { } function test_Reverts_WhenNotStarted() public { - address[] memory groups = new address[](0); - vm.expectRevert("Epoch process is not started"); epochManager.setToProcessGroups(); } function test_setsToProcessGroups() public { - ( - address[] memory groups, - address[] memory lessers, - address[] memory greaters - ) = getGroupsWithLessersAndGreaters(); + (address[] memory groups, , ) = getGroupsWithLessersAndGreaters(); epochManager.startNextEpochProcess(); epochManager.setToProcessGroups(); @@ -707,12 +699,7 @@ contract EpochManagerTest_setToProcessGroups is EpochManagerTest { } function test_setsGroupRewards() public { - ( - address[] memory groups, - address[] memory lessers, - address[] memory greaters - ) = getGroupsWithLessersAndGreaters(); - + (address[] memory groups, , ) = getGroupsWithLessersAndGreaters(); epochManager.startNextEpochProcess(); epochManager.setToProcessGroups(); @@ -779,12 +766,6 @@ contract EpochManagerTest_processGroup is EpochManagerTest { } function test_ProcessesGroup() public { - ( - address[] memory groups, - address[] memory lessers, - address[] memory greaters - ) = getGroupsWithLessersAndGreaters(); - epochManager.startNextEpochProcess(); epochManager.setToProcessGroups(); epochManager.processGroup(group, address(0), address(0)); @@ -794,12 +775,6 @@ contract EpochManagerTest_processGroup is EpochManagerTest { } function test_TransfersToCommunityAndCarbonOffsetting() public { - ( - address[] memory groups, - address[] memory lessers, - address[] memory greaters - ) = getGroupsWithLessersAndGreaters(); - epochManager.startNextEpochProcess(); epochManager.setToProcessGroups(); epochManager.processGroup(group, address(0), address(0)); @@ -809,12 +784,6 @@ contract EpochManagerTest_processGroup is EpochManagerTest { } function test_TransfersToValidatorGroup() public { - ( - address[] memory groups, - address[] memory lessers, - address[] memory greaters - ) = getGroupsWithLessersAndGreaters(); - epochManager.startNextEpochProcess(); epochManager.setToProcessGroups(); epochManager.processGroup(group, address(0), address(0)); @@ -869,12 +838,8 @@ contract EpochManagerTest_getEpochByNumber is EpochManagerTest { initializeEpochManagerSystem(); uint256 _startingEpochNumber = epochManager.getCurrentEpochNumber(); - ( - uint256 startingEpochFirstBlock, - uint256 startingEpochLastBlock, - uint256 startingEpochStartTimestamp, - uint256 startingEpochRewardBlock - ) = epochManager.getCurrentEpoch(); + (uint256 startingEpochFirstBlock, , uint256 startingEpochStartTimestamp, ) = epochManager + .getCurrentEpoch(); _travelAndProcess_N_L2Epoch(numberOfEpochsToTravel); @@ -925,7 +890,6 @@ contract EpochManagerTest_getEpochByNumber is EpochManagerTest { function test_ReturnsZeroForFutureEpochs() public { initializeEpochManagerSystem(); - address[] memory _expectedElected = new address[](0); ( uint256 _firstBlock, uint256 _lastBlock, @@ -958,12 +922,9 @@ contract EpochManagerTest_getEpochByBlockNumber is EpochManagerTest { _travelAndProcess_N_L2Epoch(2); - ( - uint256 _firstBlock, - uint256 _lastBlock, - uint256 _timestamp, - uint256 rewardsBlock - ) = epochManager.getEpochByBlockNumber(firstEpochBlock + (3 * L2_BLOCK_IN_EPOCH)); + (uint256 _firstBlock, uint256 _lastBlock, , ) = epochManager.getEpochByBlockNumber( + firstEpochBlock + (3 * L2_BLOCK_IN_EPOCH) + ); assertEq(_firstBlock, firstEpochBlock + 1 + (2 * L2_BLOCK_IN_EPOCH)); assertEq(_lastBlock, firstEpochBlock + 1 + (3 * L2_BLOCK_IN_EPOCH) - 1); } diff --git a/packages/protocol/test-sol/unit/common/FeeCurrencyWhitelist.t.sol b/packages/protocol/test-sol/unit/common/FeeCurrencyWhitelist.t.sol index 8f5d6a787a0..6dae11cb09f 100644 --- a/packages/protocol/test-sol/unit/common/FeeCurrencyWhitelist.t.sol +++ b/packages/protocol/test-sol/unit/common/FeeCurrencyWhitelist.t.sol @@ -4,7 +4,9 @@ pragma solidity ^0.5.13; import "celo-foundry/Test.sol"; import "@celo-contracts/common/FeeCurrencyWhitelist.sol"; -contract FeeCurrencyWhitelistTest is Test { +import { TestConstants } from "@test-sol/constants.sol"; + +contract FeeCurrencyWhitelistTest is Test, TestConstants { FeeCurrencyWhitelist feeCurrencyWhitelist; address nonOwner; address owner; @@ -16,6 +18,10 @@ contract FeeCurrencyWhitelistTest is Test { feeCurrencyWhitelist = new FeeCurrencyWhitelist(true); feeCurrencyWhitelist.initialize(); } + + function _whenL2() public { + deployCodeTo("Registry.sol", abi.encode(false), PROXY_ADMIN_ADDRESS); + } } contract FeeCurrencyWhitelistInitialize is FeeCurrencyWhitelistTest { @@ -43,6 +49,12 @@ contract FeeCurrencyWhitelistAddToken is FeeCurrencyWhitelistTest { vm.prank(nonOwner); feeCurrencyWhitelist.addToken(address(1)); } + + function test_Reverts_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + feeCurrencyWhitelist.addToken(address(1)); + } } contract FeeCurrencyWhitelistRemoveToken is FeeCurrencyWhitelistTest { @@ -71,4 +83,49 @@ contract FeeCurrencyWhitelistRemoveToken is FeeCurrencyWhitelistTest { vm.prank(nonOwner); feeCurrencyWhitelist.removeToken(address(2), 1); } + + function test_Reverts_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + feeCurrencyWhitelist.removeToken(address(2), 1); + } +} + +contract FeeCurrencyWhitelist_whitelist is FeeCurrencyWhitelistTest { + function setUp() public { + super.setUp(); + feeCurrencyWhitelist.addToken(address(1)); + } + + function test_ShouldRetrieveAToken() public { + address token = feeCurrencyWhitelist.whitelist(0); + assertEq(token, address(1)); + } + + function test_Reverts_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + feeCurrencyWhitelist.whitelist(0); + } +} + +contract FeeCurrencyWhitelist_getWhitelist is FeeCurrencyWhitelistTest { + function setUp() public { + super.setUp(); + feeCurrencyWhitelist.addToken(address(1)); + feeCurrencyWhitelist.addToken(address(2)); + } + + function test_ShouldRetrieveAToken() public { + address[] memory tokens = feeCurrencyWhitelist.getWhitelist(); + assertEq(tokens.length, 2); + assertEq(tokens[0], address(1)); + assertEq(tokens[1], address(2)); + } + + function test_Reverts_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + feeCurrencyWhitelist.getWhitelist(); + } } diff --git a/packages/protocol/test-sol/unit/common/FeeHandler.t.sol b/packages/protocol/test-sol/unit/common/FeeHandler.t.sol index bb735c29d08..582e9cd15a9 100644 --- a/packages/protocol/test-sol/unit/common/FeeHandler.t.sol +++ b/packages/protocol/test-sol/unit/common/FeeHandler.t.sol @@ -282,7 +282,7 @@ contract FeeHandlerTest_changeOtherBeneficiaryAllocation is FeeHandlerTest { function test_changedSucsesfully() public { feeHandler.changeOtherBeneficiaryAllocation(op, (30 * 1e24) / 100); - (uint256 fraction, string memory name, ) = feeHandler.getOtherBeneficiariesInfo(op); + (uint256 fraction, , ) = feeHandler.getOtherBeneficiariesInfo(op); assertEq(fraction, (30 * 1e24) / 100); } @@ -1158,7 +1158,7 @@ contract FeeHandlerTest_SetBeneficiaryFraction is FeeHandlerTestAbstract { function test_setFractionSucsesfully() public { feeHandler.setBeneficiaryFraction(op, (30 * 1e24) / 100); - (uint256 fraction, string memory name, ) = feeHandler.getOtherBeneficiariesInfo(op); + (uint256 fraction, , ) = feeHandler.getOtherBeneficiariesInfo(op); assertEq(fraction, (30 * 1e24) / 100); } @@ -1192,7 +1192,7 @@ contract FeeHandlerTest_SetBeneficiaryName is FeeHandlerTestAbstract { function test_setNameSucsesfully() public { feeHandler.setBeneficiaryName(op, "OP revenue share updated"); - (uint256 fraction, string memory name, ) = feeHandler.getOtherBeneficiariesInfo(op); + (, string memory name, ) = feeHandler.getOtherBeneficiariesInfo(op); assertEq(name, "OP revenue share updated"); } diff --git a/packages/protocol/test-sol/unit/common/GasPriceMinimum.t.sol b/packages/protocol/test-sol/unit/common/GasPriceMinimum.t.sol index 1836d170273..8a732e34bd1 100644 --- a/packages/protocol/test-sol/unit/common/GasPriceMinimum.t.sol +++ b/packages/protocol/test-sol/unit/common/GasPriceMinimum.t.sol @@ -199,7 +199,7 @@ contract GasPriceMinimumTest_setGasPriceMinimumFloor is GasPriceMinimumTest { } } -contract GasPriceMinimumTest_setUpdatedGasPriceMinimum is GasPriceMinimumTest { +contract GasPriceMinimumTest_getUpdatedGasPriceMinimum is GasPriceMinimumTest { using FixidityLib for FixidityLib.Fraction; uint256 nonce = 0; @@ -297,4 +297,95 @@ contract GasPriceMinimumTest_setUpdatedGasPriceMinimum is GasPriceMinimumTest { assertEq(actualUpdatedGasPriceMinimum, expectedUpdatedGasPriceMinimum); } } + + function test_shouldRevert_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + gasPriceMinimum.getUpdatedGasPriceMinimum(0, 1); + } +} + +contract GasPriceMinimumTest_gasPriceMinimumFloor is GasPriceMinimumTest { + function test_shouldReturnTheGasPriceMinimumFloor() public { + uint256 gasPriceMinFloor = gasPriceMinimum.gasPriceMinimumFloor(); + assertEq(gasPriceMinFloor, gasPriceMinimumFloor); + } + + function test_shouldRevert_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + gasPriceMinimum.gasPriceMinimumFloor(); + } +} + +contract GasPriceMinimumTest_targetDensity is GasPriceMinimumTest { + function test_shouldReturnTheTargetDensity() public { + uint256 realTargetDensity = gasPriceMinimum.targetDensity(); + assertEq(realTargetDensity, targetDensity); + } + + function test_shouldRevert_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + gasPriceMinimum.targetDensity(); + } +} + +contract GasPriceMinimumTest_adjustmentSpeed is GasPriceMinimumTest { + function test_shouldReturnTheAdjustementSpeed() public { + uint256 realAdjustementSpeed = gasPriceMinimum.adjustmentSpeed(); + assertEq(realAdjustementSpeed, adjustmentSpeed); + } + + function test_shouldRevert_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + gasPriceMinimum.adjustmentSpeed(); + } +} + +contract GasPriceMinimumTest_baseFeeOpCodeActivationBlock is GasPriceMinimumTest { + uint256 baseFeeOpCodeActivationBlock = 123; + + function setUp() public override { + super.setUp(); + gasPriceMinimum.setBaseFeeOpCodeActivationBlock(baseFeeOpCodeActivationBlock); + } + + function test_shouldReturnTheBaseFeeOpCodeActivationBlock() public { + uint256 realBaseFeeOpCodeActivationBlock = gasPriceMinimum.baseFeeOpCodeActivationBlock(); + assertEq(realBaseFeeOpCodeActivationBlock, baseFeeOpCodeActivationBlock); + } + + function test_shouldRevert_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + gasPriceMinimum.baseFeeOpCodeActivationBlock(); + } +} + +contract GasPriceMinimumTest_gasPriceMinimum is GasPriceMinimumTest { + function test_shouldReturnTheGasPriceMinimum() public { + uint256 realGasPriceMinimum = gasPriceMinimum.gasPriceMinimum(); + assertEq(realGasPriceMinimum, 100); + } + + function test_shouldRevert_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + gasPriceMinimum.gasPriceMinimum(); + } +} + +contract GasPriceMinimumTest_getGasPriceMinimum is GasPriceMinimumTest { + function test_shouldReturnTheGasPriceMinimum() public { + uint256 realGasPriceMinimum = gasPriceMinimum.getGasPriceMinimum(address(0)); + assertEq(realGasPriceMinimum, 100); + } + + function test_shouldRevert_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + gasPriceMinimum.getGasPriceMinimum(address(0)); + } } diff --git a/packages/protocol/test-sol/unit/common/GoldToken.t.sol b/packages/protocol/test-sol/unit/common/GoldToken.t.sol index a55358be7c6..5d2ab8f69ca 100644 --- a/packages/protocol/test-sol/unit/common/GoldToken.t.sol +++ b/packages/protocol/test-sol/unit/common/GoldToken.t.sol @@ -15,7 +15,7 @@ contract GoldTokenTest is Test, TestConstants, IsL2Check { address receiver; address sender; address celoTokenOwner; - address celoTokenDistributionSchedule; + address celoUnreleasedTreasuryAddress; event Transfer(address indexed from, address indexed to, uint256 value); event TransferComment(string comment); @@ -26,16 +26,17 @@ contract GoldTokenTest is Test, TestConstants, IsL2Check { } function setUp() public { + celoTokenOwner = actor("celoTokenOwner"); + celoUnreleasedTreasuryAddress = actor("celoUnreleasedTreasury"); deployCodeTo("Registry.sol", abi.encode(false), REGISTRY_ADDRESS); + deployCodeTo("CeloUnreleasedTreasury.sol", abi.encode(false), celoUnreleasedTreasuryAddress); registry = IRegistry(REGISTRY_ADDRESS); - celoTokenOwner = actor("celoTokenOwner"); - celoTokenDistributionSchedule = actor("celoTokenDistributionSchedule"); vm.prank(celoTokenOwner); celoToken = new GoldToken(true); vm.prank(celoTokenOwner); celoToken.setRegistry(REGISTRY_ADDRESS); - registry.setAddressFor("CeloUnreleasedTreasury", celoTokenDistributionSchedule); + registry.setAddressFor("CeloUnreleasedTreasury", celoUnreleasedTreasuryAddress); receiver = actor("receiver"); sender = actor("sender"); vm.deal(receiver, ONE_CELOTOKEN); @@ -126,6 +127,26 @@ contract GoldTokenTest_transfer is GoldTokenTest { vm.expectRevert(); celoToken.transfer(address(0), ONE_CELOTOKEN); } + + function test_Succeeds_whenTransferingToCeloUnreleasedTreasury() public { + vm.prank(sender); + uint256 balanceBefore = celoToken.balanceOf(celoUnreleasedTreasuryAddress); + + celoToken.transfer(celoUnreleasedTreasuryAddress, ONE_CELOTOKEN); + uint256 balanceAfter = celoToken.balanceOf(celoUnreleasedTreasuryAddress); + assertGt(balanceAfter, balanceBefore); + } + + function test_FailsWhenNativeTransferingToCeloUnreleasedTreasury() public payable { + (bool success, ) = address(uint160(celoUnreleasedTreasuryAddress)).call.value(ONE_CELOTOKEN)( + "" + ); + + assertFalse(success); + + bool sent = address(uint160(celoUnreleasedTreasuryAddress)).send(ONE_CELOTOKEN); + assertFalse(sent); + } } contract GoldTokenTest_transferFrom is GoldTokenTest { @@ -150,6 +171,14 @@ contract GoldTokenTest_transferFrom is GoldTokenTest { celoToken.transferFrom(sender, address(0), ONE_CELOTOKEN); } + function test_Succeeds_whenTransferingToCeloUnreleasedTreasury() public { + uint256 balanceBefore = celoToken.balanceOf(celoUnreleasedTreasuryAddress); + vm.prank(receiver); + celoToken.transferFrom(sender, celoUnreleasedTreasuryAddress, ONE_CELOTOKEN); + uint256 balanceAfter = celoToken.balanceOf(celoUnreleasedTreasuryAddress); + assertGt(balanceAfter, balanceBefore); + } + function test_Reverts_WhenTransferMoreThanSenderHas() public { uint256 value = sender.balance + ONE_CELOTOKEN * 4; @@ -198,7 +227,7 @@ contract GoldTokenTest_mint is GoldTokenTest { vm.expectRevert("Only VM can call"); celoToken.mint(receiver, ONE_CELOTOKEN); - vm.prank(celoTokenDistributionSchedule); + vm.prank(celoUnreleasedTreasuryAddress); vm.expectRevert("Only VM can call"); celoToken.mint(receiver, ONE_CELOTOKEN); } @@ -220,7 +249,7 @@ contract GoldTokenTest_mint is GoldTokenTest { function test_Reverts_whenL2() public _whenL2 { vm.expectRevert("This method is no longer supported in L2."); - vm.prank(celoTokenDistributionSchedule); + vm.prank(celoUnreleasedTreasuryAddress); celoToken.mint(receiver, ONE_CELOTOKEN); vm.expectRevert("This method is no longer supported in L2."); vm.prank(address(0)); @@ -249,23 +278,24 @@ contract CeloTokenMockTest is Test, TestConstants { GoldTokenMock mockCeloToken; uint256 ONE_CELOTOKEN = 1000000000000000000; address burnAddress = address(0x000000000000000000000000000000000000dEaD); - address celoUnreleasedTreasury; + address celoUnreleasedTreasuryAddress = actor("CeloUnreleasedTreasury"); modifier _whenL2() { deployCodeTo("Registry.sol", abi.encode(false), PROXY_ADMIN_ADDRESS); - vm.deal(celoUnreleasedTreasury, L2_INITIAL_STASH_BALANCE); + vm.deal(celoUnreleasedTreasuryAddress, L2_INITIAL_STASH_BALANCE); _; } function setUp() public { deployCodeTo("Registry.sol", abi.encode(false), REGISTRY_ADDRESS); + deployCodeTo("CeloUnreleasedTreasury.sol", abi.encode(false), celoUnreleasedTreasuryAddress); registry = IRegistry(REGISTRY_ADDRESS); mockCeloToken = new GoldTokenMock(); mockCeloToken.setRegistry(REGISTRY_ADDRESS); mockCeloToken.setTotalSupply(L1_MINTED_CELO_SUPPLY); - celoUnreleasedTreasury = actor("CeloUnreleasedTreasury"); - registry.setAddressFor("CeloUnreleasedTreasury", celoUnreleasedTreasury); + vm.deal(celoUnreleasedTreasuryAddress, L2_INITIAL_STASH_BALANCE); + registry.setAddressFor("CeloUnreleasedTreasury", celoUnreleasedTreasuryAddress); } } @@ -304,7 +334,7 @@ contract GoldTokenTest_AllocatedSupply is CeloTokenMockTest { } function test_ShouldReturn_WhenWithdrawn_WhenInL2() public _whenL2 { - deal(address(celoUnreleasedTreasury), ONE_CELOTOKEN); + deal(celoUnreleasedTreasuryAddress, ONE_CELOTOKEN); assertEq(mockCeloToken.allocatedSupply(), mockCeloToken.totalSupply() - ONE_CELOTOKEN); } } diff --git a/packages/protocol/test-sol/unit/common/Multisig.t.sol b/packages/protocol/test-sol/unit/common/Multisig.t.sol index 142f09d00d3..67322618c57 100644 --- a/packages/protocol/test-sol/unit/common/Multisig.t.sol +++ b/packages/protocol/test-sol/unit/common/Multisig.t.sol @@ -67,7 +67,8 @@ contract MultiSigTest_fallbackFunction is MultiSigTest { uint256 amount = 100; function uncheckedSendViaCall(address payable _to, uint256 _amount) public payable { - _to.call.value(_amount)(""); + (bool res, ) = _to.call.value(_amount)(""); + require(res, "call failed"); } function test_Emits_DepositEventWithCorrectParameters_whenReceivingCelo() public payable { diff --git a/packages/protocol/test-sol/unit/common/ProxyFactory08.t.sol b/packages/protocol/test-sol/unit/common/ProxyFactory08.t.sol index 3c03595be1d..c290e570b67 100644 --- a/packages/protocol/test-sol/unit/common/ProxyFactory08.t.sol +++ b/packages/protocol/test-sol/unit/common/ProxyFactory08.t.sol @@ -25,7 +25,7 @@ contract ProxyFactoryTest is Test, Utils08 { } function test_Reverts_WhenDeployingWithSameSenderAddressAndBytecode() public { - address deployedAddress = proxyFactory08.deployArbitraryByteCode(0, owner, 0, proxyInitCode); + proxyFactory08.deployArbitraryByteCode(0, owner, 0, proxyInitCode); vm.expectRevert("Create2: Failed on deploy"); proxyFactory08.deployArbitraryByteCode(0, owner, 0, proxyInitCode); } @@ -49,7 +49,7 @@ contract ProxyFactoryTest is Test, Utils08 { string memory compiler, bytes memory bytecode, string memory artifactPath - ) public { + ) public view { string memory bytecodeBackUp = vm.readFile(string.concat(artifactPath, compiler, ".hex")); string memory bytecodeString = vm.toString(bytecode); diff --git a/packages/protocol/test-sol/unit/common/ScoreManager.t.sol b/packages/protocol/test-sol/unit/common/ScoreManager.t.sol index be621b711b7..eccba616e3b 100644 --- a/packages/protocol/test-sol/unit/common/ScoreManager.t.sol +++ b/packages/protocol/test-sol/unit/common/ScoreManager.t.sol @@ -24,7 +24,7 @@ contract ScoreManagerTest is Test, TestConstants { event ValidatorScoreSet(address indexed validator, uint256 score); event ScoreManagerSetterSet(address indexed scoreManagerSetter); - uint256 constant ZERO_FIXED1_UINT = 1e24 + 1; + uint256 constant ZERO_SCORE = 1e24 + 1; function setUp() public virtual { owner = address(this); @@ -60,17 +60,17 @@ contract ScoreManagerTest_setGroupScore is ScoreManagerTest { scoreManager.setGroupScore(owner, 42); } - function test_Reverts_WhenSetToMoreThan1e24() public { - vm.expectRevert("Score must be less than or equal to 1e24 or ZERO_FIXED1_UINT."); - scoreManager.setGroupScore(owner, 1e24 + 2); + function test_Reverts_WhenSetToMoreThan1e24Plus1() public { + vm.expectRevert("Score must be less than or equal to 1e24."); + scoreManager.setGroupScore(owner, 1e24 + 1); } function test_Returns1FixidityWhenGroupScoreDoesNotExist() public { assertEq(scoreManager.getGroupScore(owner), 1e24); } - function test_Returns0WhenGroupScoreIsZero() public { - scoreManager.setGroupScore(owner, ZERO_FIXED1_UINT); + function test_Returns0WhenGroupScoreIsZERO_SCORE() public { + scoreManager.setGroupScore(owner, 0); assert(scoreManager.getGroupScore(owner) == 0); } @@ -102,12 +102,12 @@ contract ScoreManagerTest_setValidatorScore is ScoreManagerTest { } function test_Reverts_WhenSetToMoreThan1e24() public { - vm.expectRevert("Score must be less than or equal to 1e24 or ZERO_FIXED1_UINT."); - scoreManager.setValidatorScore(owner, 1e24 + 2); + vm.expectRevert("Score must be less than or equal to 1e24."); + scoreManager.setValidatorScore(owner, 1e24 + 1); } function test_Returns0WhenValidatorScoreIsZero() public { - scoreManager.setValidatorScore(owner, ZERO_FIXED1_UINT); + scoreManager.setValidatorScore(owner, 0); assert(scoreManager.getValidatorScore(owner) == 0); } diff --git a/packages/protocol/test-sol/unit/governance/mock/MockGovernance.sol b/packages/protocol/test-sol/unit/governance/mock/MockGovernance.sol index a54f4e4d23e..7718a9d9082 100644 --- a/packages/protocol/test-sol/unit/governance/mock/MockGovernance.sol +++ b/packages/protocol/test-sol/unit/governance/mock/MockGovernance.sol @@ -42,22 +42,16 @@ contract MockGovernance is IGovernance { removeVotesCalledFor[account] = maxAmountAllowed; } - function setConstitution(address destination, bytes4 functionId, uint256 threshold) external { + function setConstitution(address, bytes4, uint256) external { revert("not implemented"); } - function votePartially( - uint256 proposalId, - uint256 index, - uint256 yesVotes, - uint256 noVotes, - uint256 abstainVotes - ) external returns (bool) { + function votePartially(uint256, uint256, uint256, uint256, uint256) external returns (bool) { return true; } function getProposal( - uint256 proposalId + uint256 ) external view returns (address, uint256, uint256, uint256, string memory, uint256, bool) { return (address(0), 0, 0, 0, "", 0, false); } @@ -66,7 +60,7 @@ contract MockGovernance is IGovernance { return totalVotes[account]; } - function getReferendumStageDuration() external view returns (uint256) { + function getReferendumStageDuration() external pure returns (uint256) { return 0; } } diff --git a/packages/protocol/test-sol/unit/governance/network/BlockchainParameters.t.sol b/packages/protocol/test-sol/unit/governance/network/BlockchainParameters.t.sol index 45e95e13b5d..b3e507b0e31 100644 --- a/packages/protocol/test-sol/unit/governance/network/BlockchainParameters.t.sol +++ b/packages/protocol/test-sol/unit/governance/network/BlockchainParameters.t.sol @@ -173,3 +173,21 @@ contract BlockchainParametersTest_setUptimeLookbackWindow is BlockchainParameter blockchainParameters.setUptimeLookbackWindow(100); } } + +contract BlockchainParametersTest_blockGasLimit is BlockchainParametersTest { + function test_Reverts_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + blockchainParameters.blockGasLimit(); + } +} + +contract BlockchainParametersTest_intrinsicGasForAlternativeFeeCurrency is + BlockchainParametersTest +{ + function test_Reverts_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + blockchainParameters.intrinsicGasForAlternativeFeeCurrency(); + } +} diff --git a/packages/protocol/test-sol/unit/governance/network/Governance.t.sol b/packages/protocol/test-sol/unit/governance/network/Governance.t.sol index 65f0393cc05..8e38ad54d40 100644 --- a/packages/protocol/test-sol/unit/governance/network/Governance.t.sol +++ b/packages/protocol/test-sol/unit/governance/network/Governance.t.sol @@ -145,7 +145,7 @@ contract GovernanceTest is Test, TestConstants, Utils { } } - function makeValidProposal() internal returns (uint256 proposalId) { + function makeValidProposal() internal returns (uint256) { return governance.propose.value(DEPOSIT)( okProp.values, @@ -156,7 +156,7 @@ contract GovernanceTest is Test, TestConstants, Utils { ); } - function makeEmptyProposal() internal returns (uint256 proposalId) { + function makeEmptyProposal() internal returns (uint256) { Proposal memory emptyProposal; return governance.propose.value(DEPOSIT)( @@ -584,12 +584,7 @@ contract GovernanceTest_setParticipationFloor is GovernanceTest { function test_SetsValue() public { vm.prank(accOwner); governance.setParticipationFloor(NEW_VALUE); - ( - uint256 baseline, - uint256 baselineFloor, - uint256 _baselineUpdateFactor, - uint256 _baselineQuorumFactor - ) = governance.getParticipationParameters(); + (, uint256 baselineFloor, , ) = governance.getParticipationParameters(); assertEq(baselineFloor, NEW_VALUE); } @@ -619,12 +614,7 @@ contract GovernanceTest_setBaselineUpdateFactor is GovernanceTest { function test_SetsValue() public { vm.prank(accOwner); governance.setBaselineUpdateFactor(NEW_VALUE); - ( - uint256 baseline, - uint256 baselineFloor, - uint256 _baselineUpdateFactor, - uint256 _baselineQuorumFactor - ) = governance.getParticipationParameters(); + (, , uint256 _baselineUpdateFactor, ) = governance.getParticipationParameters(); assertEq(_baselineUpdateFactor, NEW_VALUE); } @@ -654,12 +644,7 @@ contract GovernanceTest_setBaselineQuorumFactor is GovernanceTest { function test_SetsValue() public { vm.prank(accOwner); governance.setBaselineQuorumFactor(NEW_VALUE); - ( - uint256 baseline, - uint256 baselineFloor, - uint256 _baselineUpdateFactor, - uint256 _baselineQuorumFactor - ) = governance.getParticipationParameters(); + (, , , uint256 _baselineQuorumFactor) = governance.getParticipationParameters(); assertEq(_baselineQuorumFactor, NEW_VALUE); } @@ -1288,7 +1273,6 @@ contract GovernanceTest_revokeUpvote is GovernanceTest { function test_markAccountAsNotHavingUpvoted_whenMoreThanDequeueFrequencySinceLastDequeue() public { - uint256 originalLastDequeue = governance.lastDequeue(); vm.warp(block.timestamp + governance.dequeueFrequency()); governance.revokeUpvote(0, 0); (uint256 recordId, uint256 recordWeight) = governance.getUpvoteRecord(accVoter); @@ -1758,7 +1742,7 @@ contract GovernanceTest_vote_WhenProposalIsApproved is GovernanceTest { vm.startPrank(accVoter); governance.vote(proposalId, 0, Proposals.VoteValue.Yes); governance.vote(proposalId, 0, Proposals.VoteValue.No); - (uint256 yes, uint256 no, uint256 abstain) = governance.getVoteTotals(proposalId); + (uint256 yes, uint256 no, ) = governance.getVoteTotals(proposalId); assertEq(yes, 0); assertEq(no, VOTER_GOLD); } @@ -1767,8 +1751,7 @@ contract GovernanceTest_vote_WhenProposalIsApproved is GovernanceTest { vm.startPrank(accVoter); governance.vote(proposalId, 0, Proposals.VoteValue.Yes); governance.vote(proposalId, 0, Proposals.VoteValue.No); - (uint256 id, uint256 _1, uint256 _2, uint256 yes, uint256 no, uint256 abstain) = governance - .getVoteRecord(accVoter, 0); + (uint256 id, , , uint256 yes, uint256 no, ) = governance.getVoteRecord(accVoter, 0); assertEq(id, proposalId); assertEq(yes, 0); assertEq(no, VOTER_GOLD); @@ -1778,7 +1761,7 @@ contract GovernanceTest_vote_WhenProposalIsApproved is GovernanceTest { vm.startPrank(accVoter); governance.vote(proposalId, 0, Proposals.VoteValue.No); governance.vote(proposalId, 0, Proposals.VoteValue.Abstain); - (uint256 yes, uint256 no, uint256 abstain) = governance.getVoteTotals(proposalId); + (, uint256 no, uint256 abstain) = governance.getVoteTotals(proposalId); assertEq(no, 0); assertEq(abstain, VOTER_GOLD); } @@ -1787,8 +1770,7 @@ contract GovernanceTest_vote_WhenProposalIsApproved is GovernanceTest { vm.startPrank(accVoter); governance.vote(proposalId, 0, Proposals.VoteValue.No); governance.vote(proposalId, 0, Proposals.VoteValue.Abstain); - (uint256 id, uint256 _1, uint256 _2, uint256 yes, uint256 no, uint256 abstain) = governance - .getVoteRecord(accVoter, 0); + (uint256 id, , , , uint256 no, uint256 abstain) = governance.getVoteRecord(accVoter, 0); assertEq(id, proposalId); assertEq(no, 0); assertEq(abstain, VOTER_GOLD); @@ -1798,7 +1780,7 @@ contract GovernanceTest_vote_WhenProposalIsApproved is GovernanceTest { vm.startPrank(accVoter); governance.vote(proposalId, 0, Proposals.VoteValue.Abstain); governance.vote(proposalId, 0, Proposals.VoteValue.Yes); - (uint256 yes, uint256 no, uint256 abstain) = governance.getVoteTotals(proposalId); + (uint256 yes, , uint256 abstain) = governance.getVoteTotals(proposalId); assertEq(abstain, 0); assertEq(yes, VOTER_GOLD); } @@ -1807,8 +1789,7 @@ contract GovernanceTest_vote_WhenProposalIsApproved is GovernanceTest { vm.startPrank(accVoter); governance.vote(proposalId, 0, Proposals.VoteValue.Abstain); governance.vote(proposalId, 0, Proposals.VoteValue.Yes); - (uint256 id, uint256 _1, uint256 _2, uint256 yes, uint256 no, uint256 abstain) = governance - .getVoteRecord(accVoter, 0); + (uint256 id, , , uint256 yes, , uint256 abstain) = governance.getVoteRecord(accVoter, 0); assertEq(id, proposalId); assertEq(abstain, 0); assertEq(yes, VOTER_GOLD); @@ -2241,8 +2222,10 @@ contract GovernanceTest_vote_PartiallyWhenProposalIsApproved is GovernanceTest { vm.startPrank(accVoter); governance.votePartially(proposalId, 0, 10, 50, 30); governance.votePartially(proposalId, 0, 30, 20, 40); - (uint256 id, uint256 _1, uint256 _2, uint256 yes, uint256 no, uint256 abstain) = governance - .getVoteRecord(accVoter, 0); + (uint256 id, , , uint256 yes, uint256 no, uint256 abstain) = governance.getVoteRecord( + accVoter, + 0 + ); assertEq(id, proposalId); assertEq(yes, 30); assertEq(no, 20); diff --git a/packages/protocol/test-sol/unit/governance/validators/Validators.t.sol b/packages/protocol/test-sol/unit/governance/validators/Validators.t.sol index 39fda7734b6..6d7f8f57b1d 100644 --- a/packages/protocol/test-sol/unit/governance/validators/Validators.t.sol +++ b/packages/protocol/test-sol/unit/governance/validators/Validators.t.sol @@ -175,7 +175,6 @@ contract ValidatorsTest is Test, TestConstants, Utils, ECDSAHelper { lockedGold = new MockLockedGold(); election = new MockElection(); address validatorsAddress = actor("Validators"); - address validatorsMockFactoryAddress = actor("validatorsMockFactory"); deployCodeTo("ValidatorsMock.sol", validatorsAddress); validators = IValidators(validatorsAddress); diff --git a/packages/protocol/test-sol/unit/governance/validators/mocks/CompileValidatorIntegrationMock.t.sol b/packages/protocol/test-sol/unit/governance/validators/mocks/CompileValidatorIntegrationMock.t.sol index e7ce8a53559..46209af1d95 100644 --- a/packages/protocol/test-sol/unit/governance/validators/mocks/CompileValidatorIntegrationMock.t.sol +++ b/packages/protocol/test-sol/unit/governance/validators/mocks/CompileValidatorIntegrationMock.t.sol @@ -8,7 +8,7 @@ import "forge-std/console.sol"; import "@test-sol/unit/governance/validators/mocks/ValidatorsMock.sol"; contract CompileValidatorIntegrationMock is Test { - function test_nop() public { + function test_nop() public view { console.log("nop"); } } diff --git a/packages/protocol/test-sol/unit/governance/validators/mocks/ValidatorsMock.sol b/packages/protocol/test-sol/unit/governance/validators/mocks/ValidatorsMock.sol index 4550cd02fd4..55470bc89c4 100644 --- a/packages/protocol/test-sol/unit/governance/validators/mocks/ValidatorsMock.sol +++ b/packages/protocol/test-sol/unit/governance/validators/mocks/ValidatorsMock.sol @@ -8,11 +8,7 @@ import "@celo-contracts/common/FixidityLib.sol"; * @title A wrapper around Validators that exposes onlyVm functions for testing. */ contract ValidatorsMock is Validators(true) { - function computeEpochReward( - address account, - uint256 score, - uint256 maxPayment - ) external view override returns (uint256) { + function computeEpochReward(address, uint256, uint256) external pure override returns (uint256) { return 1; } } diff --git a/packages/protocol/test-sol/unit/governance/voting/ReleaseGold.t.sol b/packages/protocol/test-sol/unit/governance/voting/ReleaseGold.t.sol index f5aae08777c..52f94f72f01 100644 --- a/packages/protocol/test-sol/unit/governance/voting/ReleaseGold.t.sol +++ b/packages/protocol/test-sol/unit/governance/voting/ReleaseGold.t.sol @@ -846,7 +846,7 @@ contract ReleaseGoldTest_AuthorizationTests is ReleaseGoldTest { } function test_ShouldRevertIfTheSignatureIsIncorrect() public { - (address otherAccount, uint256 otherAccountPK) = actorWithPK("otherAccount"); + (, uint256 otherAccountPK) = actorWithPK("otherAccount"); (uint8 otherV, bytes32 otherR, bytes32 otherS) = getParsedSignatureOfAddress( address(releaseGold), otherAccountPK @@ -1039,7 +1039,7 @@ contract ReleaseGoldTest_AuthorizeWithPublicKeys is ReleaseGoldTest { bytes ecdsaPublicKey; - function _randomBytes32() internal returns (bytes32) { + function _randomBytes32() internal view returns (bytes32) { return keccak256(abi.encodePacked(block.timestamp, block.difficulty, msg.sender)); } diff --git a/packages/protocol/test-sol/unit/identity/Random.t.sol b/packages/protocol/test-sol/unit/identity/Random.t.sol index 6d72c5cc406..dba2ec9744a 100644 --- a/packages/protocol/test-sol/unit/identity/Random.t.sol +++ b/packages/protocol/test-sol/unit/identity/Random.t.sol @@ -8,16 +8,26 @@ import { TestConstants } from "@test-sol/constants.sol"; import "@celo-contracts/identity/Random.sol"; import "@celo-contracts/identity/test/RandomTest.sol"; -contract RandomnessTest_SetRandomnessRetentionWindow is Test, TestConstants, IsL2Check { - event RandomnessBlockRetentionWindowSet(uint256 value); - +contract RandomTest_ is Test, TestConstants, Utils, IsL2Check { RandomTest random; + event RandomnessBlockRetentionWindowSet(uint256 value); + function setUp() public { random = new RandomTest(); random.initialize(256); } + function commitmentFor(uint256 value) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(bytes32(value))); + } + + function _whenL2() public { + deployCodeTo("Registry.sol", abi.encode(false), PROXY_ADMIN_ADDRESS); + } +} + +contract RandomTest_SetRandomnessRetentionWindow is RandomTest_ { function test_ShouldSetTheVariable() public { random.setRandomnessBlockRetentionWindow(1000); assertEq(random.randomnessBlockRetentionWindow(), 1000); @@ -36,23 +46,16 @@ contract RandomnessTest_SetRandomnessRetentionWindow is Test, TestConstants, IsL } function test_Reverts_WhenCalledOnL2() public { - deployCodeTo("Registry.sol", abi.encode(false), PROXY_ADMIN_ADDRESS); + _whenL2(); vm.expectRevert("This method is no longer supported in L2."); random.setRandomnessBlockRetentionWindow(1000); } } -contract RandomnessTest_AddTestRandomness is Test, TestConstants, Utils, IsL2Check { +contract RandomTest_AddTestRandomness is RandomTest_ { uint256 constant RETENTION_WINDOW = 5; uint256 constant EPOCH_SIZE = 10; - RandomTest random; - - function setUp() public { - random = new RandomTest(); - random.initialize(256); - } - function test_ShouldBeAbleToSimulateAddingRandomness() public { random.addTestRandomness(1, 0x0000000000000000000000000000000000000000000000000000000000000001); random.addTestRandomness(2, 0x0000000000000000000000000000000000000000000000000000000000000002); @@ -217,7 +220,7 @@ contract RandomnessTest_AddTestRandomness is Test, TestConstants, Utils, IsL2Che } function test_Reverts_WhenCalledOnL2() public { - deployCodeTo("Registry.sol", abi.encode(false), PROXY_ADMIN_ADDRESS); + _whenL2(); vm.expectRevert("This method is no longer supported in L2."); random.addTestRandomness(1, 0x0000000000000000000000000000000000000000000000000000000000000001); vm.expectRevert("This method is no longer supported in L2."); @@ -225,22 +228,15 @@ contract RandomnessTest_AddTestRandomness is Test, TestConstants, Utils, IsL2Che } } -contract RandomnessTest_RevealAndCommit is Test, TestConstants, Utils, IsL2Check { +contract RandomTest_RevealAndCommit is RandomTest_ { address constant ACCOUNT = address(0x01); bytes32 constant RANDONMESS = bytes32(uint256(0x00)); - RandomTest random; - function setUp() public { - random = new RandomTest(); - random.initialize(256); + super.setUp(); random.setRandomnessBlockRetentionWindow(256); } - function commitmentFor(uint256 value) private pure returns (bytes32) { - return keccak256(abi.encodePacked(bytes32(value))); - } - function testRevert_CannotAddZeroCommitment() public { vm.expectRevert("cannot commit zero randomness"); random.testRevealAndCommit(RANDONMESS, commitmentFor(0x00), ACCOUNT); @@ -263,9 +259,50 @@ contract RandomnessTest_RevealAndCommit is Test, TestConstants, Utils, IsL2Check } function test_Reverts_WhenCalledOnL2() public { - deployCodeTo("Registry.sol", abi.encode(false), PROXY_ADMIN_ADDRESS); + _whenL2(); vm.expectRevert("This method is no longer supported in L2."); blockTravel(2); random.testRevealAndCommit(RANDONMESS, commitmentFor(0x01), ACCOUNT); } } + +contract RandomTest_Commitments is RandomTest_ { + address constant ACCOUNT = address(0x01); + bytes32 constant RANDONMESS = bytes32(uint256(0x00)); + uint256 randomness2 = 0x01; + bytes32 commitment2 = commitmentFor(randomness2); + + function setUp() public { + super.setUp(); + random.testRevealAndCommit(RANDONMESS, commitment2, ACCOUNT); + } + + function test_returnsACommtiment() public { + bytes32 commitment = random.commitments(ACCOUNT); + assertEq(commitment, commitment2); + } + + function test_Reverts_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + random.commitments(ACCOUNT); + } +} + +contract RandomTest_RandomnessBlockRetentionWindow is RandomTest_ { + function setUp() public { + super.setUp(); + random.setRandomnessBlockRetentionWindow(256); + } + + function test_getsTheRandomnessBlockRetentionWindow() public { + uint256 randomnessBlockRetentionWindow = random.randomnessBlockRetentionWindow(); + assertEq(randomnessBlockRetentionWindow, 256); + } + + function test_Reverts_WhenCalledOnL2() public { + _whenL2(); + vm.expectRevert("This method is no longer supported in L2."); + random.randomnessBlockRetentionWindow(); + } +} diff --git a/packages/protocol/test-sol/unit/stability/FeeCurrencyAdapter.t.sol b/packages/protocol/test-sol/unit/stability/FeeCurrencyAdapter.t.sol index 44a754e231c..efddc2c0815 100644 --- a/packages/protocol/test-sol/unit/stability/FeeCurrencyAdapter.t.sol +++ b/packages/protocol/test-sol/unit/stability/FeeCurrencyAdapter.t.sol @@ -106,13 +106,7 @@ contract FeeCurrencyAdapterTest is Test { feeCurrencyAdapter = new CeloFeeCurrencyAdapterTestContract(true); feeCurrencyAdapterForFuzzyTests = new CeloFeeCurrencyAdapterTestContract(true); - address feeCurrencyAddress = actor("feeCurrency"); - - string memory name = "tokenName"; - string memory symbol = "tN"; - feeCurrency = new FeeCurrency6DecimalsTest(initialSupply); - feeCurrencyAdapter.initialize(address(feeCurrency), "wrapper", "wr", 18); } }