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

chore: deploy local avs w/ anvil #195

Merged
merged 5 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions contracts/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ deploy-core:
forge clean
DEPLOY_TYPE="core" RPC_URL="http://localhost:8545" PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" CHAIN_ID="17864" ./entrypoint.sh

deploy-avs-with-mock-eigen:
forge clean
forge script scripts/validator-registry/avs/DeployAVSWithMockEigen.s.sol:DeployAVSWithMockEigen --rpc-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --via-ir --broadcast

run-stake-example:
forge script scripts/validator-registry/ValidatorExampleScript.s.sol:StakeExample --rpc-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --via-ir --broadcast

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: BSL 1.1
pragma solidity ^0.8.20;

// solhint-disable no-console
// solhint-disable one-contract-per-file

import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/console.sol";
import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";
import {MevCommitAVS} from "../../../contracts/validator-registry/avs/MevCommitAVS.sol";
import {StrategyManagerMock} from "eigenlayer-contracts/src/test/mocks/StrategyManagerMock.sol";
import {DelegationManagerMock} from "eigenlayer-contracts/src/test/mocks/DelegationManagerMock.sol";
import {EigenPodManagerMock} from "../../../test/validator-registry/avs/EigenPodManagerMock.sol";
import {AVSDirectoryMock} from "../../../test/validator-registry/avs/AVSDirectoryMock.sol";

contract DeployAVSWithMockEigen is Script {
function run() external {
require(block.chainid == 31337, "must deploy on anvil");
vm.startBroadcast();

StrategyManagerMock strategyManagerMock = new StrategyManagerMock();
DelegationManagerMock delegationManagerMock = new DelegationManagerMock();
EigenPodManagerMock eigenPodManagerMock = new EigenPodManagerMock();
AVSDirectoryMock avsDirectoryMock = new AVSDirectoryMock();

address[] memory restakeableStrategies = new address[](3);
restakeableStrategies[0] = address(0x1);
restakeableStrategies[1] = address(0x2);
restakeableStrategies[2] = address(0x3);

address freezeOracle = address(0x5);
uint256 unfreezeFee = 1 ether;
address unfreezeReceiver = address(0x6);
uint256 unfreezePeriodBlocks = 100;
uint256 operatorDeregPeriodBlocks = 200;
uint256 validatorDeregPeriodBlocks = 300;
uint256 lstRestakerDeregPeriodBlocks = 400;
string memory metadataUrl = "https://raw.githubusercontent.com/primev/mev-commit/main/static/avs-metadata.json";

address proxy = Upgrades.deployUUPSProxy(
"MevCommitAVS.sol",
abi.encodeCall(MevCommitAVS.initialize, (
msg.sender,
delegationManagerMock,
eigenPodManagerMock,
strategyManagerMock,
avsDirectoryMock,
restakeableStrategies,
freezeOracle,
unfreezeFee,
unfreezeReceiver,
unfreezePeriodBlocks,
operatorDeregPeriodBlocks,
validatorDeregPeriodBlocks,
lstRestakerDeregPeriodBlocks,
metadataUrl
))
);
MevCommitAVS mevCommitAVS = MevCommitAVS(payable(proxy));

console.log("StrategyManagerMock deployed at:", address(strategyManagerMock));
console.log("DelegationManagerMock deployed at:", address(delegationManagerMock));
console.log("EigenPodManagerMock deployed at:", address(eigenPodManagerMock));
console.log("AVSDirectoryMock deployed at:", address(avsDirectoryMock));
console.log("MevCommitAVS deployed at:", address(mevCommitAVS));

delegationManagerMock.setIsOperator(msg.sender, true);

vm.stopBroadcast();
}
}
50 changes: 40 additions & 10 deletions contracts/test/validator-registry/avs/AVSDirectoryMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@ pragma solidity 0.8.20;
import "forge-std/Test.sol";
import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol";
import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

