Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: slashing release #311

Draft
wants to merge 30 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7d49b51
Update LICENSE (#285)
gpsanant Jul 17, 2024
163f4c3
chore: upgrade core to target operator set release
stevennevins Jul 25, 2024
ad64a45
Merge branch 'dev' into feat/operate-set-release-branch
stevennevins Aug 2, 2024
b7f4903
chore: update mock contracts with latest interfaces (#293)
shrimalmadhur Aug 5, 2024
d991827
chore: bump to latest operator set release commits
stevennevins Aug 8, 2024
4966813
chore: fixes for depedency bump
stevennevins Aug 8, 2024
4fabf80
feat: operator set migration-1-migration (#286)
stevennevins Aug 12, 2024
fe93ac6
feat: operator set migration-2-create quorum (#287)
stevennevins Aug 12, 2024
e5b2688
chore: bump operator set release dependency in core
stevennevins Aug 15, 2024
ec2fdf3
chore: updates from dependency bump
stevennevins Aug 15, 2024
12eda5d
feat: add natspec
stevennevins Aug 15, 2024
788cd09
docs: add natspec
stevennevins Aug 15, 2024
d64f4af
feat: add checks operator was registered for quorums when migrating
stevennevins Aug 15, 2024
a92d51a
fix: resolve code size issue in RegistryCoordinator
stevennevins Aug 15, 2024
32148de
chore: update to latest core (#299)
shrimalmadhur Aug 15, 2024
86f0928
feat(op sets): update stakes when forceUnregister (#300)
stevennevins Aug 21, 2024
3e4cb2b
merge dev
stevennevins Aug 21, 2024
f6ad20e
feat(op sets): register and deregister (#301)
stevennevins Aug 22, 2024
e0a79f1
feat(op sets): upgrade and migrate script (#303)
stevennevins Aug 22, 2024
eb0d6ad
chore: bump slashing core dependency (#312)
stevennevins Oct 17, 2024
cb4df12
feat: slasher templates / examples (#310)
stevennevins Nov 1, 2024
145bdaf
chore: remove unused test util contracts (#319)
stevennevins Nov 18, 2024
9a975df
feat: remove both option
stevennevins Nov 8, 2024
fa04f06
fix: storage gap remove one slot (#320)
stevennevins Nov 20, 2024
388e9f9
feat: track total slashable stake and total delegated stake per quoru…
stevennevins Nov 20, 2024
158a890
fix: use libraries with only internal vis (#324)
stevennevins Dec 4, 2024
817ad42
feat: avs registrar registration flow changes (#318)
stevennevins Dec 5, 2024
dbd59dd
feat: registration changes part 2
stevennevins Dec 9, 2024
6fd466e
chore: bump dependency for slashing mags updates (#329)
stevennevins Dec 10, 2024
f9ce2fc
Merge branch 'mainnet' into feat/slashing-release-branch
nadir-akhtar Dec 11, 2024
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
10 changes: 6 additions & 4 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ ffi = true
no-match-contract = "FFI"

# Enables or disables the optimizer
optimizer = true
# The number of optimizer runs
optimizer_runs = 200
optimizer = false
# Whether or not to use the Yul intermediate representation compilation pipeline
via_ir = false
# Override the Solidity version (this overrides `auto_detect_solc`)
solc_version = '0.8.12'
solc_version = '0.8.27'

[etherscan]
mainnet = { key = "${ETHERSCAN_API_KEY}" }
holesky = { key = "${ETHERSCAN_API_KEY}" }

[fmt]
bracket_spacing = false
Expand Down
2 changes: 1 addition & 1 deletion lib/eigenlayer-contracts
258 changes: 258 additions & 0 deletions script/OperatorSetUpgrade.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import {Script, console2} from "forge-std/Script.sol";
import {OperatorSetUpgradeLib} from "./utils/UpgradeLib.sol";
import {stdJson} from "forge-std/StdJson.sol";
import {ServiceManagerMock, IServiceManager} from "../test/mocks/ServiceManagerMock.sol";
import {StakeRegistry, IStakeRegistry} from "../src/StakeRegistry.sol";
import {RegistryCoordinator, IRegistryCoordinator} from "../src/RegistryCoordinator.sol";
import {AVSDirectory} from "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol";
import {IBLSApkRegistry} from "../src/interfaces/IBLSApkRegistry.sol";
import {IIndexRegistry} from "../src/interfaces/IIndexRegistry.sol";
import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol";
import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol";
import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol";
interface IServiceManagerMigration {
function getOperatorsToMigrate()
external
view
returns (
uint32[] memory operatorSetIdsToCreate,
uint32[][] memory operatorSetIds,
address[] memory allOperators
);
function migrateAndCreateOperatorSetIds(uint32[] memory operatorSetsToCreate) external;
function migrateToOperatorSets(uint32[][] memory operatorSetIds, address[] memory operators) external;
function finalizeMigration() external;
function migrationFinalized() external returns (bool);
}


import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

contract OperatorSetUpgradeScript is Script {
using stdJson for string;

address private constant DEFAULT_FORGE_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38;

address public proxyAdminOwner;
address public serviceManagerOwner;
address public serviceManager;
address public stakeRegistry;
address public registryCoordinator;
address public avsDirectory;
address public rewardsCoordinator;
address public delegationManager;
address public blsApkRegistry;
address public indexRegistry;
address public allocationManager;

function setUp() public {
vm.label(DEFAULT_FORGE_SENDER, "DEFAULT FORGE SENDER");

// Note: Ensure that the following environment variables are set before running the script:
// - PROXY_ADMIN_OWNER: The private key of the proxy admin owner.
// - SERVICE_MANAGER_OWNER: The private key of the service manager owner.
// These environment variables are crucial for the proper execution of the upgrade and migration processes.
/// TODO: improve DEVX of gnosis safe. Would like to do an tx service integration for SafeAPI
proxyAdminOwner = vm.rememberKey(vm.envUint("PROXY_ADMIN_OWNER"));
serviceManagerOwner = vm.rememberKey(vm.envUint("PROXY_ADMIN_OWNER"));

string memory middlewareJson = vm.readFile(vm.envString("MIDDLEWARE_JSON_PATH"));
string memory coreJson = vm.readFile(vm.envString("CORE_JSON_PATH"));

/*
* Note: Ensure that the structure of the configuration JSON files matches the structure
* of `core_testdata.json`. If you rename any of the files, you will need to update the
* corresponding key values in the code.
*/
loadAddressesSetup(middlewareJson, coreJson);
labelAndLogAddressesSetup();
}

function run() public {
vm.startBroadcast(proxyAdminOwner);

_upgrade();

vm.stopBroadcast();

vm.startBroadcast(serviceManagerOwner);

_migrateToOperatorSets();

vm.stopBroadcast();
}
// forge script script/OperatorSetUpgrade.s.sol --sig "simulateUpgrade()" -vvv
function simulateUpgrade() public {

address proxyAdmin = OperatorSetUpgradeLib.getAdmin(serviceManager);
proxyAdminOwner = Ownable(proxyAdmin).owner();
vm.startPrank(proxyAdminOwner);

_upgrade();

vm.stopPrank();

}

// forge script script/OperatorSetUpgrade.s.sol --sig "simulateMigrate()" -vvv
function simulateMigrate() public {
_upgradeAvsDirectory(); /// Workaround since this isn't on pre-prod yet

serviceManagerOwner = Ownable(serviceManager).owner();
vm.startPrank(serviceManagerOwner);

_migrateToOperatorSets();

vm.stopPrank();
}

// forge script script/OperatorSetUpgrade.s.sol --sig "simulateUpgradeAndMigrate()" -vvv
function simulateUpgradeAndMigrate() public {
_upgradeAvsDirectory(); /// Workaround since this isn't on pre-prod yet

address proxyAdmin = OperatorSetUpgradeLib.getAdmin(serviceManager);
proxyAdminOwner = Ownable(proxyAdmin).owner();

console2.log(proxyAdminOwner, "Pranker");
vm.startPrank(proxyAdminOwner);

_upgrade();

vm.stopPrank();

serviceManagerOwner = Ownable(serviceManager).owner();
vm.startPrank(serviceManagerOwner);

_migrateToOperatorSets();

vm.stopPrank();

// Assert that serviceManager is an operatorSetAVS
require(
IAVSDirectory(avsDirectory).isOperatorSetAVS(serviceManager),
"simulateUpgradeAndMigrate: serviceManager is not an operatorSetAVS"
);

// Assert that the migration is finalized
require(
IServiceManagerMigration(serviceManager).migrationFinalized(),
"simulateUpgradeAndMigrate: Migration is not finalized"
);
}

function _upgradeAvsDirectory() internal {
address proxyAdmin = OperatorSetUpgradeLib.getAdmin(avsDirectory);
address avsDirectoryOwner = Ownable(proxyAdmin).owner();
AVSDirectory avsDirectoryImpl = new AVSDirectory(IDelegationManager(delegationManager), 0); // TODO: config

vm.startPrank(avsDirectoryOwner);
OperatorSetUpgradeLib.upgrade(avsDirectory, address(avsDirectoryImpl));
vm.stopPrank();
}

function labelAndLogAddressesSetup() internal virtual {
vm.label(proxyAdminOwner, "Proxy Admin Owner Account");
vm.label(serviceManagerOwner, "Service Manager Owner Account");
vm.label(serviceManager, "Service Manager Proxy");
vm.label(stakeRegistry, "Stake Registry Proxy");
vm.label(registryCoordinator, "Registry Coordinator Proxy");
vm.label(indexRegistry, "Index Registry Proxy");
vm.label(blsApkRegistry, "BLS APK Registry Proxy");
vm.label(avsDirectory, "AVS Directory Proxy");
vm.label(delegationManager, "Delegation Manager Proxy");
vm.label(rewardsCoordinator, "Rewards Coordinator Proxy");

console2.log("Proxy Admin Owner Account", proxyAdminOwner);
console2.log("ServiceManager Owner Account", serviceManagerOwner);
console2.log("Service Manager:", serviceManager);
console2.log("Stake Registry:", stakeRegistry);
console2.log("Registry Coordinator:", registryCoordinator);
console2.log("Index Registry:", indexRegistry);
console2.log("BLS APK Registry:", blsApkRegistry);
console2.log("AVS Directory:", avsDirectory);
console2.log("Delegation Manager:", delegationManager);
console2.log("Rewards Coordinator:", rewardsCoordinator);

address oldServiceManagerImpl = OperatorSetUpgradeLib.getImplementation(serviceManager);
address oldStakeRegistryImpl = OperatorSetUpgradeLib.getImplementation(stakeRegistry);
address oldRegistryCoordinatorImpl = OperatorSetUpgradeLib.getImplementation(registryCoordinator);
address oldAvsDirectoryImpl = OperatorSetUpgradeLib.getImplementation(avsDirectory);
address oldDelegationManagerImpl = OperatorSetUpgradeLib.getImplementation(delegationManager);

vm.label(oldServiceManagerImpl, "Old Service Manager Implementation");
vm.label(oldStakeRegistryImpl, "Old Stake Registry Implementation");
vm.label(oldRegistryCoordinatorImpl, "Old Registry Coordinator Implementation");
vm.label(oldAvsDirectoryImpl, "Old AVS Directory Implementation");
vm.label(oldDelegationManagerImpl, "Old Delegation Manager Implementation");

console2.log("Old Service Manager Implementation:", oldServiceManagerImpl);
console2.log("Old Stake Registry Implementation:", oldStakeRegistryImpl);
console2.log("Old Registry Coordinator Implementation:", oldRegistryCoordinatorImpl);
console2.log("Old AVS Directory Implementation:", oldAvsDirectoryImpl);
console2.log("Old Delegation Manager Implementation:", oldDelegationManagerImpl);
}

function loadAddressesSetup(string memory middlewareJson, string memory coreJson) internal virtual {
serviceManager = middlewareJson.readAddress(".addresses.eigenDAServiceManager");
stakeRegistry = middlewareJson.readAddress(".addresses.stakeRegistry");
registryCoordinator = middlewareJson.readAddress(".addresses.registryCoordinator");
blsApkRegistry = middlewareJson.readAddress(".addresses.blsApkRegistry");
indexRegistry = middlewareJson.readAddress(".addresses.indexRegistry");

avsDirectory = coreJson.readAddress(".addresses.avsDirectory");
delegationManager = coreJson.readAddress(".addresses.delegationManager");
rewardsCoordinator = coreJson.readAddress(".addresses.rewardsCoordinator");
}

function _upgrade() internal virtual {
address newServiceManagerImpl = address(new ServiceManagerMock(
IAVSDirectory(avsDirectory),
IRewardsCoordinator(rewardsCoordinator),
IRegistryCoordinator(registryCoordinator),
IStakeRegistry(stakeRegistry),
IAllocationManager(allocationManager)
));
address newRegistryCoordinatorImpl = address(new RegistryCoordinator(
IServiceManager(serviceManager),
IStakeRegistry(stakeRegistry),
IBLSApkRegistry(blsApkRegistry),
IIndexRegistry(indexRegistry),
IAVSDirectory(avsDirectory)
));
address newStakeRegistryImpl = address(new StakeRegistry(
IRegistryCoordinator(registryCoordinator),
IDelegationManager(delegationManager),
IAVSDirectory(avsDirectory),
IServiceManager(serviceManager)
));

console2.log("New Service Manager Implementation:", newServiceManagerImpl);
console2.log("New Registry Coordinator Implementation:", newRegistryCoordinatorImpl);
console2.log("New Stake Registry Implementation:", newStakeRegistryImpl);

vm.label(newServiceManagerImpl, "New Service Manager Implementation");
vm.label(newRegistryCoordinatorImpl, "New Registry Coordinator Implementation");
vm.label(newStakeRegistryImpl, "New Stake Registry Implementation");

OperatorSetUpgradeLib.upgrade(serviceManager, newServiceManagerImpl);
OperatorSetUpgradeLib.upgrade(registryCoordinator, newRegistryCoordinatorImpl);
OperatorSetUpgradeLib.upgrade(stakeRegistry, newStakeRegistryImpl);
}

function _migrateToOperatorSets() internal virtual {
IServiceManagerMigration serviceManager = IServiceManagerMigration(serviceManager);
(
uint32[] memory operatorSetsToCreate,
uint32[][] memory operatorSetIdsToMigrate,
address[] memory operators
) = serviceManager.getOperatorsToMigrate();

serviceManager.migrateAndCreateOperatorSetIds(operatorSetsToCreate);
serviceManager.migrateToOperatorSets(operatorSetIdsToMigrate, operators);
serviceManager.finalizeMigration();
}
}
40 changes: 40 additions & 0 deletions script/utils/UpgradeLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Deploy L2AVS proxy

import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";

import {Vm} from "forge-std/Vm.sol";
import {stdJson} from "forge-std/StdJson.sol";

library OperatorSetUpgradeLib {
using stdJson for string;
Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
bytes32 internal constant IMPLEMENTATION_SLOT =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

bytes32 internal constant ADMIN_SLOT =
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;


function upgrade(address proxy, address implementation, bytes memory data) internal {
ProxyAdmin admin = ProxyAdmin(getAdmin(proxy));
admin.upgradeAndCall(TransparentUpgradeableProxy(payable(proxy)), implementation, data);
}

function upgrade(address proxy, address implementation) internal {
ProxyAdmin admin = ProxyAdmin(getAdmin(proxy));
admin.upgrade(TransparentUpgradeableProxy(payable(proxy)), implementation);
}

function getAdmin(address proxy) internal view returns (address){
bytes32 value = vm.load(proxy, ADMIN_SLOT);
return address(uint160(uint256(value)));
}

function getImplementation(address proxy) internal view returns (address) {
bytes32 value = vm.load(proxy, IMPLEMENTATION_SLOT);
return address(uint160(uint256(value)));
}
}
23 changes: 23 additions & 0 deletions script/utils/testdata/17000/core_testdata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"addresses":{
"avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC",
"avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A",
"baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40",
"beaconOracle": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25",
"delayedWithdrawalRouter": "0xC4BC46a87A67a531eCF7f74338E1FA79533334Fa",
"delayedWithdrawalRouterImplementation": "0x0011FA2c512063C495f77296Af8d195F33A8Dd38",
"delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC",
"delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1",
"eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1",
"eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B",
"eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC",
"eigenPodImplementation": "0x2D6c7f9862BD80Cf0d9d93FC6b513D69E7Db7869",
"eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff",
"eigenPodManagerImplementation": "0xc5B857A92245f64e9D90cCc5b096Db82eB77eB5c",
"emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2",
"rewardsCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0",
"rewardsCoordinatorImplementation": "0x76d4D84c90a2AFf213F7D859d2a288685A1a2Ede",
"slasher": "0x12699471dF8dca329C76D72823B1b79d55709384",
"slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0"
}
}
18 changes: 18 additions & 0 deletions script/utils/testdata/17000/middlware_testdata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"addresses":{
"blsApkRegistry": "0xAd7f9e558170a149Ca8E90f41Ab2444A5d3bd6aD",
"blsApkRegistryImplementation": "0x482a96D5879e32347d8df125f038D7eC8Ab358dd",
"eigenDAProxyAdmin": "0x9Fd7E279f5bD692Dc04792151E14Ad814FC60eC1",
"eigenDAServiceManager": "0x54A03db2784E3D0aCC08344D05385d0b62d4F432",
"eigenDAServiceManagerImplementation": "0xEB11a0f320E39d3371Fec4Bf5C76944DfBA8ee10",
"indexRegistry": "0x8cE5F2a53cBd29710eb94A04e40C07A4DdF15d10",
"indexRegistryImplementation": "0x1D4d6054BD11A5711ad7c5d3E376C987a603e17C",
"mockRollup": "0x0433646AdCeE95fbF89b3BFDb8157e75c19b6C2e",
"operatorStateRetriever": "0x17cA8C41a59466710443143b2ECF08CaA35d80ad",
"registryCoordinator": "0x2c61EA360D6500b58E7f481541A36B443Bc858c6",
"registryCoordinatorImplementation": "0x6f21A84E7f185cCBA248B436e3b583E609d1dE1D",
"serviceManagerRouter": "0xDb028E067fe81e9f406C2DE382Ba82e9cD7cBD03",
"stakeRegistry": "0x53668EBf2e28180e38B122c641BC51Ca81088871",
"stakeRegistryImplementation": "0x854dc9e5d011B060bf77B1a492302C349f2f00b5"
}
}
8 changes: 5 additions & 3 deletions src/BLSSignatureChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,11 @@ contract BLSSignatureChecker is IBLSSignatureChecker {
*/
{
bool _staleStakesForbidden = staleStakesForbidden;
uint256 withdrawalDelayBlocks = _staleStakesForbidden
? delegation.minWithdrawalDelayBlocks()
: 0;
/// TODO: FIX
uint256 withdrawalDelayBlocks = 0;
// uint256 withdrawalDelayBlocks = _staleStakesForbidden
// ? delegation.minWithdrawalDelayBlocks()
// : 0;

for (uint256 i = 0; i < quorumNumbers.length; i++) {
// If we're disallowing stale stake updates, check that each quorum's last update block
Expand Down
Loading
Loading