Skip to content

Commit

Permalink
Merge branch 'martinvol/AddOraclesToFeeHandlersSellers' of github.com…
Browse files Browse the repository at this point in the history
…:celo-org/celo-monorepo into martinvol/AddOraclesToFeeHandlersSellers
  • Loading branch information
martinvol committed Oct 16, 2024
2 parents d990645 + 9e00dc4 commit 21138ba
Show file tree
Hide file tree
Showing 72 changed files with 845 additions and 393 deletions.
44 changes: 39 additions & 5 deletions packages/protocol/contracts-0.8/common/CeloUnreleasedTreasury.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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);
Expand All @@ -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.
Expand Down
24 changes: 18 additions & 6 deletions packages/protocol/contracts-0.8/common/EpochManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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),
Expand All @@ -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");
_;
Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down
10 changes: 8 additions & 2 deletions packages/protocol/contracts-0.8/common/EpochManagerEnabler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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.
Expand Down Expand Up @@ -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)
);
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
99 changes: 73 additions & 26 deletions packages/protocol/contracts-0.8/common/GasPriceMinimum.sol
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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);
Expand All @@ -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.
Expand Down Expand Up @@ -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);
}
/**
Expand All @@ -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);
}

/**
Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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;
Expand All @@ -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;
}

/**
Expand All @@ -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);
}

Expand Down
Loading

0 comments on commit 21138ba

Please sign in to comment.