Skip to content

Commit 84456db

Browse files
committed
feat: merge slashing branch from upstream
2 parents c0863c3 + 865b490 commit 84456db

File tree

121 files changed

+6140
-2462
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+6140
-2462
lines changed

.github/workflows/tests.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ on:
1313
- dev
1414
pull_request:
1515

16-
env:
17-
FOUNDRY_PROFILE: ci
18-
1916
jobs:
2017
check:
2118
strategy:

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ EigenLayer is a set of smart contracts deployed on Ethereum that enable restakin
1515
## Branching
1616

1717
The main branches we use are:
18+
1819
* [`dev (default)`](https://github.com/Layr-Labs/eigenlayer-middleware/tree/dev): The most up-to-date branch, containing the work-in-progress code for upcoming releases
1920
* [`testnet-holesky`](https://github.com/Layr-Labs/eigenlayer-middleware/tree/testnet-holesky): Our current testnet deployment
2021
* [`mainnet`](https://github.com/Layr-Labs/eigenlayer-middleware/tree/mainnet): Our current mainnet deployment
@@ -24,6 +25,7 @@ The main branches we use are:
2425
### Basics
2526

2627
To get a basic understanding of EigenLayer, check out [You Could've Invented EigenLayer](https://www.blog.eigenlayer.xyz/ycie/). Note that some of the document's content describes features that do not exist yet (like the Slasher). To understand more about how restakers and operators interact with EigenLayer, check out these guides:
28+
2729
* [Restaking User Guide](https://docs.eigenlayer.xyz/restaking-guides/restaking-user-guide)
2830
* [Operator Guide](https://docs.eigenlayer.xyz/operator-guides/operator-introduction)
2931

@@ -32,10 +34,25 @@ Most of this content is intro-level and describes user interactions with the Eig
3234
### Deep Dive
3335

3436
For shadowy super-coders:
37+
3538
* The most up-to-date technical documentation can be found in [/docs](/docs).
3639
* To get an idea of how users interact with these contracts, check out the integration tests: [/test/integration](./test/integration)
3740
* To explore the EigenLayer core contracts, check out the core repo technical docs [here][core-docs-dev].
3841

42+
### Note On Slashing
43+
44+
The middleware contracts are available for testnet integration and experimentation. As with the rest of the testnet code, these contracts have not yet been fully audited. Internal security reviews are in progress, and we're preparing to engage external auditors. We're providing these now so AVSs can begin testing slashing conditions, Operator Sets, and related functionality, and so Operators can simulate slashing and test allocations. For more details, see [ELIP-002](https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-002.md).
45+
46+
For Operators:
47+
48+
We provide scripts to deploy a mock service manager and allocate some stake to a mock Operator Set in [these scripts](https://github.com/Layr-Labs/eigenlayer-middleware/pull/335).
49+
We've reduced various safety delays on testnet to better simulate operational flows. Additional information on these delays is in [ELIP-002](https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-002.md).
50+
For AVSs:
51+
52+
We provide a migration path for existing M2 environments (LINK). While this requires understanding the provided script, the Developer Experience will improve before Mainnet launch. Note that this is a gradual migration process to new Operator Sets, not a direct upgrade of existing Operator Sets.
53+
We also provide scripts to spin up new service managers from scratch.
54+
In all cases, you’ll need to register existing Operators or spin up new Operators and allocate funds to them. These testing flows will improve as we refine the scripts and contracts. Stay tuned for updates, and feel free to reach out with any questions.
55+
3956
## Building and Running Tests
4057

4158
This repository uses Foundry. See the [Foundry docs](https://book.getfoundry.sh/) for more info on installation and usage. If you already have foundry, you can build this project and run tests with these commands:
@@ -80,4 +97,3 @@ The current testnet deployment is on holesky, is from our M2 beta release. You c
8097
[`ServiceManagerRouter`](https://github.com/Layr-Labs/eigenlayer-middleware/blob/testnet-holesky/src/ServiceManagerRouter.sol) | - | [`0x4463...5a37`](https://holesky.etherscan.io/address/0x44632dfBdCb6D3E21EF613B0ca8A6A0c618F5a37#code) | |
8198
[`ProxyAdmin`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/ProxyAdmin.sol) | - | [`0xB043...5c15`](https://holesky.etherscan.io/address/0xB043055dd967A382577c2f5261fA6428f2905c15) | |
8299
[`eigenda/EigenDAServiceManager`](https://github.com/Layr-Labs/eigenda/blob/a33b41561cc3fb4cd6d50a8738e4c5dca43ec0a5/contracts/src/core/EigenDAServiceManager.sol) | [`0xD4A7E1Bd8015057293f0D0A557088c286942e84b`](https://holesky.etherscan.io/address/0xD4A7E1Bd8015057293f0D0A557088c286942e84b) | [`0xa722...67f3`](https://holesky.etherscan.io/address/0xa7227485e6C693AC4566fe168C5E3647c5c267f3) | Proxy: [`[email protected]`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) |
83-

foundry.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,23 @@ src = "src"
33
out = "out"
44
libs = ["lib"]
55
fs_permissions = [{ access = "read-write", path = "./" }]
6+
gas_limit = 5000000000
67

78
ffi = true
89
no-match-contract = "FFI"
910

1011
# Enables or disables the optimizer
1112
optimizer = true
12-
# The number of optimizer runs
13+
# Sets the number of optimizer runs
1314
optimizer_runs = 200
1415
# Whether or not to use the Yul intermediate representation compilation pipeline
1516
via_ir = false
1617
# Override the Solidity version (this overrides `auto_detect_solc`)
17-
solc_version = '0.8.12'
18+
solc_version = '0.8.27'
19+
20+
[etherscan]
21+
mainnet = { key = "${ETHERSCAN_API_KEY}" }
22+
holesky = { key = "${ETHERSCAN_API_KEY}" }
1823

1924
[fmt]
2025
bracket_spacing = false

lib/eigenlayer-contracts

script/ServiceManagerRouterDeploy.s.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: BUSL-1.1
2-
pragma solidity ^0.8.12;
2+
pragma solidity ^0.8.27;
33

44
import {ServiceManagerRouter} from "../src/ServiceManagerRouter.sol";
55
import "forge-std/Script.sol";
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
// Deploy L2AVS proxy
4+
5+
import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
6+
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
7+
8+
import {Vm} from "forge-std/Vm.sol";
9+
import {stdJson} from "forge-std/StdJson.sol";
10+
11+
library OperatorSetUpgradeLib {
12+
using stdJson for string;
13+
14+
// address(uint160(uint256(keccak256("hevm cheat code")))) == 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D
15+
// solhint-disable-next-line const-name-snakecase
16+
Vm private constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
17+
18+
/**
19+
* @dev Storage slot with the address of the current implementation.
20+
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
21+
*/
22+
bytes32 internal constant IMPLEMENTATION_SLOT =
23+
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
24+
25+
/**
26+
* @dev Storage slot with the admin of the contract.
27+
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
28+
*/
29+
bytes32 internal constant ADMIN_SLOT =
30+
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
31+
32+
33+
function upgrade(address proxy, address implementation, bytes memory data) internal {
34+
ProxyAdmin admin = ProxyAdmin(getAdmin(proxy));
35+
admin.upgradeAndCall(TransparentUpgradeableProxy(payable(proxy)), implementation, data);
36+
}
37+
38+
function upgrade(address proxy, address implementation) internal {
39+
ProxyAdmin admin = ProxyAdmin(getAdmin(proxy));
40+
admin.upgrade(TransparentUpgradeableProxy(payable(proxy)), implementation);
41+
}
42+
43+
function getAdmin(address proxy) internal view returns (address) {
44+
bytes32 value = vm.load(proxy, ADMIN_SLOT);
45+
return address(uint160(uint256(value)));
46+
}
47+
48+
function getImplementation(address proxy) internal view returns (address) {
49+
bytes32 value = vm.load(proxy, IMPLEMENTATION_SLOT);
50+
return address(uint160(uint256(value)));
51+
}
52+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"addresses":{
3+
"avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC",
4+
"avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A",
5+
"baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40",
6+
"beaconOracle": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25",
7+
"delayedWithdrawalRouter": "0xC4BC46a87A67a531eCF7f74338E1FA79533334Fa",
8+
"delayedWithdrawalRouterImplementation": "0x0011FA2c512063C495f77296Af8d195F33A8Dd38",
9+
"delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC",
10+
"delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1",
11+
"eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1",
12+
"eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B",
13+
"eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC",
14+
"eigenPodImplementation": "0x2D6c7f9862BD80Cf0d9d93FC6b513D69E7Db7869",
15+
"eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff",
16+
"eigenPodManagerImplementation": "0xc5B857A92245f64e9D90cCc5b096Db82eB77eB5c",
17+
"emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2",
18+
"rewardsCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0",
19+
"rewardsCoordinatorImplementation": "0x76d4D84c90a2AFf213F7D859d2a288685A1a2Ede",
20+
"slasher": "0x12699471dF8dca329C76D72823B1b79d55709384",
21+
"slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0"
22+
}
23+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"addresses":{
3+
"blsApkRegistry": "0xAd7f9e558170a149Ca8E90f41Ab2444A5d3bd6aD",
4+
"blsApkRegistryImplementation": "0x482a96D5879e32347d8df125f038D7eC8Ab358dd",
5+
"eigenDAProxyAdmin": "0x9Fd7E279f5bD692Dc04792151E14Ad814FC60eC1",
6+
"eigenDAServiceManager": "0x54A03db2784E3D0aCC08344D05385d0b62d4F432",
7+
"eigenDAServiceManagerImplementation": "0xEB11a0f320E39d3371Fec4Bf5C76944DfBA8ee10",
8+
"indexRegistry": "0x8cE5F2a53cBd29710eb94A04e40C07A4DdF15d10",
9+
"indexRegistryImplementation": "0x1D4d6054BD11A5711ad7c5d3E376C987a603e17C",
10+
"mockRollup": "0x0433646AdCeE95fbF89b3BFDb8157e75c19b6C2e",
11+
"operatorStateRetriever": "0x17cA8C41a59466710443143b2ECF08CaA35d80ad",
12+
"registryCoordinator": "0x2c61EA360D6500b58E7f481541A36B443Bc858c6",
13+
"registryCoordinatorImplementation": "0x6f21A84E7f185cCBA248B436e3b583E609d1dE1D",
14+
"serviceManagerRouter": "0xDb028E067fe81e9f406C2DE382Ba82e9cD7cBD03",
15+
"stakeRegistry": "0x53668EBf2e28180e38B122c641BC51Ca81088871",
16+
"stakeRegistryImplementation": "0x854dc9e5d011B060bf77B1a492302C349f2f00b5"
17+
}
18+
}

src/AVSRegistrar.sol

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.27;
3+
4+
import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol";
5+
import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol";
6+
import {IBLSApkRegistry} from "./interfaces/IBLSApkRegistry.sol";
7+
import {IStakeRegistry} from "./interfaces/IStakeRegistry.sol";
8+
import {IIndexRegistry} from "./interfaces/IIndexRegistry.sol";
9+
10+
abstract contract AVSRegistrar is IAVSRegistrar {
11+
function registerOperator(
12+
address operator,
13+
uint32[] calldata operatorSetIds,
14+
bytes calldata data
15+
) external virtual;
16+
17+
function deregisterOperator(
18+
address operator,
19+
uint32[] calldata operatorSetIds
20+
) external virtual;
21+
}

src/BLSApkRegistry.sol

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: BUSL-1.1
2-
pragma solidity ^0.8.12;
2+
pragma solidity ^0.8.27;
33

44
import {BLSApkRegistryStorage} from "./BLSApkRegistryStorage.sol";
55

@@ -12,10 +12,7 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
1212

1313
/// @notice when applied to a function, only allows the RegistryCoordinator to call it
1414
modifier onlyRegistryCoordinator() {
15-
require(
16-
msg.sender == address(registryCoordinator),
17-
"BLSApkRegistry.onlyRegistryCoordinator: caller is not the registry coordinator"
18-
);
15+
_checkRegistryCoordinator();
1916
_;
2017
}
2118

@@ -117,17 +114,17 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
117114

118115
// gamma = h(sigma, P, P', H(m))
119116
uint256 gamma = uint256(keccak256(abi.encodePacked(
120-
params.pubkeyRegistrationSignature.X,
121-
params.pubkeyRegistrationSignature.Y,
122-
params.pubkeyG1.X,
123-
params.pubkeyG1.Y,
124-
params.pubkeyG2.X,
125-
params.pubkeyG2.Y,
126-
pubkeyRegistrationMessageHash.X,
117+
params.pubkeyRegistrationSignature.X,
118+
params.pubkeyRegistrationSignature.Y,
119+
params.pubkeyG1.X,
120+
params.pubkeyG1.Y,
121+
params.pubkeyG2.X,
122+
params.pubkeyG2.Y,
123+
pubkeyRegistrationMessageHash.X,
127124
pubkeyRegistrationMessageHash.Y
128125
))) % BN254.FR_MODULUS;
129-
130-
// e(sigma + P * gamma, [-1]_2) = e(H(m) + [1]_1 * gamma, P')
126+
127+
// e(sigma + P * gamma, [-1]_2) = e(H(m) + [1]_1 * gamma, P')
131128
require(BN254.pairing(
132129
params.pubkeyRegistrationSignature.plus(params.pubkeyG1.scalar_mul(gamma)),
133130
BN254.negGeneratorG2(),
@@ -192,7 +189,7 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
192189
pubkeyHash != bytes32(0),
193190
"BLSApkRegistry.getRegisteredPubkey: operator is not registered"
194191
);
195-
192+
196193
return (pubkey, pubkeyHash);
197194
}
198195

@@ -205,10 +202,10 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
205202
uint256 blockNumber
206203
) external view returns (uint32[] memory) {
207204
uint32[] memory indices = new uint32[](quorumNumbers.length);
208-
205+
209206
for (uint256 i = 0; i < quorumNumbers.length; i++) {
210207
uint8 quorumNumber = uint8(quorumNumbers[i]);
211-
208+
212209
uint256 quorumApkUpdatesLength = apkHistory[quorumNumber].length;
213210
if (quorumApkUpdatesLength == 0 || blockNumber < apkHistory[quorumNumber][0].updateBlockNumber) {
214211
revert("BLSApkRegistry.getApkIndicesAtBlockNumber: blockNumber is before the first update");
@@ -256,11 +253,11 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
256253
*/
257254
require(
258255
blockNumber >= quorumApkUpdate.updateBlockNumber,
259-
"BLSApkRegistry._validateApkHashAtBlockNumber: index too recent"
256+
"BLSApkRegistry.getApkHashAtBlockNumberAndIndex: index too recent"
260257
);
261258
require(
262259
quorumApkUpdate.nextUpdateBlockNumber == 0 || blockNumber < quorumApkUpdate.nextUpdateBlockNumber,
263-
"BLSApkRegistry._validateApkHashAtBlockNumber: not latest apk update"
260+
"BLSApkRegistry.getApkHashAtBlockNumberAndIndex: not latest apk update"
264261
);
265262

266263
return quorumApkUpdate.apkHash;
@@ -281,4 +278,11 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
281278
function getOperatorId(address operator) public view returns (bytes32) {
282279
return operatorToPubkeyHash[operator];
283280
}
281+
282+
function _checkRegistryCoordinator() internal view {
283+
require(
284+
msg.sender == address(registryCoordinator),
285+
"BLSApkRegistry._checkRegistryCoordinator: caller is not the registry coordinator"
286+
);
287+
}
284288
}

src/BLSApkRegistryStorage.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: BUSL-1.1
2-
pragma solidity ^0.8.12;
2+
pragma solidity ^0.8.27;
33

44
import {IBLSApkRegistry} from "./interfaces/IBLSApkRegistry.sol";
55
import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol";

src/BLSSignatureChecker.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: BUSL-1.1
2-
pragma solidity ^0.8.12;
2+
pragma solidity ^0.8.27;
33

44
import {IBLSSignatureChecker} from "./interfaces/IBLSSignatureChecker.sol";
55
import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol";

0 commit comments

Comments
 (0)