Skip to content
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
2 changes: 1 addition & 1 deletion docs/middlewareV2/AVSRegistrar.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,4 +418,4 @@ function initialize(address admin, string memory metadataURI) public initializer
*Initialization Process*:
1. Updates AVS metadata URI in the AllocationManager
2. Sets itself as the AVS registrar
3. Initiates admin transfer via PermissionController
3. Initiates admin transfer via PermissionController
4 changes: 2 additions & 2 deletions docs/middlewareV2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
The middlewareV2 architecture simplifies AVS development by:
1. Utilizing core protocol contracts for operator key storage (`KeyRegistrar`) and task verification (`BN254CertificateVerifier` and `ECDSACertificateVerifier`)
2. Utilizing core contracts for OperatorSet (ie. quorum) membership and strategy composition in the `AllocationManager`
3. Utilizing the EigenLabs-run offchain services to update stakes instead of [`avs-sync](https://github.com/Layr-Labs/avs-sync)
3. Utilizing the EigenLabs-run offchain services to update stakes instead of [`avs-sync`](https://github.com/Layr-Labs/avs-sync)

---

Expand Down Expand Up @@ -189,4 +189,4 @@ The [`AllocationManager`](https://github.com/Layr-Labs/eigenlayer-contracts/blob
See the [`AVSRegistrar`](./AVSRegistrar.md#system-diagrams) for how an AVS is initialized to the core protocol.

#### Certificate Verifier
The [`CertificateVerifier`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/main/docs/multichain/destination/CertificateVerifier.md) is responsible for verifying certificates from an offchain task, on-chain. The stakes in the certificate verifier are defined by the AVS-deployed `OperatorTableCalculator` and transported via an off-chain process run by Eigen labs. The `CertificateVerifier` contracts support two signature schemes: ECDSA for individual signatures and BN254 for aggregated signatures. See [multichain docs](core-multichain-docs) for more information.
The [`CertificateVerifier`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/main/docs/multichain/destination/CertificateVerifier.md) is responsible for verifying certificates from an offchain task, on-chain. The stakes in the certificate verifier are defined by the AVS-deployed `OperatorTableCalculator` and transported via an off-chain process run by Eigen labs. The `CertificateVerifier` contracts support two signature schemes: ECDSA for individual signatures and BN254 for aggregated signatures. See [multichain docs](core-multichain-docs) for more information.
2 changes: 1 addition & 1 deletion lib/eigenlayer-contracts
10 changes: 5 additions & 5 deletions src/middlewareV2/tableCalculator/BN254TableCalculatorBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,27 @@ abstract contract BN254TableCalculatorBase is IBN254TableCalculator {
}

/// @inheritdoc IOperatorTableCalculator
function getOperatorWeights(
function getOperatorSetWeights(
OperatorSet calldata operatorSet
) external view virtual returns (address[] memory operators, uint256[][] memory weights) {
return _getOperatorWeights(operatorSet);
}

/// @inheritdoc IOperatorTableCalculator
function getOperatorWeight(
function getOperatorWeights(
OperatorSet calldata operatorSet,
address operator
) external view virtual returns (uint256 weight) {
) external view virtual returns (uint256[] memory) {
(address[] memory operators, uint256[][] memory weights) = _getOperatorWeights(operatorSet);

// Find the index of the operator in the operators array
for (uint256 i = 0; i < operators.length; i++) {
if (operators[i] == operator) {
return weights[i][0];
return weights[i];
}
}

return 0;
return new uint256[](0);
}

/// @inheritdoc IBN254TableCalculator
Expand Down
10 changes: 5 additions & 5 deletions src/middlewareV2/tableCalculator/ECDSATableCalculatorBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,27 @@ abstract contract ECDSATableCalculatorBase is IECDSATableCalculator {
}

/// @inheritdoc IOperatorTableCalculator
function getOperatorWeights(
function getOperatorSetWeights(
OperatorSet calldata operatorSet
) external view virtual returns (address[] memory operators, uint256[][] memory weights) {
return _getOperatorWeights(operatorSet);
}

/// @inheritdoc IOperatorTableCalculator
function getOperatorWeight(
function getOperatorWeights(
OperatorSet calldata operatorSet,
address operator
) external view virtual returns (uint256 weight) {
) external view virtual returns (uint256[] memory) {
(address[] memory operators, uint256[][] memory weights) = _getOperatorWeights(operatorSet);

// Find the index of the operator in the operators array
for (uint256 i = 0; i < operators.length; i++) {
if (operators[i] == operator) {
return weights[i][0];
return weights[i];
}
}

return 0;
return new uint256[](0);
}

/**
Expand Down
32 changes: 2 additions & 30 deletions test/integration/IntegrationDeployer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol";
import "eigenlayer-contracts/src/contracts/pods/EigenPod.sol";
import "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol";
import "eigenlayer-contracts/src/contracts/permissions/PermissionController.sol";
import "eigenlayer-contracts/src/contracts/core/SlashEscrowFactory.sol";
import "eigenlayer-contracts/src/contracts/core/SlashEscrow.sol";
import "eigenlayer-contracts/src/test/mocks/ETHDepositMock.sol";

// Middleware contracts
Expand Down Expand Up @@ -64,7 +62,6 @@ abstract contract IntegrationDeployer is Test, IUserDeployer {
ETHPOSDepositMock ethPOSDeposit;
AllocationManager public allocationManager;
PermissionController permissionController;
SlashEscrowFactory slashEscrowFactory;

// Base strategy implementation in case we want to create more strategies later
StrategyBase baseStrategyImplementation;
Expand Down Expand Up @@ -191,12 +188,6 @@ abstract contract IntegrationDeployer is Test, IUserDeployer {
)
);

slashEscrowFactory = SlashEscrowFactory(
address(
new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "")
)
);

// Deploy EigenPod Contracts
pod = new EigenPod(ethPOSDeposit, eigenPodManager, "v0.0.1");

Expand All @@ -215,7 +206,7 @@ abstract contract IntegrationDeployer is Test, IUserDeployer {
"v0.0.1"
);
StrategyManager strategyManagerImplementation =
new StrategyManager(delegationManager, slashEscrowFactory, pauserRegistry, "v0.0.1");
new StrategyManager(allocationManager, delegationManager, pauserRegistry, "v0.0.1");
EigenPodManager eigenPodManagerImplementation = new EigenPodManager(
ethPOSDeposit, eigenPodBeacon, delegationManager, pauserRegistry, "v0.0.1"
);
Expand All @@ -240,21 +231,14 @@ abstract contract IntegrationDeployer is Test, IUserDeployer {

AllocationManager allocationManagerImplementation = new AllocationManager(
delegationManager,
IStrategy(address(0)), // TODO: update this to the eigenStrategy,
pauserRegistry,
permissionController,
uint32(7 days), // DEALLOCATION_DELAY
uint32(1 days), // ALLOCATION_CONFIGURATION_DELAY
"v0.0.1" // Added config parameter
);

// Deploy SlashEscrow implementation
SlashEscrow slashEscrowImpl = new SlashEscrow();

// Deploy SlashEscrowFactory implementation
SlashEscrowFactory slashEscrowFactoryImplementation = new SlashEscrowFactory(
allocationManager, strategyManager, pauserRegistry, slashEscrowImpl, "v0.0.1"
);

// Third, upgrade the proxy contracts to point to the implementations
uint256 minWithdrawalDelayBlocks = 7 days / 12 seconds;
IStrategy[] memory initializeStrategiesToSetDelayBlocks = new IStrategy[](0);
Expand Down Expand Up @@ -327,18 +311,6 @@ abstract contract IntegrationDeployer is Test, IUserDeployer {
)
);

// SlashEscrowFactory
proxyAdmin.upgradeAndCall(
ITransparentUpgradeableProxy(payable(address(slashEscrowFactory))),
address(slashEscrowFactoryImplementation),
abi.encodeWithSelector(
SlashEscrowFactory.initialize.selector,
eigenLayerReputedMultisig, // initialOwner
0, // initialPausedStatus
7 days / 12 // initialGlobalDelayBlocks (7 days worth of blocks)
)
);

// Deploy and whitelist strategies
baseStrategyImplementation = new StrategyBase(strategyManager, pauserRegistry, "v0.0.1");
for (uint256 i = 0; i < MAX_STRATEGY_COUNT; i++) {
Expand Down
17 changes: 17 additions & 0 deletions test/mocks/KeyRegistrarMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,23 @@ contract KeyRegistrarMock is IKeyRegistrar {
return abi.encode(g1Point, g2Point);
}

function getOperatorFromSigningKey(
OperatorSet memory,
/**
* operatorSet
*/
bytes calldata
)
/**
* keyData
*/
external
pure
returns (address, bool)
{
return (address(0), false);
}

receive() external payable {}
fallback() external payable {}
}
83 changes: 35 additions & 48 deletions test/unit/middlewareV2/BN254TableCalculatorBaseUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -479,10 +479,10 @@ contract BN254TableCalculatorBaseUnitTests_calculateOperatorTableBytes is
}

/**
* @title BN254TableCalculatorBaseUnitTests_getOperatorWeights
* @notice Unit tests for BN254TableCalculatorBase.getOperatorWeights
* @title BN254TableCalculatorBaseUnitTests_getOperatorSetWeights
* @notice Unit tests for BN254TableCalculatorBase.getOperatorSetWeights
*/
contract BN254TableCalculatorBaseUnitTests_getOperatorWeights is
contract BN254TableCalculatorBaseUnitTests_getOperatorSetWeights is
BN254TableCalculatorBaseUnitTests
{
function test_returnsImplementationResult() public {
Expand All @@ -498,7 +498,7 @@ contract BN254TableCalculatorBaseUnitTests_getOperatorWeights is
calculator.setMockOperatorWeights(defaultOperatorSet, expectedOperators, expectedWeights);

(address[] memory operators, uint256[][] memory weights) =
calculator.getOperatorWeights(defaultOperatorSet);
calculator.getOperatorSetWeights(defaultOperatorSet);

assertEq(operators.length, expectedOperators.length, "Operators length mismatch");
assertEq(weights.length, expectedWeights.length, "Weights length mismatch");
Expand All @@ -525,18 +525,18 @@ contract BN254TableCalculatorBaseUnitTests_getOperatorWeights is
calculator.setMockOperatorWeights(defaultOperatorSet, expectedOperators, expectedWeights);

(address[] memory operators, uint256[][] memory weights) =
calculator.getOperatorWeights(defaultOperatorSet);
calculator.getOperatorSetWeights(defaultOperatorSet);

assertEq(operators.length, numOperators, "Operators length mismatch");
assertEq(weights.length, numOperators, "Weights length mismatch");
}
}

/**
* @title BN254TableCalculatorBaseUnitTests_getOperatorWeight
* @notice Unit tests for BN254TableCalculatorBase.getOperatorWeight
* @title BN254TableCalculatorBaseUnitTests_getOperatorWeights
* @notice Unit tests for BN254TableCalculatorBase.getOperatorWeights
*/
contract BN254TableCalculatorBaseUnitTests_getOperatorWeight is
contract BN254TableCalculatorBaseUnitTests_getOperatorWeights is
BN254TableCalculatorBaseUnitTests
{
function test_operatorExists() public {
Expand All @@ -553,21 +553,17 @@ contract BN254TableCalculatorBaseUnitTests_getOperatorWeight is

calculator.setMockOperatorWeights(defaultOperatorSet, operators, weights);

assertEq(
calculator.getOperatorWeight(defaultOperatorSet, operator1),
100,
"Operator1 weight mismatch"
);
assertEq(
calculator.getOperatorWeight(defaultOperatorSet, operator2),
200,
"Operator2 weight mismatch"
);
assertEq(
calculator.getOperatorWeight(defaultOperatorSet, operator3),
300,
"Operator3 weight mismatch"
);
uint256[] memory op1Weights = calculator.getOperatorWeights(defaultOperatorSet, operator1);
assertEq(op1Weights.length, 1, "Operator1 should have 1 weight type");
assertEq(op1Weights[0], 100, "Operator1 weight mismatch");

uint256[] memory op2Weights = calculator.getOperatorWeights(defaultOperatorSet, operator2);
assertEq(op2Weights.length, 1, "Operator2 should have 1 weight type");
assertEq(op2Weights[0], 200, "Operator2 weight mismatch");

uint256[] memory op3Weights = calculator.getOperatorWeights(defaultOperatorSet, operator3);
assertEq(op3Weights.length, 1, "Operator3 should have 1 weight type");
assertEq(op3Weights[0], 300, "Operator3 weight mismatch");
}

function test_operatorDoesNotExist() public {
Expand All @@ -582,16 +578,12 @@ contract BN254TableCalculatorBaseUnitTests_getOperatorWeight is

calculator.setMockOperatorWeights(defaultOperatorSet, operators, weights);

assertEq(
calculator.getOperatorWeight(defaultOperatorSet, operator3),
0,
"Non-existent operator should return 0"
);
assertEq(
calculator.getOperatorWeight(defaultOperatorSet, address(0xdead)),
0,
"Random address should return 0"
);
uint256[] memory op3Weights = calculator.getOperatorWeights(defaultOperatorSet, operator3);
assertEq(op3Weights.length, 0, "Non-existent operator should return empty array");

uint256[] memory deadWeights =
calculator.getOperatorWeights(defaultOperatorSet, address(0xdead));
assertEq(deadWeights.length, 0, "Random address should return empty array");
}

function test_emptyOperatorSet() public {
Expand All @@ -601,14 +593,11 @@ contract BN254TableCalculatorBaseUnitTests_getOperatorWeight is

calculator.setMockOperatorWeights(defaultOperatorSet, operators, weights);

assertEq(
calculator.getOperatorWeight(defaultOperatorSet, operator1),
0,
"Should return 0 for empty set"
);
uint256[] memory op1Weights = calculator.getOperatorWeights(defaultOperatorSet, operator1);
assertEq(op1Weights.length, 0, "Should return empty array for empty set");
}

function testFuzz_getOperatorWeight(address operator, uint256 weight) public {
function testFuzz_getOperatorWeights(address operator, uint256 weight) public {
weight = bound(weight, 0, 1e18);

// Set single operator
Expand All @@ -619,17 +608,15 @@ contract BN254TableCalculatorBaseUnitTests_getOperatorWeight is

calculator.setMockOperatorWeights(defaultOperatorSet, operators, weights);

assertEq(
calculator.getOperatorWeight(defaultOperatorSet, operator), weight, "Weight mismatch"
);
uint256[] memory opWeights = calculator.getOperatorWeights(defaultOperatorSet, operator);
assertEq(opWeights.length, 1, "Should have 1 weight type");
assertEq(opWeights[0], weight, "Weight mismatch");

// Different operator should return 0
// Different operator should return empty array
address differentOperator = address(uint160(uint256(uint160(operator)) + 1));
assertEq(
calculator.getOperatorWeight(defaultOperatorSet, differentOperator),
0,
"Different operator should return 0"
);
uint256[] memory diffWeights =
calculator.getOperatorWeights(defaultOperatorSet, differentOperator);
assertEq(diffWeights.length, 0, "Different operator should return empty array");
}
}

Expand Down
Loading
Loading