From 04eb2dbf31229a1a8e9f2c7c90324ae7aa2788fd Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 3 Feb 2025 12:14:25 -0500 Subject: [PATCH 1/8] test: add utils for testing --- test/utils/BN256G2.sol | 337 +++++++++++++++++++++++++++++++++ test/utils/MockAVSDeployer.sol | 9 + test/utils/OperatorLib.sol | 88 +++++++++ 3 files changed, 434 insertions(+) create mode 100644 test/utils/BN256G2.sol create mode 100644 test/utils/OperatorLib.sol diff --git a/test/utils/BN256G2.sol b/test/utils/BN256G2.sol new file mode 100644 index 00000000..45cd34b2 --- /dev/null +++ b/test/utils/BN256G2.sol @@ -0,0 +1,337 @@ +pragma solidity ^0.8.0; + +/** + * @title Elliptic curve operations on twist points for alt_bn128 + * @author Mustafa Al-Bassam (mus@musalbas.com) + * @dev Homepage: https://github.com/musalbas/solidity-BN256G2 + */ +library BN256G2 { + uint256 internal constant FIELD_MODULUS = + 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; + uint256 internal constant TWISTBX = + 0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5; + uint256 internal constant TWISTBY = + 0x9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2; + uint256 internal constant PTXX = 0; + uint256 internal constant PTXY = 1; + uint256 internal constant PTYX = 2; + uint256 internal constant PTYY = 3; + uint256 internal constant PTZX = 4; + uint256 internal constant PTZY = 5; + + /** + * @notice Add two twist points + * @param pt1xx Coefficient 1 of x on point 1 + * @param pt1xy Coefficient 2 of x on point 1 + * @param pt1yx Coefficient 1 of y on point 1 + * @param pt1yy Coefficient 2 of y on point 1 + * @param pt2xx Coefficient 1 of x on point 2 + * @param pt2xy Coefficient 2 of x on point 2 + * @param pt2yx Coefficient 1 of y on point 2 + * @param pt2yy Coefficient 2 of y on point 2 + * @return (pt3xx, pt3xy, pt3yx, pt3yy) + */ + function ECTwistAdd( + uint256 pt1xx, + uint256 pt1xy, + uint256 pt1yx, + uint256 pt1yy, + uint256 pt2xx, + uint256 pt2xy, + uint256 pt2yx, + uint256 pt2yy + ) public view returns (uint256, uint256, uint256, uint256) { + if (pt1xx == 0 && pt1xy == 0 && pt1yx == 0 && pt1yy == 0) { + if (!(pt2xx == 0 && pt2xy == 0 && pt2yx == 0 && pt2yy == 0)) { + assert(_isOnCurve(pt2xx, pt2xy, pt2yx, pt2yy)); + } + return (pt2xx, pt2xy, pt2yx, pt2yy); + } else if (pt2xx == 0 && pt2xy == 0 && pt2yx == 0 && pt2yy == 0) { + assert(_isOnCurve(pt1xx, pt1xy, pt1yx, pt1yy)); + return (pt1xx, pt1xy, pt1yx, pt1yy); + } + + assert(_isOnCurve(pt1xx, pt1xy, pt1yx, pt1yy)); + assert(_isOnCurve(pt2xx, pt2xy, pt2yx, pt2yy)); + + uint256[6] memory pt3 = + _ECTwistAddJacobian(pt1xx, pt1xy, pt1yx, pt1yy, 1, 0, pt2xx, pt2xy, pt2yx, pt2yy, 1, 0); + + return _fromJacobian(pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]); + } + + /** + * @notice Multiply a twist point by a scalar + * @param s Scalar to multiply by + * @param pt1xx Coefficient 1 of x + * @param pt1xy Coefficient 2 of x + * @param pt1yx Coefficient 1 of y + * @param pt1yy Coefficient 2 of y + * @return (pt2xx, pt2xy, pt2yx, pt2yy) + */ + function ECTwistMul( + uint256 s, + uint256 pt1xx, + uint256 pt1xy, + uint256 pt1yx, + uint256 pt1yy + ) public view returns (uint256, uint256, uint256, uint256) { + uint256 pt1zx = 1; + if (pt1xx == 0 && pt1xy == 0 && pt1yx == 0 && pt1yy == 0) { + pt1xx = 1; + pt1yx = 1; + pt1zx = 0; + } else { + assert(_isOnCurve(pt1xx, pt1xy, pt1yx, pt1yy)); + } + + uint256[6] memory pt2 = _ECTwistMulJacobian(s, pt1xx, pt1xy, pt1yx, pt1yy, pt1zx, 0); + + return _fromJacobian(pt2[PTXX], pt2[PTXY], pt2[PTYX], pt2[PTYY], pt2[PTZX], pt2[PTZY]); + } + + /** + * @notice Get the field modulus + * @return The field modulus + */ + function GetFieldModulus() public pure returns (uint256) { + return FIELD_MODULUS; + } + + function submod(uint256 a, uint256 b, uint256 n) internal pure returns (uint256) { + return addmod(a, n - b, n); + } + + function _FQ2Mul( + uint256 xx, + uint256 xy, + uint256 yx, + uint256 yy + ) internal pure returns (uint256, uint256) { + return ( + submod(mulmod(xx, yx, FIELD_MODULUS), mulmod(xy, yy, FIELD_MODULUS), FIELD_MODULUS), + addmod(mulmod(xx, yy, FIELD_MODULUS), mulmod(xy, yx, FIELD_MODULUS), FIELD_MODULUS) + ); + } + + function _FQ2Muc(uint256 xx, uint256 xy, uint256 c) internal pure returns (uint256, uint256) { + return (mulmod(xx, c, FIELD_MODULUS), mulmod(xy, c, FIELD_MODULUS)); + } + + function _FQ2Add( + uint256 xx, + uint256 xy, + uint256 yx, + uint256 yy + ) internal pure returns (uint256, uint256) { + return (addmod(xx, yx, FIELD_MODULUS), addmod(xy, yy, FIELD_MODULUS)); + } + + function _FQ2Sub( + uint256 xx, + uint256 xy, + uint256 yx, + uint256 yy + ) internal pure returns (uint256 rx, uint256 ry) { + return (submod(xx, yx, FIELD_MODULUS), submod(xy, yy, FIELD_MODULUS)); + } + + function _FQ2Div( + uint256 xx, + uint256 xy, + uint256 yx, + uint256 yy + ) internal view returns (uint256, uint256) { + (yx, yy) = _FQ2Inv(yx, yy); + return _FQ2Mul(xx, xy, yx, yy); + } + + function _FQ2Inv(uint256 x, uint256 y) internal view returns (uint256, uint256) { + uint256 inv = _modInv( + addmod(mulmod(y, y, FIELD_MODULUS), mulmod(x, x, FIELD_MODULUS), FIELD_MODULUS), + FIELD_MODULUS + ); + return (mulmod(x, inv, FIELD_MODULUS), FIELD_MODULUS - mulmod(y, inv, FIELD_MODULUS)); + } + + function _isOnCurve( + uint256 xx, + uint256 xy, + uint256 yx, + uint256 yy + ) internal pure returns (bool) { + uint256 yyx; + uint256 yyy; + uint256 xxxx; + uint256 xxxy; + (yyx, yyy) = _FQ2Mul(yx, yy, yx, yy); + (xxxx, xxxy) = _FQ2Mul(xx, xy, xx, xy); + (xxxx, xxxy) = _FQ2Mul(xxxx, xxxy, xx, xy); + (yyx, yyy) = _FQ2Sub(yyx, yyy, xxxx, xxxy); + (yyx, yyy) = _FQ2Sub(yyx, yyy, TWISTBX, TWISTBY); + return yyx == 0 && yyy == 0; + } + + function _modInv(uint256 a, uint256 n) internal view returns (uint256 result) { + bool success; + assembly ("memory-safe") { + let freemem := mload(0x40) + mstore(freemem, 0x20) + mstore(add(freemem, 0x20), 0x20) + mstore(add(freemem, 0x40), 0x20) + mstore(add(freemem, 0x60), a) + mstore(add(freemem, 0x80), sub(n, 2)) + mstore(add(freemem, 0xA0), n) + success := staticcall(sub(gas(), 2000), 5, freemem, 0xC0, freemem, 0x20) + result := mload(freemem) + } + require(success); + } + + function _fromJacobian( + uint256 pt1xx, + uint256 pt1xy, + uint256 pt1yx, + uint256 pt1yy, + uint256 pt1zx, + uint256 pt1zy + ) internal view returns (uint256 pt2xx, uint256 pt2xy, uint256 pt2yx, uint256 pt2yy) { + uint256 invzx; + uint256 invzy; + (invzx, invzy) = _FQ2Inv(pt1zx, pt1zy); + (pt2xx, pt2xy) = _FQ2Mul(pt1xx, pt1xy, invzx, invzy); + (pt2yx, pt2yy) = _FQ2Mul(pt1yx, pt1yy, invzx, invzy); + } + + function _ECTwistAddJacobian( + uint256 pt1xx, + uint256 pt1xy, + uint256 pt1yx, + uint256 pt1yy, + uint256 pt1zx, + uint256 pt1zy, + uint256 pt2xx, + uint256 pt2xy, + uint256 pt2yx, + uint256 pt2yy, + uint256 pt2zx, + uint256 pt2zy + ) internal pure returns (uint256[6] memory pt3) { + if (pt1zx == 0 && pt1zy == 0) { + (pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]) = + (pt2xx, pt2xy, pt2yx, pt2yy, pt2zx, pt2zy); + return pt3; + } else if (pt2zx == 0 && pt2zy == 0) { + (pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]) = + (pt1xx, pt1xy, pt1yx, pt1yy, pt1zx, pt1zy); + return pt3; + } + + (pt2yx, pt2yy) = _FQ2Mul(pt2yx, pt2yy, pt1zx, pt1zy); // U1 = y2 * z1 + (pt3[PTYX], pt3[PTYY]) = _FQ2Mul(pt1yx, pt1yy, pt2zx, pt2zy); // U2 = y1 * z2 + (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt1zx, pt1zy); // V1 = x2 * z1 + (pt3[PTZX], pt3[PTZY]) = _FQ2Mul(pt1xx, pt1xy, pt2zx, pt2zy); // V2 = x1 * z2 + + if (pt2xx == pt3[PTZX] && pt2xy == pt3[PTZY]) { + if (pt2yx == pt3[PTYX] && pt2yy == pt3[PTYY]) { + (pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]) = + _ECTwistDoubleJacobian(pt1xx, pt1xy, pt1yx, pt1yy, pt1zx, pt1zy); + return pt3; + } + (pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]) = (1, 0, 1, 0, 0, 0); + return pt3; + } + + (pt2zx, pt2zy) = _FQ2Mul(pt1zx, pt1zy, pt2zx, pt2zy); // W = z1 * z2 + (pt1xx, pt1xy) = _FQ2Sub(pt2yx, pt2yy, pt3[PTYX], pt3[PTYY]); // U = U1 - U2 + (pt1yx, pt1yy) = _FQ2Sub(pt2xx, pt2xy, pt3[PTZX], pt3[PTZY]); // V = V1 - V2 + (pt1zx, pt1zy) = _FQ2Mul(pt1yx, pt1yy, pt1yx, pt1yy); // V_squared = V * V + (pt2yx, pt2yy) = _FQ2Mul(pt1zx, pt1zy, pt3[PTZX], pt3[PTZY]); // V_squared_times_V2 = V_squared * V2 + (pt1zx, pt1zy) = _FQ2Mul(pt1zx, pt1zy, pt1yx, pt1yy); // V_cubed = V * V_squared + (pt3[PTZX], pt3[PTZY]) = _FQ2Mul(pt1zx, pt1zy, pt2zx, pt2zy); // newz = V_cubed * W + (pt2xx, pt2xy) = _FQ2Mul(pt1xx, pt1xy, pt1xx, pt1xy); // U * U + (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt2zx, pt2zy); // U * U * W + (pt2xx, pt2xy) = _FQ2Sub(pt2xx, pt2xy, pt1zx, pt1zy); // U * U * W - V_cubed + (pt2zx, pt2zy) = _FQ2Muc(pt2yx, pt2yy, 2); // 2 * V_squared_times_V2 + (pt2xx, pt2xy) = _FQ2Sub(pt2xx, pt2xy, pt2zx, pt2zy); // A = U * U * W - V_cubed - 2 * V_squared_times_V2 + (pt3[PTXX], pt3[PTXY]) = _FQ2Mul(pt1yx, pt1yy, pt2xx, pt2xy); // newx = V * A + (pt1yx, pt1yy) = _FQ2Sub(pt2yx, pt2yy, pt2xx, pt2xy); // V_squared_times_V2 - A + (pt1yx, pt1yy) = _FQ2Mul(pt1xx, pt1xy, pt1yx, pt1yy); // U * (V_squared_times_V2 - A) + (pt1xx, pt1xy) = _FQ2Mul(pt1zx, pt1zy, pt3[PTYX], pt3[PTYY]); // V_cubed * U2 + (pt3[PTYX], pt3[PTYY]) = _FQ2Sub(pt1yx, pt1yy, pt1xx, pt1xy); // newy = U * (V_squared_times_V2 - A) - V_cubed * U2 + } + + function _ECTwistDoubleJacobian( + uint256 pt1xx, + uint256 pt1xy, + uint256 pt1yx, + uint256 pt1yy, + uint256 pt1zx, + uint256 pt1zy + ) + internal + pure + returns ( + uint256 pt2xx, + uint256 pt2xy, + uint256 pt2yx, + uint256 pt2yy, + uint256 pt2zx, + uint256 pt2zy + ) + { + (pt2xx, pt2xy) = _FQ2Muc(pt1xx, pt1xy, 3); // 3 * x + (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt1xx, pt1xy); // W = 3 * x * x + (pt1zx, pt1zy) = _FQ2Mul(pt1yx, pt1yy, pt1zx, pt1zy); // S = y * z + (pt2yx, pt2yy) = _FQ2Mul(pt1xx, pt1xy, pt1yx, pt1yy); // x * y + (pt2yx, pt2yy) = _FQ2Mul(pt2yx, pt2yy, pt1zx, pt1zy); // B = x * y * S + (pt1xx, pt1xy) = _FQ2Mul(pt2xx, pt2xy, pt2xx, pt2xy); // W * W + (pt2zx, pt2zy) = _FQ2Muc(pt2yx, pt2yy, 8); // 8 * B + (pt1xx, pt1xy) = _FQ2Sub(pt1xx, pt1xy, pt2zx, pt2zy); // H = W * W - 8 * B + (pt2zx, pt2zy) = _FQ2Mul(pt1zx, pt1zy, pt1zx, pt1zy); // S_squared = S * S + (pt2yx, pt2yy) = _FQ2Muc(pt2yx, pt2yy, 4); // 4 * B + (pt2yx, pt2yy) = _FQ2Sub(pt2yx, pt2yy, pt1xx, pt1xy); // 4 * B - H + (pt2yx, pt2yy) = _FQ2Mul(pt2yx, pt2yy, pt2xx, pt2xy); // W * (4 * B - H) + (pt2xx, pt2xy) = _FQ2Muc(pt1yx, pt1yy, 8); // 8 * y + (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt1yx, pt1yy); // 8 * y * y + (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt2zx, pt2zy); // 8 * y * y * S_squared + (pt2yx, pt2yy) = _FQ2Sub(pt2yx, pt2yy, pt2xx, pt2xy); // newy = W * (4 * B - H) - 8 * y * y * S_squared + (pt2xx, pt2xy) = _FQ2Muc(pt1xx, pt1xy, 2); // 2 * H + (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt1zx, pt1zy); // newx = 2 * H * S + (pt2zx, pt2zy) = _FQ2Mul(pt1zx, pt1zy, pt2zx, pt2zy); // S * S_squared + (pt2zx, pt2zy) = _FQ2Muc(pt2zx, pt2zy, 8); // newz = 8 * S * S_squared + } + + function _ECTwistMulJacobian( + uint256 d, + uint256 pt1xx, + uint256 pt1xy, + uint256 pt1yx, + uint256 pt1yy, + uint256 pt1zx, + uint256 pt1zy + ) internal pure returns (uint256[6] memory pt2) { + while (d != 0) { + if ((d & 1) != 0) { + pt2 = _ECTwistAddJacobian( + pt2[PTXX], + pt2[PTXY], + pt2[PTYX], + pt2[PTYY], + pt2[PTZX], + pt2[PTZY], + pt1xx, + pt1xy, + pt1yx, + pt1yy, + pt1zx, + pt1zy + ); + } + (pt1xx, pt1xy, pt1yx, pt1yy, pt1zx, pt1zy) = + _ECTwistDoubleJacobian(pt1xx, pt1xy, pt1yx, pt1yy, pt1zx, pt1zy); + + d = d / 2; + } + } +} \ No newline at end of file diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index e527e0f8..dd1de21d 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -53,6 +53,7 @@ import {BLSApkRegistryHarness} from "../harnesses/BLSApkRegistryHarness.sol"; import {EmptyContract} from "eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; import {StakeRegistryHarness} from "../harnesses/StakeRegistryHarness.sol"; +import {OperatorLib} from "../utils/OperatorLib.sol"; import "forge-std/Test.sol"; @@ -547,4 +548,12 @@ contract MockAVSDeployer is Test { salt: salt }); } + + function _createOperators(uint256 numOperators, uint256 startIndex) internal returns (OperatorLib.Operator[] memory) { + OperatorLib.Operator[] memory operators = new OperatorLib.Operator[](numOperators); + for (uint256 i = 0; i < numOperators; i++) { + operators[i] = OperatorLib.createOperator(string(abi.encodePacked("operator-", i + startIndex))); + } + return operators; + } } diff --git a/test/utils/OperatorLib.sol b/test/utils/OperatorLib.sol new file mode 100644 index 00000000..e67c0100 --- /dev/null +++ b/test/utils/OperatorLib.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Vm} from "forge-std/Vm.sol"; +import {BN254} from "../../../src/libraries/BN254.sol"; +import {BN256G2} from "./BN256G2.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; + +library OperatorLib { + using BN254 for *; + using Strings for uint256; + + struct Wallet { + uint256 privateKey; + address addr; + } + + struct BLSWallet { + uint256 privateKey; + BN254.G2Point publicKeyG2; + BN254.G1Point publicKeyG1; + } + + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + struct Operator { + Wallet key; + BLSWallet signingKey; + } + + function createBLSWallet(uint256 salt) internal returns (BLSWallet memory) { + uint256 privateKey = uint256(keccak256(abi.encodePacked(salt))); + BN254.G1Point memory publicKeyG1 = BN254.generatorG1().scalar_mul(privateKey); + BN254.G2Point memory publicKeyG2 = mul(privateKey); + + return BLSWallet({ + privateKey: privateKey, + publicKeyG2: publicKeyG2, + publicKeyG1: publicKeyG1 + }); + } + + function createWallet(uint256 salt) internal pure returns (Wallet memory) { + uint256 privateKey = uint256(keccak256(abi.encodePacked(salt))); + address addr = vm.addr(privateKey); + + return Wallet({ + privateKey: privateKey, + addr: addr + }); + } + + function createOperator(string memory name) internal returns (Operator memory) { + uint256 salt = uint256(keccak256(abi.encodePacked(name))); + Wallet memory vmWallet = createWallet(salt); + BLSWallet memory blsWallet = createBLSWallet(salt); + + return Operator({ + key: vmWallet, + signingKey: blsWallet + }); + } + + function mul(uint256 x) internal returns (BN254.G2Point memory g2Point) { + string[] memory inputs = new string[](5); + inputs[0] = "go"; + inputs[1] = "run"; + inputs[2] = "test/ffi/go/g2mul.go"; + inputs[3] = x.toString(); + + inputs[4] = "1"; + bytes memory res = vm.ffi(inputs); + g2Point.X[1] = abi.decode(res, (uint256)); + + inputs[4] = "2"; + res = vm.ffi(inputs); + g2Point.X[0] = abi.decode(res, (uint256)); + + inputs[4] = "3"; + res = vm.ffi(inputs); + g2Point.Y[1] = abi.decode(res, (uint256)); + + inputs[4] = "4"; + res = vm.ffi(inputs); + g2Point.Y[0] = abi.decode(res, (uint256)); + } + +} \ No newline at end of file From d7e1bffa68fd3ea2872f476891a3b058f2db8ff4 Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 3 Feb 2025 12:19:26 -0500 Subject: [PATCH 2/8] chore: fix remappings --- test/utils/OperatorLib.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/utils/OperatorLib.sol b/test/utils/OperatorLib.sol index e67c0100..082c6f03 100644 --- a/test/utils/OperatorLib.sol +++ b/test/utils/OperatorLib.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import {Vm} from "forge-std/Vm.sol"; -import {BN254} from "../../../src/libraries/BN254.sol"; +import {BN254} from "src/libraries/BN254.sol"; import {BN256G2} from "./BN256G2.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; From 338ccf07d7d41a2cac3b012266e3d0ae6a2b45f4 Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 3 Feb 2025 12:53:24 -0500 Subject: [PATCH 3/8] chore: formatting --- test/utils/BN256G2.sol | 4 +- test/utils/MockAVSDeployer.sol | 14 +++++-- ...{OperatorLib.sol => OperatorWalletLib.sol} | 42 +++++++++---------- 3 files changed, 32 insertions(+), 28 deletions(-) rename test/utils/{OperatorLib.sol => OperatorWalletLib.sol} (72%) diff --git a/test/utils/BN256G2.sol b/test/utils/BN256G2.sol index 45cd34b2..9d407b41 100644 --- a/test/utils/BN256G2.sol +++ b/test/utils/BN256G2.sol @@ -174,7 +174,7 @@ library BN256G2 { function _modInv(uint256 a, uint256 n) internal view returns (uint256 result) { bool success; - assembly ("memory-safe") { + assembly ("memory-safe") { let freemem := mload(0x40) mstore(freemem, 0x20) mstore(add(freemem, 0x20), 0x20) @@ -334,4 +334,4 @@ library BN256G2 { d = d / 2; } } -} \ No newline at end of file +} diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index dd1de21d..82cd0423 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -53,7 +53,7 @@ import {BLSApkRegistryHarness} from "../harnesses/BLSApkRegistryHarness.sol"; import {EmptyContract} from "eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; import {StakeRegistryHarness} from "../harnesses/StakeRegistryHarness.sol"; -import {OperatorLib} from "../utils/OperatorLib.sol"; +import {OperatorWalletLib} from "../utils/OperatorWalletLib.sol"; import "forge-std/Test.sol"; @@ -549,10 +549,16 @@ contract MockAVSDeployer is Test { }); } - function _createOperators(uint256 numOperators, uint256 startIndex) internal returns (OperatorLib.Operator[] memory) { - OperatorLib.Operator[] memory operators = new OperatorLib.Operator[](numOperators); + function _createOperators( + uint256 numOperators, + uint256 startIndex + ) internal returns (OperatorWalletLib.Operator[] memory) { + OperatorWalletLib.Operator[] memory operators = + new OperatorWalletLib.Operator[](numOperators); for (uint256 i = 0; i < numOperators; i++) { - operators[i] = OperatorLib.createOperator(string(abi.encodePacked("operator-", i + startIndex))); + operators[i] = OperatorWalletLib.createOperator( + string(abi.encodePacked("operator-", i + startIndex)) + ); } return operators; } diff --git a/test/utils/OperatorLib.sol b/test/utils/OperatorWalletLib.sol similarity index 72% rename from test/utils/OperatorLib.sol rename to test/utils/OperatorWalletLib.sol index 082c6f03..561eb1e3 100644 --- a/test/utils/OperatorLib.sol +++ b/test/utils/OperatorWalletLib.sol @@ -6,7 +6,7 @@ import {BN254} from "src/libraries/BN254.sol"; import {BN256G2} from "./BN256G2.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; -library OperatorLib { +library OperatorWalletLib { using BN254 for *; using Strings for uint256; @@ -21,47 +21,46 @@ library OperatorLib { BN254.G1Point publicKeyG1; } - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - struct Operator { Wallet key; BLSWallet signingKey; } - function createBLSWallet(uint256 salt) internal returns (BLSWallet memory) { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function createBLSWallet( + uint256 salt + ) internal returns (BLSWallet memory) { uint256 privateKey = uint256(keccak256(abi.encodePacked(salt))); BN254.G1Point memory publicKeyG1 = BN254.generatorG1().scalar_mul(privateKey); BN254.G2Point memory publicKeyG2 = mul(privateKey); - return BLSWallet({ - privateKey: privateKey, - publicKeyG2: publicKeyG2, - publicKeyG1: publicKeyG1 - }); + return + BLSWallet({privateKey: privateKey, publicKeyG2: publicKeyG2, publicKeyG1: publicKeyG1}); } - function createWallet(uint256 salt) internal pure returns (Wallet memory) { + function createWallet( + uint256 salt + ) internal pure returns (Wallet memory) { uint256 privateKey = uint256(keccak256(abi.encodePacked(salt))); address addr = vm.addr(privateKey); - return Wallet({ - privateKey: privateKey, - addr: addr - }); + return Wallet({privateKey: privateKey, addr: addr}); } - function createOperator(string memory name) internal returns (Operator memory) { + function createOperator( + string memory name + ) internal returns (Operator memory) { uint256 salt = uint256(keccak256(abi.encodePacked(name))); Wallet memory vmWallet = createWallet(salt); BLSWallet memory blsWallet = createBLSWallet(salt); - return Operator({ - key: vmWallet, - signingKey: blsWallet - }); + return Operator({key: vmWallet, signingKey: blsWallet}); } - function mul(uint256 x) internal returns (BN254.G2Point memory g2Point) { + function mul( + uint256 x + ) internal returns (BN254.G2Point memory g2Point) { string[] memory inputs = new string[](5); inputs[0] = "go"; inputs[1] = "run"; @@ -84,5 +83,4 @@ library OperatorLib { res = vm.ffi(inputs); g2Point.Y[0] = abi.decode(res, (uint256)); } - -} \ No newline at end of file +} From de46ee0ee2f797de3cd2a377422b5a8284bcf4b3 Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 3 Feb 2025 16:17:18 -0500 Subject: [PATCH 4/8] test: add back deployment lib and use operator keys libs --- src/RegistryCoordinator.sol | 18 + test/unit/RegistryCoordinatorUnit.t.sol | 49 ++- test/utils/CoreDeployLib.sol | 556 ++++++++++++------------ test/utils/MockAVSDeployer.sol | 8 +- test/utils/OperatorWalletLib.sol | 61 ++- 5 files changed, 390 insertions(+), 302 deletions(-) diff --git a/src/RegistryCoordinator.sol b/src/RegistryCoordinator.sol index 325722ad..41b427ab 100644 --- a/src/RegistryCoordinator.sol +++ b/src/RegistryCoordinator.sol @@ -208,6 +208,24 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato return (1 << quorumCount) - 1; } + + /** + * @notice Returns the message hash that an operator must sign to register their BLS public key. + * @param operator is the address of the operator registering their BLS public key + */ + function calculatePubkeyRegistrationMessageHash( + address operator + ) public view returns (bytes32) { + return _hashTypedDataV4( + keccak256( + abi.encode( + PUBKEY_REGISTRATION_TYPEHASH, + operator + ) + ) + ); + } + /// @dev need to override function here since its defined in both these contracts function owner() public diff --git a/test/unit/RegistryCoordinatorUnit.t.sol b/test/unit/RegistryCoordinatorUnit.t.sol index a734171a..587f838f 100644 --- a/test/unit/RegistryCoordinatorUnit.t.sol +++ b/test/unit/RegistryCoordinatorUnit.t.sol @@ -12,6 +12,7 @@ import {IBLSApkRegistryTypes} from "../../src/interfaces/IBLSApkRegistry.sol"; import {QuorumBitmapHistoryLib} from "../../src/libraries/QuorumBitmapHistoryLib.sol"; import {BitmapUtils} from "../../src/libraries/BitmapUtils.sol"; import {console} from "forge-std/console.sol"; +import {OperatorWalletLib, SigningKeyOperationsLib, OperatorKeyOperationsLib, Operator} from "../utils/OperatorWalletLib.sol"; contract RegistryCoordinatorUnitTests is MockAVSDeployer { using BN254 for BN254.G1Point; @@ -2418,52 +2419,72 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT assertTrue(registryCoordinator.operatorSetsEnabled()); } + /// function test_M2_Deregister() public { - vm.skip(true); - /// Create 2 M2 quorums _deployMockEigenLayerAndAVS(2); - address operatorToRegister = address(420); + Operator memory operatorToRegister = OperatorWalletLib.createOperator("4"); - ISignatureUtils.SignatureWithSaltAndExpiry memory emptySignature = ISignatureUtils - .SignatureWithSaltAndExpiry({signature: new bytes(0), salt: bytes32(0), expiry: 0}); + /// NOTE: resolves stack too deep + { + // Set operator shares for quorum 0 + (IStrategy strategy, ) = stakeRegistry.strategyParams(0, 0); + delegationMock.setOperatorShares(operatorToRegister.key.addr, strategy, 1 ether); + } + bytes32 salt = bytes32(uint256(1)); + uint256 expiry = block.timestamp + 1 days; + bytes32 digestHash = avsDirectory.calculateOperatorAVSRegistrationDigestHash( + operatorToRegister.key.addr, + address(registryCoordinator), + salt, + expiry + ); + bytes memory signature = OperatorKeyOperationsLib.sign(operatorToRegister.key, digestHash); + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature = ISignatureUtils + .SignatureWithSaltAndExpiry({ + signature: signature, + salt: salt, + expiry: expiry + }); + bytes32 messageHash = registryCoordinator.calculatePubkeyRegistrationMessageHash(operatorToRegister.key.addr); IBLSApkRegistryTypes.PubkeyRegistrationParams memory operatorRegisterApkParams = IBLSApkRegistryTypes.PubkeyRegistrationParams({ - pubkeyRegistrationSignature: BN254.G1Point({X: 0, Y: 0}), - pubkeyG1: BN254.G1Point({X: 0, Y: 0}), - pubkeyG2: BN254.G2Point({X: [uint256(0), uint256(0)], Y: [uint256(0), uint256(0)]}) + pubkeyRegistrationSignature: SigningKeyOperationsLib.sign(operatorToRegister.signingKey, messageHash), + pubkeyG1: operatorToRegister.signingKey.publicKeyG1, + pubkeyG2: operatorToRegister.signingKey.publicKeyG2 }); string memory socket = "socket"; // register for quorum 0 - vm.prank(operatorToRegister); + vm.prank(operatorToRegister.key.addr); registryCoordinator.registerOperator( new bytes(1), // Convert 0 to bytes1 first socket, operatorRegisterApkParams, - emptySignature + operatorSignature ); /// migrate to operator sets + vm.prank(registryCoordinatorOwner); registryCoordinator.enableOperatorSets(); /// Deregistration for m2 should for the first two operator sets - vm.prank(defaultOperator); + vm.prank(operatorToRegister.key.addr); registryCoordinator.deregisterOperator(new bytes(1)); // Verify operator was deregistered by checking their bitmap is empty - bytes32 operatorId = registryCoordinator.getOperatorId(operatorToRegister); + bytes32 operatorId = registryCoordinator.getOperatorId(operatorToRegister.key.addr); uint192 bitmap = registryCoordinator.getCurrentQuorumBitmap(operatorId); assertEq(bitmap, 0, "Operator bitmap should be empty after deregistration"); // Verify operator status is NEVER_REGISTERED ISlashingRegistryCoordinatorTypes.OperatorStatus status = - registryCoordinator.getOperatorStatus(operatorToRegister); + registryCoordinator.getOperatorStatus(operatorToRegister.key.addr); assertEq( uint8(status), - uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.NEVER_REGISTERED), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED), "Operator status should be NEVER_REGISTERED" ); } diff --git a/test/utils/CoreDeployLib.sol b/test/utils/CoreDeployLib.sol index d25dd95a..25e281fa 100644 --- a/test/utils/CoreDeployLib.sol +++ b/test/utils/CoreDeployLib.sol @@ -1,271 +1,285 @@ -// // SPDX-License-Identifier: UNLICENSED -// pragma solidity ^0.8.0; - -// import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -// import {TransparentUpgradeableProxy} from -// "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -// import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; -// import {DelegationManager} from "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; -// import {StrategyManager} from "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; -// import {AVSDirectory} from "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol"; -// import {EigenPodManager} from "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol"; -// import {RewardsCoordinator} from "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol"; -// import {StrategyBase} from "eigenlayer-contracts/src/contracts/strategies/StrategyBase.sol"; -// import {EigenPod} from "eigenlayer-contracts/src/contracts/pods/EigenPod.sol"; -// import {IETHPOSDeposit} from "eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol"; -// import {StrategyBaseTVLLimits} from "eigenlayer-contracts/src/contracts/strategies/StrategyBaseTVLLimits.sol"; -// import {PauserRegistry} from "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol"; -// import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; -// import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -// import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; -// import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; -// import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; -// import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; -// import {IEigenPodManager} from "eigenlayer-contracts/src/contracts/interfaces/IEigenPodManager.sol"; -// import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; -// import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; -// import {StrategyFactory} from "eigenlayer-contracts/src/contracts/strategies/StrategyFactory.sol"; - -// import {UpgradeableProxyLib} from "../unit/UpgradeableProxyLib.sol"; - -// library CoreDeploymentLib { -// using UpgradeableProxyLib for address; - -// struct StrategyManagerConfig { -// uint256 initPausedStatus; -// uint256 initWithdrawalDelayBlocks; -// } - -// struct DelegationManagerConfig { -// uint256 initPausedStatus; -// IStrategy[] strategies; -// uint256 minWithdrawalDelayBlocks; -// uint256[] withdrawalDelayBlocks; - -// } - -// struct EigenPodManagerConfig { -// uint256 initPausedStatus; -// } - -// struct RewardsCoordinatorConfig { -// uint256 initPausedStatus; -// uint256 maxRewardsDuration; -// uint256 maxRetroactiveLength; -// uint256 maxFutureLength; -// uint256 genesisRewardsTimestamp; -// address updater; -// uint256 activationDelay; -// uint256 calculationIntervalSeconds; -// uint256 globalOperatorCommissionBips; -// } - -// struct StrategyFactoryConfig { -// uint256 initPausedStatus; -// } - -// struct DeploymentConfigData { -// StrategyManagerConfig strategyManager; -// DelegationManagerConfig delegationManager; -// EigenPodManagerConfig eigenPodManager; -// RewardsCoordinatorConfig rewardsCoordinator; -// StrategyFactoryConfig strategyFactory; -// } - -// struct DeploymentData { -// address delegationManager; -// address avsDirectory; -// address strategyManager; -// address eigenPodManager; -// address rewardsCoordinator; -// address eigenPodBeacon; -// address pauserRegistry; -// address strategyFactory; -// address strategyBeacon; -// } - -// function deployContracts( -// address proxyAdmin, -// DeploymentConfigData memory configData -// ) internal returns (DeploymentData memory) { -// DeploymentData memory result; - -// result.delegationManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); -// result.avsDirectory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); -// result.strategyManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); -// result.eigenPodManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); -// result.rewardsCoordinator = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); -// result.eigenPodBeacon = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); -// result.pauserRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); -// result.strategyFactory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - -// // Deploy the implementation contracts, using the proxy contracts as inputs -// address delegationManagerImpl = address( -// new DelegationManager( -// IStrategyManager(result.strategyManager), -// IEigenPodManager(result.eigenPodManager) -// ) -// ); -// address avsDirectoryImpl = -// address(new AVSDirectory(IDelegationManager(result.delegationManager))); - -// address strategyManagerImpl = address( -// new StrategyManager( -// IDelegationManager(result.delegationManager), -// IEigenPodManager(result.eigenPodManager) -// ) -// ); - -// address strategyFactoryImpl = -// address(new StrategyFactory(IStrategyManager(result.strategyManager))); - -// address ethPOSDeposit; -// if (block.chainid == 1) { -// ethPOSDeposit = 0x00000000219ab540356cBB839Cbe05303d7705Fa; -// } else { -// // For non-mainnet chains, you might want to deploy a mock or read from a config -// // This assumes you have a similar config setup as in M2_Deploy_From_Scratch.s.sol -// /// TODO: Handle Eth pos -// } - -// address eigenPodManagerImpl = address( -// new EigenPodManager( -// IETHPOSDeposit(ethPOSDeposit), -// IBeacon(result.eigenPodBeacon), -// IStrategyManager(result.strategyManager), -// IDelegationManager(result.delegationManager) -// ) -// ); - -// /// TODO: Get actual values -// uint32 CALCULATION_INTERVAL_SECONDS = 1 days; -// uint32 MAX_REWARDS_DURATION = 1 days; -// uint32 MAX_RETROACTIVE_LENGTH = 1; -// uint32 MAX_FUTURE_LENGTH = 1; -// uint32 GENESIS_REWARDS_TIMESTAMP = 10 days; -// address rewardsCoordinatorImpl = address( -// new RewardsCoordinator( -// IDelegationManager(result.delegationManager), -// IStrategyManager(result.strategyManager), -// CALCULATION_INTERVAL_SECONDS, -// MAX_REWARDS_DURATION, -// MAX_RETROACTIVE_LENGTH, -// MAX_FUTURE_LENGTH, -// GENESIS_REWARDS_TIMESTAMP -// ) -// ); - -// /// TODO: Get actual genesis time -// uint64 GENESIS_TIME = 1_564_000; - -// address eigenPodImpl = address( -// new EigenPod( -// IETHPOSDeposit(ethPOSDeposit), -// IEigenPodManager(result.eigenPodManager), -// GENESIS_TIME -// ) -// ); -// address eigenPodBeaconImpl = address(new UpgradeableBeacon(eigenPodImpl)); -// address baseStrategyImpl = -// address(new StrategyBase(IStrategyManager(result.strategyManager))); -// /// TODO: PauserRegistry isn't upgradeable -// address pauserRegistryImpl = address( -// new PauserRegistry( -// new address[](0), // Empty array for pausers -// proxyAdmin // ProxyAdmin as the unpauser -// ) -// ); - -// // Deploy and configure the strategy beacon -// result.strategyBeacon = address(new UpgradeableBeacon(baseStrategyImpl)); - -// // Upgrade contracts -// /// TODO: Get from config -// bytes memory upgradeCall = abi.encodeWithSelector( /// TODO: Fix abi.encodeCall was failing Cannot implicitly convert component at position 4 from "IStrategy[]" to "IStrategy[]" -// DelegationManager.initialize.selector, -// proxyAdmin, // initialOwner -// IPauserRegistry(result.pauserRegistry), // _pauserRegistry -// configData.delegationManager.initPausedStatus, // initialPausedStatus -// configData.delegationManager.minWithdrawalDelayBlocks, // _minWithdrawalDelayBlocks -// configData.delegationManager.strategies, // _strategies -// configData.delegationManager.withdrawalDelayBlocks // _withdrawalDelayBlocks -// ); -// UpgradeableProxyLib.upgradeAndCall( -// result.delegationManager, delegationManagerImpl, upgradeCall -// ); - -// // Upgrade StrategyManager contract -// upgradeCall = abi.encodeCall( -// StrategyManager.initialize, -// ( -// proxyAdmin, // initialOwner -// result.strategyFactory, // initialStrategyWhitelister -// IPauserRegistry(result.pauserRegistry), // _pauserRegistry -// configData.strategyManager.initPausedStatus // initialPausedStatus -// ) -// ); -// UpgradeableProxyLib.upgradeAndCall(result.strategyManager, strategyManagerImpl, upgradeCall); - -// // Upgrade StrategyFactory contract -// upgradeCall = abi.encodeCall( -// StrategyFactory.initialize, -// ( -// proxyAdmin, // initialOwner -// IPauserRegistry(result.pauserRegistry), // _pauserRegistry -// configData.strategyFactory.initPausedStatus, // initialPausedStatus -// IBeacon(result.strategyBeacon) -// ) -// ); -// UpgradeableProxyLib.upgradeAndCall(result.strategyFactory, strategyFactoryImpl, upgradeCall); - -// // Upgrade EigenPodManager contract -// upgradeCall = abi.encodeCall( -// EigenPodManager.initialize, -// ( -// proxyAdmin, // initialOwner -// IPauserRegistry(result.pauserRegistry), // _pauserRegistry -// configData.eigenPodManager.initPausedStatus // initialPausedStatus -// ) -// ); -// UpgradeableProxyLib.upgradeAndCall(result.eigenPodManager, eigenPodManagerImpl, upgradeCall); - -// // Upgrade AVSDirectory contract -// upgradeCall = abi.encodeCall( -// AVSDirectory.initialize, -// ( -// proxyAdmin, // initialOwner -// IPauserRegistry(result.pauserRegistry), // _pauserRegistry -// 0 // TODO: AVS Missing configinitialPausedStatus -// ) -// ); -// UpgradeableProxyLib.upgradeAndCall(result.avsDirectory, avsDirectoryImpl, upgradeCall); - -// // Upgrade RewardsCoordinator contract -// upgradeCall = abi.encodeCall( -// RewardsCoordinator.initialize, -// ( -// proxyAdmin, // initialOwner -// IPauserRegistry(result.pauserRegistry), // _pauserRegistry -// configData.rewardsCoordinator.initPausedStatus, // initialPausedStatus -// /// TODO: is there a setter and is this expected? -// address(0), // rewards updater -// uint32(configData.rewardsCoordinator.activationDelay), // _activationDelay -// uint16(configData.rewardsCoordinator.globalOperatorCommissionBips) // _globalCommissionBips -// ) -// ); -// UpgradeableProxyLib.upgradeAndCall( -// result.rewardsCoordinator, rewardsCoordinatorImpl, upgradeCall -// ); - -// // Upgrade EigenPod contract -// upgradeCall = abi.encodeCall( -// EigenPod.initialize, -// // TODO: Double check this -// (address(result.eigenPodManager)) // _podOwner -// ); -// UpgradeableProxyLib.upgradeAndCall(result.eigenPodBeacon, eigenPodImpl, upgradeCall); - -// return result; -// } - -// } +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; +import {DelegationManager} from "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; +import {StrategyManager} from "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; +import {AVSDirectory} from "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol"; +import {EigenPodManager} from "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol"; +import {RewardsCoordinator} from "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol"; +import {StrategyBase} from "eigenlayer-contracts/src/contracts/strategies/StrategyBase.sol"; +import {EigenPod} from "eigenlayer-contracts/src/contracts/pods/EigenPod.sol"; +import {IETHPOSDeposit} from "eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol"; +import {StrategyBaseTVLLimits} from "eigenlayer-contracts/src/contracts/strategies/StrategyBaseTVLLimits.sol"; +import {PauserRegistry} from "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol"; +import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; +import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; +import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; +import {IEigenPodManager} from "eigenlayer-contracts/src/contracts/interfaces/IEigenPodManager.sol"; +import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; +import {StrategyFactory} from "eigenlayer-contracts/src/contracts/strategies/StrategyFactory.sol"; +import {IPermissionController} from "eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol"; +import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol"; + +import {UpgradeableProxyLib} from "../unit/UpgradeableProxyLib.sol"; + +library CoreDeploymentLib { + using UpgradeableProxyLib for address; + + struct StrategyManagerConfig { + uint256 initPausedStatus; + address initialOwner; + address initialStrategyWhitelister; + } + + struct DelegationManagerConfig { + uint256 initPausedStatus; + address initialOwner; + uint32 minWithdrawalDelayBlocks; + } + + struct EigenPodManagerConfig { + uint256 initPausedStatus; + address initialOwner; + } + + struct AllocationManagerConfig { + uint256 initPausedStatus; + address initialOwner; + uint32 deallocationDelay; + uint32 allocationConfigurationDelay; + } + + struct StrategyFactoryConfig { + uint256 initPausedStatus; + address initialOwner; + } + + struct RewardsCoordinatorConfig { + uint256 initPausedStatus; + address initialOwner; + address rewardsUpdater; + uint32 activationDelay; + uint16 defaultSplitBips; + uint32 calculationIntervalSeconds; + uint32 maxRewardsDuration; + uint32 maxRetroactiveLength; + uint32 maxFutureLength; + uint32 genesisRewardsTimestamp; + } + + struct DeploymentConfigData { + StrategyManagerConfig strategyManager; + DelegationManagerConfig delegationManager; + EigenPodManagerConfig eigenPodManager; + AllocationManagerConfig allocationManager; + StrategyFactoryConfig strategyFactory; + RewardsCoordinatorConfig rewardsCoordinator; + address permissionController; + } + + struct DeploymentData { + address delegationManager; + address avsDirectory; + address strategyManager; + address eigenPodManager; + address allocationManager; + address eigenPodBeacon; + address pauserRegistry; + address strategyFactory; + address strategyBeacon; + address rewardsCoordinator; + } + + function deployContracts( + address proxyAdmin, + DeploymentConfigData memory configData + ) internal returns (DeploymentData memory) { + DeploymentData memory result; + + // Deploy proxy contracts + result.delegationManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.avsDirectory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.strategyManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.eigenPodManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.allocationManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.eigenPodBeacon = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.pauserRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.strategyFactory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.rewardsCoordinator = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + + // Deploy implementation contracts + address strategyManagerImpl = address( + new StrategyManager( + IDelegationManager(result.delegationManager), + IPauserRegistry(result.pauserRegistry) + ) + ); + + address allocationManagerImpl = address( + new AllocationManager( + IDelegationManager(result.delegationManager), + IPauserRegistry(result.pauserRegistry), + IPermissionController(configData.permissionController), + configData.allocationManager.deallocationDelay, + configData.allocationManager.allocationConfigurationDelay + ) + ); + + address delegationManagerImpl = address( + new DelegationManager( + IStrategyManager(result.strategyManager), + IEigenPodManager(result.eigenPodManager), + IAllocationManager(result.allocationManager), + IPauserRegistry(result.pauserRegistry), + IPermissionController(configData.permissionController), + configData.delegationManager.minWithdrawalDelayBlocks + ) + ); + + address avsDirectoryImpl = address( + new AVSDirectory( + IDelegationManager(result.delegationManager), + IPauserRegistry(result.pauserRegistry) + ) + ); + + address ethPOSDeposit; + if (block.chainid == 1) { + ethPOSDeposit = 0x00000000219ab540356cBB839Cbe05303d7705Fa; + } else { + // For non-mainnet chains, deploy a mock + /// TODO: Handle Eth pos deposit contract + ethPOSDeposit = address(0); + } + + address eigenPodManagerImpl = address( + new EigenPodManager( + IETHPOSDeposit(ethPOSDeposit), + IBeacon(result.eigenPodBeacon), + IDelegationManager(result.delegationManager), + IPauserRegistry(result.pauserRegistry) + ) + ); + + address eigenPodImpl = address( + new EigenPod( + IETHPOSDeposit(ethPOSDeposit), + IEigenPodManager(result.eigenPodManager), + uint64(block.timestamp) // Use current timestamp as genesis time for testing + ) + ); + + address eigenPodBeaconImpl = address(new UpgradeableBeacon(eigenPodImpl)); + + address baseStrategyImpl = address( + new StrategyBase( + IStrategyManager(result.strategyManager), + IPauserRegistry(result.pauserRegistry) + ) + ); + + address strategyFactoryImpl = address( + new StrategyFactory( + IStrategyManager(result.strategyManager), + IPauserRegistry(result.pauserRegistry) + ) + ); + + address rewardsCoordinatorImpl = address( + new RewardsCoordinator( + IDelegationManager(result.delegationManager), + IStrategyManager(result.strategyManager), + IAllocationManager(result.allocationManager), + IPauserRegistry(result.pauserRegistry), + IPermissionController(configData.permissionController), + configData.rewardsCoordinator.calculationIntervalSeconds, + configData.rewardsCoordinator.maxRewardsDuration, + configData.rewardsCoordinator.maxRetroactiveLength, + configData.rewardsCoordinator.maxFutureLength, + configData.rewardsCoordinator.genesisRewardsTimestamp + ) + ); + + // Deploy and configure the strategy beacon + result.strategyBeacon = address(new UpgradeableBeacon(baseStrategyImpl)); + + // Initialize contracts + bytes memory upgradeCall = abi.encodeCall( + StrategyManager.initialize, + ( + configData.strategyManager.initialOwner, + configData.strategyManager.initialStrategyWhitelister, + configData.strategyManager.initPausedStatus + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.strategyManager, strategyManagerImpl, upgradeCall); + + upgradeCall = abi.encodeCall( + DelegationManager.initialize, + ( + configData.delegationManager.initialOwner, + configData.delegationManager.initPausedStatus + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.delegationManager, delegationManagerImpl, upgradeCall); + + upgradeCall = abi.encodeCall( + AllocationManager.initialize, + ( + configData.allocationManager.initialOwner, + configData.allocationManager.initPausedStatus + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.allocationManager, allocationManagerImpl, upgradeCall); + + upgradeCall = abi.encodeCall( + AVSDirectory.initialize, + ( + proxyAdmin, // initialOwner + 0 // initialPausedStatus + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.avsDirectory, avsDirectoryImpl, upgradeCall); + + upgradeCall = abi.encodeCall( + EigenPodManager.initialize, + ( + configData.eigenPodManager.initialOwner, + configData.eigenPodManager.initPausedStatus + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.eigenPodManager, eigenPodManagerImpl, upgradeCall); + + upgradeCall = abi.encodeCall( + StrategyFactory.initialize, + ( + configData.strategyFactory.initialOwner, + configData.strategyFactory.initPausedStatus, + IBeacon(result.strategyBeacon) + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.strategyFactory, strategyFactoryImpl, upgradeCall); + + upgradeCall = abi.encodeCall( + RewardsCoordinator.initialize, + ( + configData.rewardsCoordinator.initialOwner, + configData.rewardsCoordinator.initPausedStatus, + configData.rewardsCoordinator.rewardsUpdater, + configData.rewardsCoordinator.activationDelay, + configData.rewardsCoordinator.defaultSplitBips + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.rewardsCoordinator, rewardsCoordinatorImpl, upgradeCall); + + return result; + } +} diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index 82cd0423..358ff700 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -53,7 +53,7 @@ import {BLSApkRegistryHarness} from "../harnesses/BLSApkRegistryHarness.sol"; import {EmptyContract} from "eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; import {StakeRegistryHarness} from "../harnesses/StakeRegistryHarness.sol"; -import {OperatorWalletLib} from "../utils/OperatorWalletLib.sol"; +import {OperatorWalletLib, Operator} from "../utils/OperatorWalletLib.sol"; import "forge-std/Test.sol"; @@ -552,9 +552,9 @@ contract MockAVSDeployer is Test { function _createOperators( uint256 numOperators, uint256 startIndex - ) internal returns (OperatorWalletLib.Operator[] memory) { - OperatorWalletLib.Operator[] memory operators = - new OperatorWalletLib.Operator[](numOperators); + ) internal returns (Operator[] memory) { + Operator[] memory operators = + new Operator[](numOperators); for (uint256 i = 0; i < numOperators; i++) { operators[i] = OperatorWalletLib.createOperator( string(abi.encodePacked("operator-", i + startIndex)) diff --git a/test/utils/OperatorWalletLib.sol b/test/utils/OperatorWalletLib.sol index 561eb1e3..c33931a2 100644 --- a/test/utils/OperatorWalletLib.sol +++ b/test/utils/OperatorWalletLib.sol @@ -6,26 +6,61 @@ import {BN254} from "src/libraries/BN254.sol"; import {BN256G2} from "./BN256G2.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; -library OperatorWalletLib { - using BN254 for *; - using Strings for uint256; +struct Wallet { + uint256 privateKey; + address addr; +} - struct Wallet { - uint256 privateKey; - address addr; +struct BLSWallet { + uint256 privateKey; + BN254.G2Point publicKeyG2; + BN254.G1Point publicKeyG1; +} + +struct Operator { + Wallet key; + BLSWallet signingKey; +} + +library OperatorKeyOperationsLib { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + function sign( + Wallet memory wallet, + bytes32 digest + ) internal pure returns (bytes memory) { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(wallet.privateKey, digest); + return abi.encodePacked(r, s, v); } +} + +library SigningKeyOperationsLib { + using BN254 for BN254.G1Point; + + function sign( + BLSWallet memory blsWallet, + bytes32 messageHash + ) internal view returns (BN254.G1Point memory) { + // Hash the message to a point on G1 + BN254.G1Point memory messagePoint = BN254.hashToG1(messageHash); - struct BLSWallet { - uint256 privateKey; - BN254.G2Point publicKeyG2; - BN254.G1Point publicKeyG1; + // Sign by multiplying the hashed message point with the private key + return messagePoint.scalar_mul(blsWallet.privateKey); } - struct Operator { - Wallet key; - BLSWallet signingKey; + function aggregate( + BN254.G2Point memory pk1, + BN254.G2Point memory pk2 + ) internal view returns (BN254.G2Point memory apk) { + (apk.X[0], apk.X[1], apk.Y[0], apk.Y[1]) = + BN256G2.ECTwistAdd(pk1.X[0], pk1.X[1], pk1.Y[0], pk1.Y[1], pk2.X[0], pk2.X[1], pk2.Y[0], pk2.Y[1]); } +} + +library OperatorWalletLib { + using BN254 for *; + using Strings for uint256; + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); function createBLSWallet( From 1eb23e4f4aa38f881d6a02e378535c2108df28eb Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 3 Feb 2025 16:22:58 -0500 Subject: [PATCH 5/8] fix: core deployment lib for tests --- test/utils/CoreDeployLib.sol | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/test/utils/CoreDeployLib.sol b/test/utils/CoreDeployLib.sol index 25e281fa..cf459fa3 100644 --- a/test/utils/CoreDeployLib.sol +++ b/test/utils/CoreDeployLib.sol @@ -27,6 +27,7 @@ import {StrategyFactory} from "eigenlayer-contracts/src/contracts/strategies/Str import {IPermissionController} from "eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol"; import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol"; +import {PermissionController} from "eigenlayer-contracts/src/contracts/permissions/PermissionController.sol"; import {UpgradeableProxyLib} from "../unit/UpgradeableProxyLib.sol"; @@ -82,7 +83,6 @@ library CoreDeploymentLib { AllocationManagerConfig allocationManager; StrategyFactoryConfig strategyFactory; RewardsCoordinatorConfig rewardsCoordinator; - address permissionController; } struct DeploymentData { @@ -96,6 +96,7 @@ library CoreDeploymentLib { address strategyFactory; address strategyBeacon; address rewardsCoordinator; + address permissionController; } function deployContracts( @@ -114,8 +115,12 @@ library CoreDeploymentLib { result.pauserRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); result.strategyFactory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); result.rewardsCoordinator = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.permissionController = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); // Deploy implementation contracts + address permissionControllerImpl = address(new PermissionController()); + + address strategyManagerImpl = address( new StrategyManager( IDelegationManager(result.delegationManager), @@ -127,7 +132,7 @@ library CoreDeploymentLib { new AllocationManager( IDelegationManager(result.delegationManager), IPauserRegistry(result.pauserRegistry), - IPermissionController(configData.permissionController), + IPermissionController(result.permissionController), configData.allocationManager.deallocationDelay, configData.allocationManager.allocationConfigurationDelay ) @@ -139,7 +144,7 @@ library CoreDeploymentLib { IEigenPodManager(result.eigenPodManager), IAllocationManager(result.allocationManager), IPauserRegistry(result.pauserRegistry), - IPermissionController(configData.permissionController), + IPermissionController(result.permissionController), configData.delegationManager.minWithdrawalDelayBlocks ) ); @@ -199,7 +204,7 @@ library CoreDeploymentLib { IStrategyManager(result.strategyManager), IAllocationManager(result.allocationManager), IPauserRegistry(result.pauserRegistry), - IPermissionController(configData.permissionController), + IPermissionController(result.permissionController), configData.rewardsCoordinator.calculationIntervalSeconds, configData.rewardsCoordinator.maxRewardsDuration, configData.rewardsCoordinator.maxRetroactiveLength, @@ -211,8 +216,11 @@ library CoreDeploymentLib { // Deploy and configure the strategy beacon result.strategyBeacon = address(new UpgradeableBeacon(baseStrategyImpl)); + UpgradeableProxyLib.upgrade(result.permissionController, permissionControllerImpl); // Initialize contracts - bytes memory upgradeCall = abi.encodeCall( + bytes memory upgradeCall; + + upgradeCall = abi.encodeCall( StrategyManager.initialize, ( configData.strategyManager.initialOwner, @@ -220,6 +228,10 @@ library CoreDeploymentLib { configData.strategyManager.initPausedStatus ) ); + + // Upgrade the eigenPodBeacon with the eigenPodBeaconImpl + UpgradeableProxyLib.upgrade(result.eigenPodBeacon, eigenPodBeaconImpl); + UpgradeableProxyLib.upgradeAndCall(result.strategyManager, strategyManagerImpl, upgradeCall); upgradeCall = abi.encodeCall( From aa601c692ef49861fd7e89cdf5edf636acd2f650 Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 3 Feb 2025 16:28:26 -0500 Subject: [PATCH 6/8] test: clean up config structs for helper lib --- test/utils/CoreDeployLib.sol | 51 +++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/test/utils/CoreDeployLib.sol b/test/utils/CoreDeployLib.sol index cf459fa3..fe527304 100644 --- a/test/utils/CoreDeployLib.sol +++ b/test/utils/CoreDeployLib.sol @@ -63,6 +63,11 @@ library CoreDeploymentLib { address initialOwner; } + struct AVSDirectoryConfig { + uint256 initPausedStatus; + address initialOwner; + } + struct RewardsCoordinatorConfig { uint256 initPausedStatus; address initialOwner; @@ -76,6 +81,14 @@ library CoreDeploymentLib { uint32 genesisRewardsTimestamp; } + struct ETHPOSDepositConfig { + address ethPOSDepositAddress; + } + + struct EigenPodConfig { + uint64 genesisTimestamp; + } + struct DeploymentConfigData { StrategyManagerConfig strategyManager; DelegationManagerConfig delegationManager; @@ -83,6 +96,9 @@ library CoreDeploymentLib { AllocationManagerConfig allocationManager; StrategyFactoryConfig strategyFactory; RewardsCoordinatorConfig rewardsCoordinator; + AVSDirectoryConfig avsDirectory; + ETHPOSDepositConfig ethPOSDeposit; + EigenPodConfig eigenPod; } struct DeploymentData { @@ -102,9 +118,7 @@ library CoreDeploymentLib { function deployContracts( address proxyAdmin, DeploymentConfigData memory configData - ) internal returns (DeploymentData memory) { - DeploymentData memory result; - + ) internal returns (DeploymentData memory result) { // Deploy proxy contracts result.delegationManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); result.avsDirectory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); @@ -120,7 +134,6 @@ library CoreDeploymentLib { // Deploy implementation contracts address permissionControllerImpl = address(new PermissionController()); - address strategyManagerImpl = address( new StrategyManager( IDelegationManager(result.delegationManager), @@ -156,13 +169,13 @@ library CoreDeploymentLib { ) ); - address ethPOSDeposit; - if (block.chainid == 1) { - ethPOSDeposit = 0x00000000219ab540356cBB839Cbe05303d7705Fa; - } else { - // For non-mainnet chains, deploy a mock - /// TODO: Handle Eth pos deposit contract - ethPOSDeposit = address(0); + address ethPOSDeposit = configData.ethPOSDeposit.ethPOSDepositAddress; + if (ethPOSDeposit == address(0)) { + if (block.chainid == 1) { + ethPOSDeposit = 0x00000000219ab540356cBB839Cbe05303d7705Fa; + } else { + revert("DEPLOY_MOCK_ETHPOS_CONTRACT"); + } } address eigenPodManagerImpl = address( @@ -178,7 +191,7 @@ library CoreDeploymentLib { new EigenPod( IETHPOSDeposit(ethPOSDeposit), IEigenPodManager(result.eigenPodManager), - uint64(block.timestamp) // Use current timestamp as genesis time for testing + configData.eigenPod.genesisTimestamp == 0 ? uint64(block.timestamp) : configData.eigenPod.genesisTimestamp // Use configured timestamp or current timestamp as fallback ) ); @@ -213,11 +226,13 @@ library CoreDeploymentLib { ) ); - // Deploy and configure the strategy beacon result.strategyBeacon = address(new UpgradeableBeacon(baseStrategyImpl)); + // Upgrade contracts + UpgradeableProxyLib.upgrade(result.eigenPodBeacon, eigenPodBeaconImpl); + UpgradeableProxyLib.upgrade(result.permissionController, permissionControllerImpl); - // Initialize contracts + bytes memory upgradeCall; upgradeCall = abi.encodeCall( @@ -229,8 +244,6 @@ library CoreDeploymentLib { ) ); - // Upgrade the eigenPodBeacon with the eigenPodBeaconImpl - UpgradeableProxyLib.upgrade(result.eigenPodBeacon, eigenPodBeaconImpl); UpgradeableProxyLib.upgradeAndCall(result.strategyManager, strategyManagerImpl, upgradeCall); @@ -255,10 +268,11 @@ library CoreDeploymentLib { upgradeCall = abi.encodeCall( AVSDirectory.initialize, ( - proxyAdmin, // initialOwner - 0 // initialPausedStatus + configData.avsDirectory.initialOwner, + configData.avsDirectory.initPausedStatus ) ); + UpgradeableProxyLib.upgradeAndCall(result.avsDirectory, avsDirectoryImpl, upgradeCall); upgradeCall = abi.encodeCall( @@ -290,6 +304,7 @@ library CoreDeploymentLib { configData.rewardsCoordinator.defaultSplitBips ) ); + UpgradeableProxyLib.upgradeAndCall(result.rewardsCoordinator, rewardsCoordinatorImpl, upgradeCall); return result; From 2ddc38c78672990ac2c8119c6ed7f9199f70d731 Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 3 Feb 2025 16:30:28 -0500 Subject: [PATCH 7/8] chore: forge fmt --- src/RegistryCoordinator.sol | 10 +---- test/unit/RegistryCoordinatorUnit.t.sol | 27 ++++++------ test/utils/CoreDeployLib.sol | 57 +++++++++++++------------ test/utils/MockAVSDeployer.sol | 3 +- test/utils/OperatorWalletLib.sol | 12 +++--- 5 files changed, 51 insertions(+), 58 deletions(-) diff --git a/src/RegistryCoordinator.sol b/src/RegistryCoordinator.sol index 41b427ab..c1970c08 100644 --- a/src/RegistryCoordinator.sol +++ b/src/RegistryCoordinator.sol @@ -208,7 +208,6 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato return (1 << quorumCount) - 1; } - /** * @notice Returns the message hash that an operator must sign to register their BLS public key. * @param operator is the address of the operator registering their BLS public key @@ -216,14 +215,7 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato function calculatePubkeyRegistrationMessageHash( address operator ) public view returns (bytes32) { - return _hashTypedDataV4( - keccak256( - abi.encode( - PUBKEY_REGISTRATION_TYPEHASH, - operator - ) - ) - ); + return _hashTypedDataV4(keccak256(abi.encode(PUBKEY_REGISTRATION_TYPEHASH, operator))); } /// @dev need to override function here since its defined in both these contracts diff --git a/test/unit/RegistryCoordinatorUnit.t.sol b/test/unit/RegistryCoordinatorUnit.t.sol index 587f838f..3e0208bc 100644 --- a/test/unit/RegistryCoordinatorUnit.t.sol +++ b/test/unit/RegistryCoordinatorUnit.t.sol @@ -12,7 +12,12 @@ import {IBLSApkRegistryTypes} from "../../src/interfaces/IBLSApkRegistry.sol"; import {QuorumBitmapHistoryLib} from "../../src/libraries/QuorumBitmapHistoryLib.sol"; import {BitmapUtils} from "../../src/libraries/BitmapUtils.sol"; import {console} from "forge-std/console.sol"; -import {OperatorWalletLib, SigningKeyOperationsLib, OperatorKeyOperationsLib, Operator} from "../utils/OperatorWalletLib.sol"; +import { + OperatorWalletLib, + SigningKeyOperationsLib, + OperatorKeyOperationsLib, + Operator +} from "../utils/OperatorWalletLib.sol"; contract RegistryCoordinatorUnitTests is MockAVSDeployer { using BN254 for BN254.G1Point; @@ -2428,29 +2433,25 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT /// NOTE: resolves stack too deep { // Set operator shares for quorum 0 - (IStrategy strategy, ) = stakeRegistry.strategyParams(0, 0); + (IStrategy strategy,) = stakeRegistry.strategyParams(0, 0); delegationMock.setOperatorShares(operatorToRegister.key.addr, strategy, 1 ether); } bytes32 salt = bytes32(uint256(1)); uint256 expiry = block.timestamp + 1 days; bytes32 digestHash = avsDirectory.calculateOperatorAVSRegistrationDigestHash( - operatorToRegister.key.addr, - address(registryCoordinator), - salt, - expiry + operatorToRegister.key.addr, address(registryCoordinator), salt, expiry ); bytes memory signature = OperatorKeyOperationsLib.sign(operatorToRegister.key, digestHash); ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature = ISignatureUtils - .SignatureWithSaltAndExpiry({ - signature: signature, - salt: salt, - expiry: expiry - }); + .SignatureWithSaltAndExpiry({signature: signature, salt: salt, expiry: expiry}); - bytes32 messageHash = registryCoordinator.calculatePubkeyRegistrationMessageHash(operatorToRegister.key.addr); + bytes32 messageHash = + registryCoordinator.calculatePubkeyRegistrationMessageHash(operatorToRegister.key.addr); IBLSApkRegistryTypes.PubkeyRegistrationParams memory operatorRegisterApkParams = IBLSApkRegistryTypes.PubkeyRegistrationParams({ - pubkeyRegistrationSignature: SigningKeyOperationsLib.sign(operatorToRegister.signingKey, messageHash), + pubkeyRegistrationSignature: SigningKeyOperationsLib.sign( + operatorToRegister.signingKey, messageHash + ), pubkeyG1: operatorToRegister.signingKey.publicKeyG1, pubkeyG2: operatorToRegister.signingKey.publicKeyG2 }); diff --git a/test/utils/CoreDeployLib.sol b/test/utils/CoreDeployLib.sol index fe527304..0c0f65be 100644 --- a/test/utils/CoreDeployLib.sol +++ b/test/utils/CoreDeployLib.sol @@ -2,7 +2,8 @@ pragma solidity ^0.8.0; import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {TransparentUpgradeableProxy} from + "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import {DelegationManager} from "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; import {StrategyManager} from "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; @@ -12,22 +13,27 @@ import {RewardsCoordinator} from "eigenlayer-contracts/src/contracts/core/Reward import {StrategyBase} from "eigenlayer-contracts/src/contracts/strategies/StrategyBase.sol"; import {EigenPod} from "eigenlayer-contracts/src/contracts/pods/EigenPod.sol"; import {IETHPOSDeposit} from "eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol"; -import {StrategyBaseTVLLimits} from "eigenlayer-contracts/src/contracts/strategies/StrategyBaseTVLLimits.sol"; +import {StrategyBaseTVLLimits} from + "eigenlayer-contracts/src/contracts/strategies/StrategyBaseTVLLimits.sol"; import {PauserRegistry} from "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol"; import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; -import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; +import {IDelegationManager} from + "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {IEigenPodManager} from "eigenlayer-contracts/src/contracts/interfaces/IEigenPodManager.sol"; import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; import {StrategyFactory} from "eigenlayer-contracts/src/contracts/strategies/StrategyFactory.sol"; -import {IPermissionController} from "eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol"; -import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IPermissionController} from + "eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol"; +import {IAllocationManager} from + "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol"; -import {PermissionController} from "eigenlayer-contracts/src/contracts/permissions/PermissionController.sol"; +import {PermissionController} from + "eigenlayer-contracts/src/contracts/permissions/PermissionController.sol"; import {UpgradeableProxyLib} from "../unit/UpgradeableProxyLib.sol"; @@ -136,8 +142,7 @@ library CoreDeploymentLib { address strategyManagerImpl = address( new StrategyManager( - IDelegationManager(result.delegationManager), - IPauserRegistry(result.pauserRegistry) + IDelegationManager(result.delegationManager), IPauserRegistry(result.pauserRegistry) ) ); @@ -164,8 +169,7 @@ library CoreDeploymentLib { address avsDirectoryImpl = address( new AVSDirectory( - IDelegationManager(result.delegationManager), - IPauserRegistry(result.pauserRegistry) + IDelegationManager(result.delegationManager), IPauserRegistry(result.pauserRegistry) ) ); @@ -191,7 +195,9 @@ library CoreDeploymentLib { new EigenPod( IETHPOSDeposit(ethPOSDeposit), IEigenPodManager(result.eigenPodManager), - configData.eigenPod.genesisTimestamp == 0 ? uint64(block.timestamp) : configData.eigenPod.genesisTimestamp // Use configured timestamp or current timestamp as fallback + configData.eigenPod.genesisTimestamp == 0 + ? uint64(block.timestamp) + : configData.eigenPod.genesisTimestamp // Use configured timestamp or current timestamp as fallback ) ); @@ -199,15 +205,13 @@ library CoreDeploymentLib { address baseStrategyImpl = address( new StrategyBase( - IStrategyManager(result.strategyManager), - IPauserRegistry(result.pauserRegistry) + IStrategyManager(result.strategyManager), IPauserRegistry(result.pauserRegistry) ) ); address strategyFactoryImpl = address( new StrategyFactory( - IStrategyManager(result.strategyManager), - IPauserRegistry(result.pauserRegistry) + IStrategyManager(result.strategyManager), IPauserRegistry(result.pauserRegistry) ) ); @@ -244,7 +248,6 @@ library CoreDeploymentLib { ) ); - UpgradeableProxyLib.upgradeAndCall(result.strategyManager, strategyManagerImpl, upgradeCall); upgradeCall = abi.encodeCall( @@ -254,7 +257,9 @@ library CoreDeploymentLib { configData.delegationManager.initPausedStatus ) ); - UpgradeableProxyLib.upgradeAndCall(result.delegationManager, delegationManagerImpl, upgradeCall); + UpgradeableProxyLib.upgradeAndCall( + result.delegationManager, delegationManagerImpl, upgradeCall + ); upgradeCall = abi.encodeCall( AllocationManager.initialize, @@ -263,24 +268,20 @@ library CoreDeploymentLib { configData.allocationManager.initPausedStatus ) ); - UpgradeableProxyLib.upgradeAndCall(result.allocationManager, allocationManagerImpl, upgradeCall); + UpgradeableProxyLib.upgradeAndCall( + result.allocationManager, allocationManagerImpl, upgradeCall + ); upgradeCall = abi.encodeCall( AVSDirectory.initialize, - ( - configData.avsDirectory.initialOwner, - configData.avsDirectory.initPausedStatus - ) + (configData.avsDirectory.initialOwner, configData.avsDirectory.initPausedStatus) ); UpgradeableProxyLib.upgradeAndCall(result.avsDirectory, avsDirectoryImpl, upgradeCall); upgradeCall = abi.encodeCall( EigenPodManager.initialize, - ( - configData.eigenPodManager.initialOwner, - configData.eigenPodManager.initPausedStatus - ) + (configData.eigenPodManager.initialOwner, configData.eigenPodManager.initPausedStatus) ); UpgradeableProxyLib.upgradeAndCall(result.eigenPodManager, eigenPodManagerImpl, upgradeCall); @@ -305,7 +306,9 @@ library CoreDeploymentLib { ) ); - UpgradeableProxyLib.upgradeAndCall(result.rewardsCoordinator, rewardsCoordinatorImpl, upgradeCall); + UpgradeableProxyLib.upgradeAndCall( + result.rewardsCoordinator, rewardsCoordinatorImpl, upgradeCall + ); return result; } diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index 358ff700..1de4029b 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -553,8 +553,7 @@ contract MockAVSDeployer is Test { uint256 numOperators, uint256 startIndex ) internal returns (Operator[] memory) { - Operator[] memory operators = - new Operator[](numOperators); + Operator[] memory operators = new Operator[](numOperators); for (uint256 i = 0; i < numOperators; i++) { operators[i] = OperatorWalletLib.createOperator( string(abi.encodePacked("operator-", i + startIndex)) diff --git a/test/utils/OperatorWalletLib.sol b/test/utils/OperatorWalletLib.sol index c33931a2..d46127fc 100644 --- a/test/utils/OperatorWalletLib.sol +++ b/test/utils/OperatorWalletLib.sol @@ -24,10 +24,8 @@ struct Operator { library OperatorKeyOperationsLib { Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - function sign( - Wallet memory wallet, - bytes32 digest - ) internal pure returns (bytes memory) { + + function sign(Wallet memory wallet, bytes32 digest) internal pure returns (bytes memory) { (uint8 v, bytes32 r, bytes32 s) = vm.sign(wallet.privateKey, digest); return abi.encodePacked(r, s, v); } @@ -51,10 +49,10 @@ library SigningKeyOperationsLib { BN254.G2Point memory pk1, BN254.G2Point memory pk2 ) internal view returns (BN254.G2Point memory apk) { - (apk.X[0], apk.X[1], apk.Y[0], apk.Y[1]) = - BN256G2.ECTwistAdd(pk1.X[0], pk1.X[1], pk1.Y[0], pk1.Y[1], pk2.X[0], pk2.X[1], pk2.Y[0], pk2.Y[1]); + (apk.X[0], apk.X[1], apk.Y[0], apk.Y[1]) = BN256G2.ECTwistAdd( + pk1.X[0], pk1.X[1], pk1.Y[0], pk1.Y[1], pk2.X[0], pk2.X[1], pk2.Y[0], pk2.Y[1] + ); } - } library OperatorWalletLib { From 491ec94854a7a016919833e080e04214dae21d82 Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 3 Feb 2025 16:51:20 -0500 Subject: [PATCH 8/8] chore: refactor to avoid stack too deep --- test/utils/CoreDeployLib.sol | 266 +++++++++++++++++++---------------- 1 file changed, 148 insertions(+), 118 deletions(-) diff --git a/test/utils/CoreDeployLib.sol b/test/utils/CoreDeployLib.sol index 0c0f65be..c0f474e7 100644 --- a/test/utils/CoreDeployLib.sol +++ b/test/utils/CoreDeployLib.sol @@ -125,55 +125,117 @@ library CoreDeploymentLib { address proxyAdmin, DeploymentConfigData memory configData ) internal returns (DeploymentData memory result) { - // Deploy proxy contracts - result.delegationManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - result.avsDirectory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - result.strategyManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - result.eigenPodManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - result.allocationManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - result.eigenPodBeacon = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - result.pauserRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - result.strategyFactory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - result.rewardsCoordinator = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - result.permissionController = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); - - // Deploy implementation contracts + result = deployEmptyProxies(proxyAdmin); + + deployAndConfigureCore(result, configData); + deployAndConfigurePods(result, configData); + deployAndConfigureStrategies(result, configData); + deployAndConfigureRewards(result, configData); + + return result; + } + + function deployEmptyProxies( + address proxyAdmin + ) internal returns (DeploymentData memory proxies) { + proxies.delegationManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.avsDirectory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.strategyManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.eigenPodManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.allocationManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.eigenPodBeacon = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.pauserRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.strategyFactory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.rewardsCoordinator = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.permissionController = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + return proxies; + } + + function deployAndConfigureCore( + DeploymentData memory deployments, + DeploymentConfigData memory config + ) internal { + // Deploy core implementations address permissionControllerImpl = address(new PermissionController()); address strategyManagerImpl = address( new StrategyManager( - IDelegationManager(result.delegationManager), IPauserRegistry(result.pauserRegistry) + IDelegationManager(deployments.delegationManager), + IPauserRegistry(deployments.pauserRegistry) ) ); address allocationManagerImpl = address( new AllocationManager( - IDelegationManager(result.delegationManager), - IPauserRegistry(result.pauserRegistry), - IPermissionController(result.permissionController), - configData.allocationManager.deallocationDelay, - configData.allocationManager.allocationConfigurationDelay + IDelegationManager(deployments.delegationManager), + IPauserRegistry(deployments.pauserRegistry), + IPermissionController(deployments.permissionController), + config.allocationManager.deallocationDelay, + config.allocationManager.allocationConfigurationDelay ) ); address delegationManagerImpl = address( new DelegationManager( - IStrategyManager(result.strategyManager), - IEigenPodManager(result.eigenPodManager), - IAllocationManager(result.allocationManager), - IPauserRegistry(result.pauserRegistry), - IPermissionController(result.permissionController), - configData.delegationManager.minWithdrawalDelayBlocks + IStrategyManager(deployments.strategyManager), + IEigenPodManager(deployments.eigenPodManager), + IAllocationManager(deployments.allocationManager), + IPauserRegistry(deployments.pauserRegistry), + IPermissionController(deployments.permissionController), + config.delegationManager.minWithdrawalDelayBlocks ) ); address avsDirectoryImpl = address( new AVSDirectory( - IDelegationManager(result.delegationManager), IPauserRegistry(result.pauserRegistry) + IDelegationManager(deployments.delegationManager), + IPauserRegistry(deployments.pauserRegistry) ) ); - address ethPOSDeposit = configData.ethPOSDeposit.ethPOSDepositAddress; + // Initialize core contracts + UpgradeableProxyLib.upgrade(deployments.permissionController, permissionControllerImpl); + + bytes memory upgradeCall = abi.encodeCall( + StrategyManager.initialize, + ( + config.strategyManager.initialOwner, + config.strategyManager.initialStrategyWhitelister, + config.strategyManager.initPausedStatus + ) + ); + UpgradeableProxyLib.upgradeAndCall( + deployments.strategyManager, strategyManagerImpl, upgradeCall + ); + + upgradeCall = abi.encodeCall( + DelegationManager.initialize, + (config.delegationManager.initialOwner, config.delegationManager.initPausedStatus) + ); + UpgradeableProxyLib.upgradeAndCall( + deployments.delegationManager, delegationManagerImpl, upgradeCall + ); + + upgradeCall = abi.encodeCall( + AllocationManager.initialize, + (config.allocationManager.initialOwner, config.allocationManager.initPausedStatus) + ); + UpgradeableProxyLib.upgradeAndCall( + deployments.allocationManager, allocationManagerImpl, upgradeCall + ); + + upgradeCall = abi.encodeCall( + AVSDirectory.initialize, + (config.avsDirectory.initialOwner, config.avsDirectory.initPausedStatus) + ); + UpgradeableProxyLib.upgradeAndCall(deployments.avsDirectory, avsDirectoryImpl, upgradeCall); + } + + function deployAndConfigurePods( + DeploymentData memory deployments, + DeploymentConfigData memory config + ) internal { + address ethPOSDeposit = config.ethPOSDeposit.ethPOSDepositAddress; if (ethPOSDeposit == address(0)) { if (block.chainid == 1) { ethPOSDeposit = 0x00000000219ab540356cBB839Cbe05303d7705Fa; @@ -182,134 +244,102 @@ library CoreDeploymentLib { } } - address eigenPodManagerImpl = address( - new EigenPodManager( - IETHPOSDeposit(ethPOSDeposit), - IBeacon(result.eigenPodBeacon), - IDelegationManager(result.delegationManager), - IPauserRegistry(result.pauserRegistry) - ) - ); - address eigenPodImpl = address( new EigenPod( IETHPOSDeposit(ethPOSDeposit), - IEigenPodManager(result.eigenPodManager), - configData.eigenPod.genesisTimestamp == 0 + IEigenPodManager(deployments.eigenPodManager), + config.eigenPod.genesisTimestamp == 0 ? uint64(block.timestamp) - : configData.eigenPod.genesisTimestamp // Use configured timestamp or current timestamp as fallback + : config.eigenPod.genesisTimestamp ) ); address eigenPodBeaconImpl = address(new UpgradeableBeacon(eigenPodImpl)); + UpgradeableProxyLib.upgrade(deployments.eigenPodBeacon, eigenPodBeaconImpl); - address baseStrategyImpl = address( - new StrategyBase( - IStrategyManager(result.strategyManager), IPauserRegistry(result.pauserRegistry) + address eigenPodManagerImpl = address( + new EigenPodManager( + IETHPOSDeposit(ethPOSDeposit), + IBeacon(deployments.eigenPodBeacon), + IDelegationManager(deployments.delegationManager), + IPauserRegistry(deployments.pauserRegistry) ) ); - address strategyFactoryImpl = address( - new StrategyFactory( - IStrategyManager(result.strategyManager), IPauserRegistry(result.pauserRegistry) - ) + bytes memory upgradeCall = abi.encodeCall( + EigenPodManager.initialize, + (config.eigenPodManager.initialOwner, config.eigenPodManager.initPausedStatus) ); - - address rewardsCoordinatorImpl = address( - new RewardsCoordinator( - IDelegationManager(result.delegationManager), - IStrategyManager(result.strategyManager), - IAllocationManager(result.allocationManager), - IPauserRegistry(result.pauserRegistry), - IPermissionController(result.permissionController), - configData.rewardsCoordinator.calculationIntervalSeconds, - configData.rewardsCoordinator.maxRewardsDuration, - configData.rewardsCoordinator.maxRetroactiveLength, - configData.rewardsCoordinator.maxFutureLength, - configData.rewardsCoordinator.genesisRewardsTimestamp - ) + UpgradeableProxyLib.upgradeAndCall( + deployments.eigenPodManager, eigenPodManagerImpl, upgradeCall ); + } - result.strategyBeacon = address(new UpgradeableBeacon(baseStrategyImpl)); - - // Upgrade contracts - UpgradeableProxyLib.upgrade(result.eigenPodBeacon, eigenPodBeaconImpl); - - UpgradeableProxyLib.upgrade(result.permissionController, permissionControllerImpl); - - bytes memory upgradeCall; - - upgradeCall = abi.encodeCall( - StrategyManager.initialize, - ( - configData.strategyManager.initialOwner, - configData.strategyManager.initialStrategyWhitelister, - configData.strategyManager.initPausedStatus + function deployAndConfigureStrategies( + DeploymentData memory deployments, + DeploymentConfigData memory config + ) internal { + address baseStrategyImpl = address( + new StrategyBase( + IStrategyManager(deployments.strategyManager), + IPauserRegistry(deployments.pauserRegistry) ) ); - UpgradeableProxyLib.upgradeAndCall(result.strategyManager, strategyManagerImpl, upgradeCall); + deployments.strategyBeacon = address(new UpgradeableBeacon(baseStrategyImpl)); - upgradeCall = abi.encodeCall( - DelegationManager.initialize, - ( - configData.delegationManager.initialOwner, - configData.delegationManager.initPausedStatus + address strategyFactoryImpl = address( + new StrategyFactory( + IStrategyManager(deployments.strategyManager), + IPauserRegistry(deployments.pauserRegistry) ) ); - UpgradeableProxyLib.upgradeAndCall( - result.delegationManager, delegationManagerImpl, upgradeCall - ); - upgradeCall = abi.encodeCall( - AllocationManager.initialize, + bytes memory upgradeCall = abi.encodeCall( + StrategyFactory.initialize, ( - configData.allocationManager.initialOwner, - configData.allocationManager.initPausedStatus + config.strategyFactory.initialOwner, + config.strategyFactory.initPausedStatus, + IBeacon(deployments.strategyBeacon) ) ); UpgradeableProxyLib.upgradeAndCall( - result.allocationManager, allocationManagerImpl, upgradeCall - ); - - upgradeCall = abi.encodeCall( - AVSDirectory.initialize, - (configData.avsDirectory.initialOwner, configData.avsDirectory.initPausedStatus) - ); - - UpgradeableProxyLib.upgradeAndCall(result.avsDirectory, avsDirectoryImpl, upgradeCall); - - upgradeCall = abi.encodeCall( - EigenPodManager.initialize, - (configData.eigenPodManager.initialOwner, configData.eigenPodManager.initPausedStatus) + deployments.strategyFactory, strategyFactoryImpl, upgradeCall ); - UpgradeableProxyLib.upgradeAndCall(result.eigenPodManager, eigenPodManagerImpl, upgradeCall); + } - upgradeCall = abi.encodeCall( - StrategyFactory.initialize, - ( - configData.strategyFactory.initialOwner, - configData.strategyFactory.initPausedStatus, - IBeacon(result.strategyBeacon) + function deployAndConfigureRewards( + DeploymentData memory deployments, + DeploymentConfigData memory config + ) internal { + address rewardsCoordinatorImpl = address( + new RewardsCoordinator( + IDelegationManager(deployments.delegationManager), + IStrategyManager(deployments.strategyManager), + IAllocationManager(deployments.allocationManager), + IPauserRegistry(deployments.pauserRegistry), + IPermissionController(deployments.permissionController), + config.rewardsCoordinator.calculationIntervalSeconds, + config.rewardsCoordinator.maxRewardsDuration, + config.rewardsCoordinator.maxRetroactiveLength, + config.rewardsCoordinator.maxFutureLength, + config.rewardsCoordinator.genesisRewardsTimestamp ) ); - UpgradeableProxyLib.upgradeAndCall(result.strategyFactory, strategyFactoryImpl, upgradeCall); - upgradeCall = abi.encodeCall( + bytes memory upgradeCall = abi.encodeCall( RewardsCoordinator.initialize, ( - configData.rewardsCoordinator.initialOwner, - configData.rewardsCoordinator.initPausedStatus, - configData.rewardsCoordinator.rewardsUpdater, - configData.rewardsCoordinator.activationDelay, - configData.rewardsCoordinator.defaultSplitBips + config.rewardsCoordinator.initialOwner, + config.rewardsCoordinator.initPausedStatus, + config.rewardsCoordinator.rewardsUpdater, + config.rewardsCoordinator.activationDelay, + config.rewardsCoordinator.defaultSplitBips ) ); UpgradeableProxyLib.upgradeAndCall( - result.rewardsCoordinator, rewardsCoordinatorImpl, upgradeCall + deployments.rewardsCoordinator, rewardsCoordinatorImpl, upgradeCall ); - - return result; } }