Skip to content
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
25 changes: 22 additions & 3 deletions l1-contracts/script/DeployEverything.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import { DeployUniFiAVSManager } from "script/DeployUniFiAVSManager.s.sol";
import { SetupAccess } from "script/SetupAccess.s.sol";
import { AccessManager } from "@openzeppelin/contracts/access/manager/AccessManager.sol";
import { AVSDeployment } from "script/DeploymentStructs.sol";
import { console } from "forge-std/console.sol";

import { UniFiAVSDisputeManager } from "../src/UniFiAVSDisputeManager.sol";
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
/**
* @title Deploy all protocol contracts
* @author Puffer Finance
* @notice Deploys all contracts for the AVS and sets up the access control
* @dev Example on how to run the script
* forge script script/DeployEverything.s.sol:DeployEverything --rpc-url=$RPC_URL --sig 'run()' --broadcast
*/

contract DeployEverything is BaseScript {
address DAO;

Expand All @@ -28,16 +29,32 @@ contract DeployEverything is BaseScript {

vm.startBroadcast(_deployerPrivateKey);
AccessManager accessManager = new AccessManager(_broadcaster);

// Deploy DisputeManager
UniFiAVSDisputeManager disputeManagerImplementation = new UniFiAVSDisputeManager();
address disputeManager = address(
new ERC1967Proxy{ salt: bytes32("UniFiAVSDisputeManager") }(
address(disputeManagerImplementation),
abi.encodeCall(UniFiAVSDisputeManager.initialize, (address(accessManager)))
)
);

vm.stopBroadcast();

// 1. Deploy AVSManager
(address avsManagerImplementation, address avsManagerProxy) = new DeployUniFiAVSManager().run(
address(accessManager), eigenPodManager, eigenDelegationManager, avsDirectory, initialDeregistrationDelay
address(accessManager),
eigenPodManager,
eigenDelegationManager,
avsDirectory,
initialDeregistrationDelay,
disputeManager
);

deployment.avsManagerImplementation = avsManagerImplementation;
deployment.avsManagerProxy = avsManagerProxy;
deployment.accessManager = address(accessManager);
deployment.disputeManagerProxy = disputeManager;

// `anvil` in the terminal
if (_localAnvil) {
Expand Down Expand Up @@ -65,6 +82,8 @@ contract DeployEverything is BaseScript {
vm.serializeAddress(obj, "avsManagerImplementation", deployment.avsManagerImplementation);
vm.serializeAddress(obj, "avsManagerProxy", deployment.avsManagerProxy);
vm.serializeAddress(obj, "accessManager", deployment.accessManager);
vm.serializeAddress(obj, "disputeManagerImplementation", deployment.disputeManagerImplementation);
vm.serializeAddress(obj, "disputeManagerProxy", deployment.disputeManagerProxy);
vm.serializeAddress(obj, "dao", DAO);

string memory finalJson = vm.serializeString(obj, "", "");
Expand Down
10 changes: 7 additions & 3 deletions l1-contracts/script/DeployUniFiAVSManager.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { IEigenPodManager } from "eigenlayer/interfaces/IEigenPodManager.sol";
import { IDelegationManager } from "eigenlayer/interfaces/IDelegationManager.sol";
import { IAVSDirectory } from "eigenlayer/interfaces/IAVSDirectory.sol";
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import { console } from "forge-std/console.sol";
import { IUniFiAVSDisputeManager } from "../src/interfaces/IUniFiAVSDisputeManager.sol";

contract DeployUniFiAVSManager is BaseScript {
UniFiAVSManager public uniFiAVSManagerProxy;
Expand All @@ -17,11 +17,15 @@ contract DeployUniFiAVSManager is BaseScript {
address eigenPodManager,
address eigenDelegationManager,
address avsDirectory,
uint64 initialDeregistrationDelay
uint64 initialDeregistrationDelay,
address disputeManager
) public returns (address, address) {
vm.startBroadcast(_deployerPrivateKey);
UniFiAVSManager uniFiAVSManagerImplementation = new UniFiAVSManager(
IEigenPodManager(eigenPodManager), IDelegationManager(eigenDelegationManager), IAVSDirectory(avsDirectory)
IEigenPodManager(eigenPodManager),
IDelegationManager(eigenDelegationManager),
IAVSDirectory(avsDirectory),
IUniFiAVSDisputeManager(disputeManager)
);

uniFiAVSManagerProxy = UniFiAVSManager(
Expand Down
19 changes: 16 additions & 3 deletions l1-contracts/script/DeployUniFiAVSManagerWithMocks.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import { IDelegationManager } from "eigenlayer/interfaces/IDelegationManager.sol
import { IAVSDirectory } from "eigenlayer/interfaces/IAVSDirectory.sol";
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import { AccessManager } from "@openzeppelin/contracts/access/manager/AccessManager.sol";
import "forge-std/console.sol";

import "../test/mocks/MockEigenPodManager.sol";
import "../test/mocks/MockDelegationManager.sol";
import "../test/mocks/MockAVSDirectory.sol";
import "../src/UniFiAVSDisputeManager.sol";
import { IUniFiAVSDisputeManager } from "../src/interfaces/IUniFiAVSDisputeManager.sol";
import { console } from "forge-std/console.sol";

contract DeployUniFiAVSManagerWithMocks is BaseScript {
UniFiAVSManager public uniFiAVSManagerProxy;
Expand All @@ -21,16 +22,27 @@ contract DeployUniFiAVSManagerWithMocks is BaseScript {
address eigenDelegationManager;
address avsDirectory;
uint64 initialDeregistrationDelay = 0;
address disputeManager;

function run() public broadcast returns (address, address) {
eigenPodManager = address(new MockEigenPodManager());
eigenDelegationManager = address(new MockDelegationManager());
avsDirectory = address(new MockAVSDirectory());

accessManager = new AccessManager(_broadcaster);
UniFiAVSDisputeManager disputeManagerImplementation = new UniFiAVSDisputeManager();
disputeManager = address(
new ERC1967Proxy{ salt: bytes32("UniFiAVSDisputeManager") }(
address(disputeManagerImplementation),
abi.encodeCall(UniFiAVSDisputeManager.initialize, (address(accessManager)))
)
);

UniFiAVSManager uniFiAVSManagerImplementation = new UniFiAVSManager(
IEigenPodManager(eigenPodManager), IDelegationManager(eigenDelegationManager), IAVSDirectory(avsDirectory)
IEigenPodManager(eigenPodManager),
IDelegationManager(eigenDelegationManager),
IAVSDirectory(avsDirectory),
IUniFiAVSDisputeManager(disputeManager)
);

uniFiAVSManagerProxy = UniFiAVSManager(
Expand All @@ -49,6 +61,7 @@ contract DeployUniFiAVSManagerWithMocks is BaseScript {
console.log("eigenPodManager mock:", address(eigenPodManager));
console.log("eigenDelegationManager mock:", address(eigenDelegationManager));
console.log("avsDirectory mock:", address(avsDirectory));
console.log("disputeManager mock:", address(disputeManager));

return (address(uniFiAVSManagerImplementation), address(uniFiAVSManagerProxy));
}
Expand Down
2 changes: 2 additions & 0 deletions l1-contracts/script/DeploymentStructs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ struct AVSDeployment {
address accessManager;
address timelock;
address dao;
address disputeManagerProxy;
address disputeManagerImplementation;
}
3 changes: 3 additions & 0 deletions l1-contracts/script/Roles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ uint64 constant ROLE_ID_AVS_COORDINATOR_ALLOWLISTER = 5;

// Lockbox role for ETH Mainnet
uint64 constant ROLE_ID_LOCKBOX = 7;

// Role for UniFiAVSManager
uint64 constant ROLE_ID_UNIFI_AVS_MANAGER = 30;
45 changes: 36 additions & 9 deletions l1-contracts/script/SetupAccess.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { AccessManager } from "@openzeppelin/contracts/access/manager/AccessMana
import { Multicall } from "@openzeppelin/contracts/utils/Multicall.sol";
import { UniFiAVSManager } from "../src/UniFiAVSManager.sol";
import { AVSDeployment } from "script/DeploymentStructs.sol";

import { UniFiAVSDisputeManager } from "../src/UniFiAVSDisputeManager.sol";
import {
ROLE_ID_OPERATIONS_MULTISIG,
ROLE_ID_OPERATIONS_PAYMASTER,
ROLE_ID_PUFFER_PROTOCOL,
ROLE_ID_DAO,
ROLE_ID_OPERATIONS_COORDINATOR,
ROLE_ID_VT_PRICER
ROLE_ID_VT_PRICER,
ROLE_ID_UNIFI_AVS_MANAGER
} from "../script/Roles.sol";

contract SetupAccess is BaseScript {
Expand All @@ -31,6 +32,7 @@ contract SetupAccess is BaseScript {
bytes[] memory calldatas = _generateAccessCalldata({
rolesCalldatas: _grantRoles(dao),
uniFiAVSManagerRoles: _setupUniFiAVSManagerRoles(),
uniFiAVSDisputeManagerRoles: _setupUniFiAVSDisputeManagerRoles(),
roleLabels: _labelRoles()
});

Expand All @@ -43,21 +45,26 @@ contract SetupAccess is BaseScript {
function _generateAccessCalldata(
bytes[] memory rolesCalldatas,
bytes[] memory uniFiAVSManagerRoles,
bytes[] memory uniFiAVSDisputeManagerRoles,
bytes[] memory roleLabels
) internal view returns (bytes[] memory calldatas) {
calldatas = new bytes[](4);
calldatas = new bytes[](6);
calldatas[0] = rolesCalldatas[0];
calldatas[1] = rolesCalldatas[1];

calldatas[1] = uniFiAVSManagerRoles[0];
calldatas[2] = uniFiAVSManagerRoles[1];

calldatas[3] = roleLabels[0];
calldatas[2] = uniFiAVSManagerRoles[0];
calldatas[3] = uniFiAVSManagerRoles[1];
calldatas[4] = uniFiAVSDisputeManagerRoles[0];
calldatas[5] = roleLabels[0];
}

function _grantRoles(address dao) internal view returns (bytes[] memory) {
bytes[] memory calldatas = new bytes[](1);
bytes[] memory calldatas = new bytes[](2);

calldatas[0] = abi.encodeWithSelector(AccessManager.grantRole.selector, ROLE_ID_DAO, dao, 0);
calldatas[1] = abi.encodeWithSelector(
AccessManager.grantRole.selector, ROLE_ID_UNIFI_AVS_MANAGER, avsDeployment.avsManagerProxy, 0
);

return calldatas;
}
Expand Down Expand Up @@ -88,7 +95,7 @@ contract SetupAccess is BaseScript {
);

bytes4[] memory publicSelectors = new bytes4[](0);
publicSelectors = new bytes4[](8);
publicSelectors = new bytes4[](12);
publicSelectors[0] = UniFiAVSManager.registerOperator.selector;
publicSelectors[1] = UniFiAVSManager.registerValidators.selector;
publicSelectors[2] = UniFiAVSManager.startDeregisterOperator.selector;
Expand All @@ -97,6 +104,10 @@ contract SetupAccess is BaseScript {
publicSelectors[5] = UniFiAVSManager.setOperatorCommitment.selector;
publicSelectors[6] = UniFiAVSManager.updateOperatorCommitment.selector;
publicSelectors[7] = UniFiAVSManager.registerOperatorWithCommitment.selector;
publicSelectors[8] = UniFiAVSManager.registerValidatorsOptimistically.selector;
publicSelectors[9] = UniFiAVSManager.verifyValidatorSignatures.selector;
publicSelectors[10] = UniFiAVSManager.slashValidatorsWithInvalidPubkey.selector;
publicSelectors[11] = UniFiAVSManager.slashValidatorsWithInvalidIndex.selector;

calldatas[1] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector,
Expand All @@ -107,4 +118,20 @@ contract SetupAccess is BaseScript {

return calldatas;
}

function _setupUniFiAVSDisputeManagerRoles() internal view returns (bytes[] memory) {
bytes[] memory calldatas = new bytes[](1);

bytes4[] memory selectors = new bytes4[](1);
selectors[0] = UniFiAVSDisputeManager.slashOperator.selector;

calldatas[0] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector,
address(avsDeployment.disputeManagerProxy),
selectors,
ROLE_ID_UNIFI_AVS_MANAGER
);

return calldatas;
}
}
19 changes: 18 additions & 1 deletion l1-contracts/script/UpgradeMainnetUniFiAVS.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import { IAVSDirectory } from "eigenlayer/interfaces/IAVSDirectory.sol";
import { console } from "forge-std/console.sol";
import { ROLE_ID_OPERATIONS_MULTISIG, ROLE_ID_DAO } from "./Roles.sol";
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import { UniFiAVSDisputeManager } from "../src/UniFiAVSDisputeManager.sol";
import { IUniFiAVSDisputeManager } from "../src/interfaces/IUniFiAVSDisputeManager.sol";
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

contract UpgradeMainnetUniFiAVS is BaseScript {
function run() public returns (AVSDeployment memory deployment) {
Expand All @@ -25,8 +28,22 @@ contract UpgradeMainnetUniFiAVS is BaseScript {
uint64 initialDeregistrationDelay = 0;

AccessManager accessManager = AccessManager(accessManagerAddress);
// Deploy DisputeManager
UniFiAVSDisputeManager disputeManagerImplementation = new UniFiAVSDisputeManager();
address disputeManager = address(
new ERC1967Proxy{ salt: bytes32("UniFiAVSDisputeManager") }(
address(disputeManagerImplementation),
abi.encodeCall(UniFiAVSDisputeManager.initialize, (address(accessManager)))
)
);
console.log("DisputeManager implementation:", address(disputeManagerImplementation));
console.log("DisputeManager proxy:", disputeManager);

UniFiAVSManager uniFiAVSManagerImplementation = new UniFiAVSManager(
IEigenPodManager(eigenPodManager), IDelegationManager(eigenDelegationManager), IAVSDirectory(avsDirectory)
IEigenPodManager(eigenPodManager),
IDelegationManager(eigenDelegationManager),
IAVSDirectory(avsDirectory),
IUniFiAVSDisputeManager(disputeManager)
);

console.log("UniFiAVSManager Implementation:", address(uniFiAVSManagerImplementation));
Expand Down
48 changes: 48 additions & 0 deletions l1-contracts/src/UniFiAVSDisputeManager.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
pragma solidity >=0.8.0 <0.9.0;

import "./storage/UniFiAVSDisputeManagerStorage.sol";
import "./structs/ValidatorData.sol";
import { AccessManagedUpgradeable } from
"@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol";
import { IUniFiAVSDisputeManager } from "./interfaces/IUniFiAVSDisputeManager.sol";
/**
* @title UniFiAVSDisputeManager
* @dev Manages disputes and slashing of operators.
*/

contract UniFiAVSDisputeManager is IUniFiAVSDisputeManager, UniFiAVSDisputeManagerStorage, AccessManagedUpgradeable {
constructor() {
_disableInitializers();
}

function initialize(address accessManager) external initializer {
__AccessManaged_init(accessManager);
}

/**
* @inheritdoc IUniFiAVSDisputeManager
* @dev restricted to the UniFiAVSManager
*/
function slashOperator(address operator, bytes32[] calldata validators, address slashingBeneficiary)
external
restricted
{
UniFiAVSDisputeStorage storage $ = _getUniFiAVSDisputeStorage();

for (uint256 i = 0; i < validators.length; i++) {
$.slashedOperators[operator].push(
InvalidValidator({ slashingBeneficiary: slashingBeneficiary, blsPubKeyHash: validators[i] })
);
}

emit OperatorSlashed(operator, validators, slashingBeneficiary);
}

/**
* @inheritdoc IUniFiAVSDisputeManager
*/
function isOperatorSlashed(address operator) external view returns (bool) {
UniFiAVSDisputeStorage storage $ = _getUniFiAVSDisputeStorage();
return $.slashedOperators[operator].length > 0;
}
}
Loading