Skip to content
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
f12106e
wip
0xClandestine Dec 16, 2025
196d782
test
0xClandestine Dec 16, 2025
bdb91cc
gap
0xClandestine Dec 16, 2025
9eafb1b
fix epoch calc
0xClandestine Dec 17, 2025
500eb8d
docs
0xClandestine Dec 17, 2025
f4ad933
rebase fixes
0xClandestine Dec 17, 2025
b80bdfd
fmt
0xClandestine Dec 17, 2025
94bbff3
wip
0xClandestine Dec 17, 2025
4720207
add mocks
0xClandestine Dec 17, 2025
538f1c9
update constructor
0xClandestine Dec 17, 2025
025a741
passing
0xClandestine Dec 17, 2025
4b27fe8
passing
0xClandestine Dec 17, 2025
864fe16
test
0xClandestine Dec 17, 2025
70b03b6
passing
0xClandestine Dec 17, 2025
a366b4c
wip
0xClandestine Dec 18, 2025
d07b578
wip
0xClandestine Dec 18, 2025
647e5da
wip
0xClandestine Dec 19, 2025
ebe098c
wip
0xClandestine Dec 19, 2025
5ac71f5
typo
0xClandestine Dec 19, 2025
78b8659
missing accounting
0xClandestine Dec 19, 2025
6eb0106
test
0xClandestine Dec 19, 2025
a0096d2
fix deny_warnings
0xClandestine Dec 19, 2025
b7b9680
wip
0xClandestine Dec 19, 2025
cb98b00
rename
0xClandestine Dec 19, 2025
c7ffd46
fmt
0xClandestine Dec 19, 2025
1804c3e
todo
0xClandestine Dec 19, 2025
fba7fd1
passing
0xClandestine Dec 19, 2025
812cbef
wip
0xClandestine Dec 22, 2025
fa6de9d
wip
0xClandestine Dec 22, 2025
9ebc04b
wip
0xClandestine Dec 22, 2025
cbc9bfa
docs
0xClandestine Dec 22, 2025
51a6179
wip
0xClandestine Dec 22, 2025
fa055ce
fixes
0xClandestine Dec 22, 2025
e8a8701
fix
0xClandestine Dec 22, 2025
8c0ae9d
fix
0xClandestine Dec 22, 2025
0acec59
fixes
0xClandestine Dec 22, 2025
56a5a19
docs
0xClandestine Dec 22, 2025
64bf038
optimize
0xClandestine Dec 22, 2025
d9c9d3b
cleanup
0xClandestine Dec 22, 2025
67a6482
passing
0xClandestine Jan 5, 2026
28963df
review
0xClandestine Jan 5, 2026
7f05baf
flakey test
0xClandestine Jan 7, 2026
b2c392b
review
0xClandestine Jan 7, 2026
615c4cc
fix: total weight check
0xClandestine Jan 7, 2026
b0a9d70
gap
0xClandestine Jan 7, 2026
a2e1d98
add event
0xClandestine Jan 7, 2026
1716838
fix
0xClandestine Jan 7, 2026
2c68008
regression test
0xClandestine Jan 7, 2026
f5e2258
remove disableDistribution, use update instead to disable + reenable
0xClandestine Jan 7, 2026
de09d42
update denominator
0xClandestine Jan 7, 2026
435d395
validate operator sets
0xClandestine Jan 8, 2026
dfe2f71
passing
0xClandestine Jan 8, 2026
403dd40
passing
0xClandestine Jan 8, 2026
71e5a82
prevent button press/mints before epoch 0
0xClandestine Jan 8, 2026
d9805dc
pending weight accounting
0xClandestine Jan 8, 2026
900ca73
more coverage
0xClandestine Jan 8, 2026
3ab690e
remove pending total weight in favor or restricting adds/updates unti…
0xClandestine Jan 8, 2026
1a6e455
stopEpoch -> totalEpochs
0xClandestine Jan 9, 2026
90fe467
prevent reverts when processing
0xClandestine Jan 9, 2026
9be8bdd
unused error
0xClandestine Jan 9, 2026
ee43371
setup check
0xClandestine Jan 9, 2026
a3d26bd
use require statements
0xClandestine Jan 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
# Specifies the exact version of Solidity to use, overriding auto-detection.
solc_version = '0.8.30'
# If enabled, treats Solidity compiler warnings as errors, preventing artifact generation if warnings are present.
deny_warnings = true
deny = "warnings"
# If set to true, changes compilation pipeline to go through the new IR optimizer.
via_ir = false
# Whether or not to enable the Solidity optimizer.
Expand Down
444 changes: 444 additions & 0 deletions src/contracts/core/EmissionsController.sol
Comment thread
elhajin marked this conversation as resolved.

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions src/contracts/core/storage/EmissionsControllerStorage.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import "../../interfaces/IEmissionsController.sol";
import "../../interfaces/IRewardsCoordinator.sol";