// Eigenlayer core does not define their own mock for AVSDirectory.sol, hence we define our own.
contract AVSDirectoryMock is IAVSDirectory, Test {
mapping(address => bool) public isOperatorRegistered;
address public avs_;

bytes32 public constant OPERATOR_AVS_REGISTRATION_TYPEHASH =
keccak256("OperatorAVSRegistration(address operator,address avs,bytes32 salt,uint256 expiry)");

bytes32 public constant DOMAIN_TYPEHASH =
keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");

function registerOperator(address operator) external {
isOperatorRegistered[operator] = true;
Expand All @@ -17,16 +25,28 @@ contract AVSDirectoryMock is IAVSDirectory, Test {
isOperatorRegistered[operator] = false;
}

function isRegisteredOperator(address operator) external view returns (bool) {
return isOperatorRegistered[operator];
}

function registerOperatorToAVS(
address operator,
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature
) external override {
require(operator != address(0), "Operator cannot be zero");
require(operatorSignature.salt != bytes32(0), "Salt cannot be zero");
require(operator != address(0), "Operator required");
require(keccak256(operatorSignature.signature) != keccak256(bytes("")), "Signature required");
require(operatorSignature.salt != bytes32(0), "Salt required");
require(operatorSignature.expiry != 0, "Expiry required");

bytes32 operatorRegistrationDigestHash = calculateOperatorAVSRegistrationDigestHash({
operator: operator,
avs: msg.sender,
salt: operatorSignature.salt,
expiry: operatorSignature.expiry
});

// solhint-disable-next-line reason-string
require(
ECDSA.recover(operatorRegistrationDigestHash, operatorSignature.signature) == operator,
"EIP1271SignatureUtils.checkSignature_EIP1271: signature not from signer"
);

isOperatorRegistered[operator] = true;
emit OperatorAVSRegistrationStatusUpdated(operator, msg.sender, OperatorAVSRegistrationStatus.REGISTERED);
}
Expand All @@ -40,6 +60,10 @@ contract AVSDirectoryMock is IAVSDirectory, Test {
emit AVSMetadataURIUpdated(msg.sender, metadataURI);
}

function isRegisteredOperator(address operator) external view returns (bool) {
return isOperatorRegistered[operator];
}

function operatorSaltIsSpent(address operator, bytes32 salt) external pure override returns (bool) {
require(operator != address(0), "Operator cannot be zero");
require(salt != bytes32(0), "Salt cannot be zero");
Expand All @@ -51,11 +75,17 @@ contract AVSDirectoryMock is IAVSDirectory, Test {
address avs,
bytes32 salt,
uint256 expiry
) external pure override returns (bytes32) {
return keccak256(abi.encodePacked(operator, avs, salt, expiry));
) public view returns (bytes32) {
bytes32 structHash = keccak256(
abi.encode(OPERATOR_AVS_REGISTRATION_TYPEHASH, operator, avs, salt, expiry)
);
bytes32 digestHash = keccak256(
abi.encodePacked("\x19\x01", domainSeparator(), structHash)
);
return digestHash;
}

function OPERATOR_AVS_REGISTRATION_TYPEHASH() external pure override returns (bytes32) {
return keccak256("OperatorAVSRegistration(address operator,address avs,bytes32 salt,uint256 expiry)");
function domainSeparator() public view returns (bytes32) {
return keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes("EigenLayer")), block.chainid, address(this)));
}
}
41 changes: 24 additions & 17 deletions contracts/test/validator-registry/avs/MevCommitAVSTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ contract MevCommitAVSTest is Test {
uint256 public lstRestakerDeregPeriodBlocks;
string public metadataUrl;

address public operator = address(0x18A8E44e0E225B10a4Af86CEC6e4c514BB95B342);
uint256 public operatorPrivateKey = uint256(0xe0ea92e36ee0c574bc092425926b3bfe817ec9471afbe90b577757ee16f60fd8);

event OperatorRegistered(address indexed operator);
event OperatorDeregistrationRequested(address indexed operator);
event OperatorDeregistered(address indexed operator);
Expand Down Expand Up @@ -95,9 +98,16 @@ contract MevCommitAVSTest is Test {

function testRegisterOperator() public {

address operator = address(0x888);
bytes32 digestHash = avsDirectoryMock.calculateOperatorAVSRegistrationDigestHash({
operator: operator,
avs: address(mevCommitAVS),
salt: bytes32("salt"),
expiry: block.timestamp + 1 days
});

(uint8 v, bytes32 r, bytes32 s) = vm.sign(operatorPrivateKey, digestHash);
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature = ISignatureUtils.SignatureWithSaltAndExpiry({
signature: bytes("signature"),
signature: abi.encodePacked(r, s, v),
salt: bytes32("salt"),
expiry: block.timestamp + 1 days
});
Expand Down Expand Up @@ -133,8 +143,6 @@ contract MevCommitAVSTest is Test {
function testRequestOperatorDeregistration() public {
vm.roll(108);

address operator = address(0x888);

vm.prank(owner);
mevCommitAVS.pause();
vm.expectRevert(PausableUpgradeable.EnforcedPause.selector);
Expand Down Expand Up @@ -176,8 +184,6 @@ contract MevCommitAVSTest is Test {
function testDeregisterOperator() public {
vm.roll(11);

address operator = address(0x888);

vm.prank(owner);
mevCommitAVS.pause();
vm.expectRevert(PausableUpgradeable.EnforcedPause.selector);
Expand Down Expand Up @@ -232,7 +238,6 @@ contract MevCommitAVSTest is Test {
function testRegisterValidatorsByPodOwners() public {
vm.roll(55);

address operator = address(0x888);
address podOwner = address(0x420);
ISignatureUtils.SignatureWithExpiry memory sig = ISignatureUtils.SignatureWithExpiry({
signature: bytes("signature"),
Expand Down Expand Up @@ -332,7 +337,6 @@ contract MevCommitAVSTest is Test {

function testRequestValidatorsDeregistration() public {

address operator = address(0x888);
address podOwner = address(0x420);

bytes[] memory valPubkeys = new bytes[](2);
Expand Down Expand Up @@ -388,7 +392,6 @@ contract MevCommitAVSTest is Test {

function testDeregisterValidator() public {

address operator = address(0x888);
address podOwner = address(0x420);
bytes[] memory valPubkeys = new bytes[](1);
valPubkeys[0] = bytes("valPubkey1");
Expand Down Expand Up @@ -447,7 +450,6 @@ contract MevCommitAVSTest is Test {

function testRegisterLSTRestaker() public {

address operator = address(0x888);
address lstRestaker = address(0x34443);
address otherAcct = address(0x777);
bytes[] memory chosenVals = new bytes[](0);
Expand Down Expand Up @@ -631,7 +633,6 @@ contract MevCommitAVSTest is Test {

vm.roll(403);

address operator = address(0x888);
bytes[] memory valPubkeys2 = new bytes[](1);
valPubkeys2[0] = bytes("valPubkey1");
vm.prank(operator);
Expand Down Expand Up @@ -699,7 +700,6 @@ contract MevCommitAVSTest is Test {
assertTrue(mevCommitAVS.getValidatorRegInfo(valPubkeys[1]).freezeHeight.exists);

address lstRestaker = address(0x34443);
address operator = address(0x888);
ISignatureUtils.SignatureWithExpiry memory sig = ISignatureUtils.SignatureWithExpiry({
signature: bytes("signature"),
expiry: 10
Expand Down Expand Up @@ -933,7 +933,6 @@ contract MevCommitAVSTest is Test {
function testValidatorsWithReqDeregisteredOperatorsCannotRegister() public {
testRegisterOperator();

address operator = address(0x888);
vm.prank(operator);
mevCommitAVS.requestOperatorDeregistration(operator);

Expand Down Expand Up @@ -1012,19 +1011,28 @@ contract MevCommitAVSTest is Test {
assertTrue(mevCommitAVS.isValidatorOptedIn(valPubkeys[0]));
assertTrue(mevCommitAVS.isValidatorOptedIn(valPubkeys[1]));

address operator = address(0x888);
vm.prank(operator);
mevCommitAVS.requestOperatorDeregistration(operator);

assertFalse(mevCommitAVS.isValidatorOptedIn(valPubkeys[0]));
assertFalse(mevCommitAVS.isValidatorOptedIn(valPubkeys[1]));

address newOperator = address(0x999);
address newOperator = address(0x0c94D2aE152F29Bf68A78dc9747BEa59B6f01418);
uint256 newOperatorPrivateKey = uint256(0x61437e7186d6d418e8c3221a88ce4c4aafba32347414d113ed31c425a99085a6);
delegationManagerMock.setIsOperator(newOperator, true);

bytes32 digestHash = avsDirectoryMock.calculateOperatorAVSRegistrationDigestHash({
operator: newOperator,
avs: address(mevCommitAVS),
salt: bytes32("salt"),
expiry: block.timestamp + 1 days
});

(uint8 v, bytes32 r, bytes32 s) = vm.sign(newOperatorPrivateKey, digestHash);

vm.prank(newOperator);
ISignatureUtils.SignatureWithSaltAndExpiry memory newOperatorSigWithSalt = ISignatureUtils.SignatureWithSaltAndExpiry({
signature: bytes("signature"),
signature: abi.encodePacked(r, s, v),
salt: bytes32("salt"),
expiry: block.timestamp + 1 days
});
Expand All @@ -1046,7 +1054,6 @@ contract MevCommitAVSTest is Test {
function testDeregisteredOperatorCanStillDeregisterValidators() public {
testRegisterValidatorsByPodOwners();

address operator = address(0x888);
vm.prank(operator);
mevCommitAVS.requestOperatorDeregistration(operator);
assertTrue(mevCommitAVS.getOperatorRegInfo(operator).exists);
Expand Down
Loading