abstract contract EmissionsControllerStorage is IEmissionsController {
// Constants

/// @inheritdoc IEmissionsController
uint256 public constant MAX_TOTAL_WEIGHT = 10_000;

/// @dev Index for flag that pauses pressing the button when set.
uint8 internal constant PAUSED_TOKEN_FLOWS = 0;

// Immutables

/// @dev The EIGEN token that will be minted for emissions.
IEigen public immutable override EIGEN;
/// @dev The backing Eigen token that will be minted for emissions.
IBackingEigen public immutable override BACKING_EIGEN;
Comment thread
0xClandestine marked this conversation as resolved.
/// @dev The AllocationManager contract for managing operator sets.
IAllocationManager public immutable override ALLOCATION_MANAGER;
/// @dev The RewardsCoordinator contract for submitting rewards.
IRewardsCoordinator public immutable override REWARDS_COORDINATOR;

/// @inheritdoc IEmissionsController
uint256 public immutable EMISSIONS_INFLATION_RATE;
/// @inheritdoc IEmissionsController
uint256 public immutable EMISSIONS_START_TIME;
/// @inheritdoc IEmissionsController
uint256 public immutable EMISSIONS_EPOCH_LENGTH;

// Mutatables

// Slot 0 (Packed)

/// @inheritdoc IEmissionsController
address public incentiveCouncil;
/// @inheritdoc IEmissionsController
uint16 public totalWeight;

/// @dev Returns an append-only array of distributions.
Distribution[] internal _distributions;
/// @dev Mapping from epoch number to epoch metadata.
mapping(uint256 epoch => Epoch) internal _epochs;

// Construction

constructor(
IEigen eigen,
IBackingEigen backingEigen,
IAllocationManager allocationManager,
IRewardsCoordinator rewardsCoordinator,
uint256 inflationRate,
uint256 startTime,
uint256 epochLength
) {
EIGEN = eigen;
BACKING_EIGEN = backingEigen;
ALLOCATION_MANAGER = allocationManager;
REWARDS_COORDINATOR = rewardsCoordinator;

EMISSIONS_INFLATION_RATE = inflationRate;
EMISSIONS_START_TIME = startTime;
EMISSIONS_EPOCH_LENGTH = epochLength;
Comment thread
elhajin marked this conversation as resolved.
}

/// @dev This empty reserved space is put in place to allow future versions to add new
/// variables without shifting down storage in the inheritance chain.
/// See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
uint256[47] private __gap;
}
223 changes: 166 additions & 57 deletions src/contracts/interfaces/IEmissionsController.sol

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/test/mocks/BackingEigenMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.9;

import "forge-std/Test.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract BackingEigenMock is Test, ERC20 {
constructor() ERC20("Backing EIGEN", "bEIGEN") {}

function mint(address to, uint amount) external {
_mint(to, amount);
}
}

19 changes: 19 additions & 0 deletions src/test/mocks/EigenMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.9;

import "forge-std/Test.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./BackingEigenMock.sol";

contract EigenMock is Test, ERC20 {
BackingEigenMock backingEigen;

constructor(BackingEigenMock _backingEigen) ERC20("EIGEN", "EIGEN") {
backingEigen = _backingEigen;
}

function wrap(uint amount) external {
backingEigen.transferFrom(msg.sender, address(this), amount);
_mint(msg.sender, amount);
}
}
20 changes: 20 additions & 0 deletions src/test/mocks/RewardsCoordinatorMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.9;

import "forge-std/Test.sol";
import "../../contracts/interfaces/IRewardsCoordinator.sol";

contract RewardsCoordinatorMock is Test {
function createRewardsForAllEarners(IRewardsCoordinatorTypes.RewardsSubmission[] calldata) external {
// Mock implementation - does nothing for testing
}

function createUniqueStakeRewardsSubmission(OperatorSet calldata, IRewardsCoordinatorTypes.RewardsSubmission[] calldata) external {
// Mock implementation - does nothing for testing
}

function createTotalStakeRewardsSubmission(OperatorSet calldata, IRewardsCoordinatorTypes.RewardsSubmission[] calldata) external {
// Mock implementation - does nothing for testing
}
}

2 changes: 1 addition & 1 deletion src/test/unit/ECDSACertificateVerifierUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ contract ECDSACertificateVerifierUnitTests_verifyCertificate is ECDSACertificate

// Verification should fail - expect SignersNotOrdered because signature recovery
// with wrong message hash produces different addresses that break ordering
vm.expectRevert(IECDSACertificateVerifierErrors.SignersNotOrdered.selector);
vm.expectRevert(); // SignersNotOrdered or VerificationFailed
verifier.verifyCertificate(defaultOperatorSet, cert);
}

Expand Down
Loading