diff --git a/mainnet-contracts/script/AccessManagerMigrations/08_GenerateFeeSetterCalldata.s.sol b/mainnet-contracts/script/AccessManagerMigrations/08_GenerateFeeSetterCalldata.s.sol index daae041c..5063ce72 100644 --- a/mainnet-contracts/script/AccessManagerMigrations/08_GenerateFeeSetterCalldata.s.sol +++ b/mainnet-contracts/script/AccessManagerMigrations/08_GenerateFeeSetterCalldata.s.sol @@ -16,8 +16,9 @@ contract GenerateFeeSetterCalldata is Script { daoSelectors[0] = PufferVaultV5.setExitFeeBasisPoints.selector; daoSelectors[1] = PufferVaultV5.setTreasuryExitFeeBasisPoints.selector; - calldatas[0] = - abi.encodeWithSelector(AccessManager.setTargetFunctionRole.selector, pufferVault, daoSelectors, ROLE_ID_DAO); + calldatas[0] = abi.encodeWithSelector( + AccessManager.setTargetFunctionRole.selector, pufferVault, daoSelectors, ROLE_ID_DAO + ); bytes memory encodedMulticall = abi.encodeCall(Multicall.multicall, (calldatas)); diff --git a/mainnet-contracts/script/CompleteQueuedWithdrawals.s.sol b/mainnet-contracts/script/CompleteQueuedWithdrawals.s.sol index 18627741..b0e95f48 100644 --- a/mainnet-contracts/script/CompleteQueuedWithdrawals.s.sol +++ b/mainnet-contracts/script/CompleteQueuedWithdrawals.s.sol @@ -65,11 +65,12 @@ contract CompleteQueuedWithdrawals is Script { tokens[0] = t; vm.startBroadcast(); - PufferModuleManager(payable(params.pufferModuleManager)).callCompleteQueuedWithdrawals({ - moduleName: params.moduleName, - withdrawals: withdrawals, - tokens: tokens, - receiveAsTokens: params.receiveAsTokens - }); + PufferModuleManager(payable(params.pufferModuleManager)) + .callCompleteQueuedWithdrawals({ + moduleName: params.moduleName, + withdrawals: withdrawals, + tokens: tokens, + receiveAsTokens: params.receiveAsTokens + }); } } diff --git a/mainnet-contracts/script/DeployCarrotVesting.s.sol b/mainnet-contracts/script/DeployCarrotVesting.s.sol index 4a0502ba..a5476b61 100644 --- a/mainnet-contracts/script/DeployCarrotVesting.s.sol +++ b/mainnet-contracts/script/DeployCarrotVesting.s.sol @@ -25,7 +25,9 @@ contract DeployCarrotVesting is Script { address carrot, // CARROT token address, for impl constructor address puffer, // PUFFER token address, for impl constructor address owner // owner of the contract, for initialize - ) public { + ) + public + { vm.startBroadcast(); CarrotVesting impl = new CarrotVesting(carrot, puffer); diff --git a/mainnet-contracts/script/DeployEverything.s.sol b/mainnet-contracts/script/DeployEverything.s.sol index a2e86236..3007c793 100644 --- a/mainnet-contracts/script/DeployEverything.s.sol +++ b/mainnet-contracts/script/DeployEverything.s.sol @@ -13,8 +13,9 @@ import { DeployPufferOracle } from "script/DeployPufferOracle.s.sol"; import { GuardiansDeployment, PufferProtocolDeployment, BridgingDeployment } from "./DeploymentStructs.sol"; import { PufferRevenueDepositor } from "src/PufferRevenueDepositor.sol"; import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import { GenerateRevenueDepositorCalldata } from - "script/AccessManagerMigrations/06_GenerateRevenueDepositorCalldata.s.sol"; +import { + GenerateRevenueDepositorCalldata +} from "script/AccessManagerMigrations/06_GenerateRevenueDepositorCalldata.s.sol"; import { MockAeraVault } from "test/mocks/MockAeraVault.sol"; /** @@ -47,9 +48,8 @@ contract DeployEverything is BaseScript { GuardiansDeployment memory guardiansDeployment = new DeployGuardians().run(AccessManager(puffETHDeployment.accessManager), guardians, threshold); - address pufferOracle = new DeployPufferOracle().run( - puffETHDeployment.accessManager, guardiansDeployment.guardianModule, puffETHDeployment.pufferVault - ); + address pufferOracle = new DeployPufferOracle() + .run(puffETHDeployment.accessManager, guardiansDeployment.guardianModule, puffETHDeployment.pufferVault); PufferProtocolDeployment memory pufferDeployment = new DeployPuffer().run(guardiansDeployment, puffETHDeployment.pufferVault, pufferOracle); @@ -114,14 +114,10 @@ contract DeployEverything is BaseScript { }); PufferRevenueDepositor revenueDepositor = PufferRevenueDepositor( - ( - payable( - new ERC1967Proxy{ salt: bytes32("revenueDepositor") }( + (payable(new ERC1967Proxy{ salt: bytes32("revenueDepositor") }( address(revenueDepositorImpl), abi.encodeCall(PufferRevenueDepositor.initialize, (address(puffETHDeployment.accessManager))) - ) - ) - ) + ))) ); bytes memory accessManagerCd = diff --git a/mainnet-contracts/script/DeployPufETH.s.sol b/mainnet-contracts/script/DeployPufETH.s.sol index 6309d523..ab10fef0 100644 --- a/mainnet-contracts/script/DeployPufETH.s.sol +++ b/mainnet-contracts/script/DeployPufETH.s.sol @@ -126,13 +126,16 @@ contract DeployPufETH is BaseScript { } // Initialize Depositor - NoImplementation(payable(address(depositorProxy))).upgradeToAndCall( - address(pufferDepositorImplementation), abi.encodeCall(PufferDepositor.initialize, (address(accessManager))) - ); + NoImplementation(payable(address(depositorProxy))) + .upgradeToAndCall( + address(pufferDepositorImplementation), + abi.encodeCall(PufferDepositor.initialize, (address(accessManager))) + ); // Initialize Vault - NoImplementation(payable(address(vaultProxy))).upgradeToAndCall( - address(pufferVaultImplementation), abi.encodeCall(PufferVaultV5.initialize, (address(accessManager))) - ); + NoImplementation(payable(address(vaultProxy))) + .upgradeToAndCall( + address(pufferVaultImplementation), abi.encodeCall(PufferVaultV5.initialize, (address(accessManager))) + ); vm.serializeAddress(obj, "PufferDepositor", address(depositorProxy)); vm.serializeAddress(obj, "PufferDepositorImplementation", address(pufferDepositorImplementation)); @@ -210,8 +213,9 @@ contract DeployPufETH is BaseScript { bytes[] memory calldatas = new bytes[](4); // Setup role members (no delay) - calldatas[0] = - abi.encodeWithSelector(AccessManager.grantRole.selector, ROLE_ID_OPERATIONS_MULTISIG, operationsMultisig, 0); + calldatas[0] = abi.encodeWithSelector( + AccessManager.grantRole.selector, ROLE_ID_OPERATIONS_MULTISIG, operationsMultisig, 0 + ); // Grant admin role to timelock calldatas[1] = abi.encodeWithSelector(AccessManager.grantRole.selector, accessManager.ADMIN_ROLE(), address(timelock), 0); diff --git a/mainnet-contracts/script/DeployPuffer.s.sol b/mainnet-contracts/script/DeployPuffer.s.sol index ea294c78..b52150be 100644 --- a/mainnet-contracts/script/DeployPuffer.s.sol +++ b/mainnet-contracts/script/DeployPuffer.s.sol @@ -113,13 +113,14 @@ contract DeployPuffer is BaseScript { operationsMultisig: operationsMultisig }); - NoImplementation(payable(address(validatorTicketProxy))).upgradeToAndCall( - address(validatorTicketImplementation), - abi.encodeCall( - ValidatorTicket.initialize, - (address(accessManager), 500, 50) //@todo recheck 5% treasury, 0.5% guardians - ) - ); + NoImplementation(payable(address(validatorTicketProxy))) + .upgradeToAndCall( + address(validatorTicketImplementation), + abi.encodeCall( + ValidatorTicket.initialize, + (address(accessManager), 500, 50) //@todo recheck 5% treasury, 0.5% guardians + ) + ); // UUPS proxy for PufferProtocol proxy = new ERC1967Proxy(address(new NoImplementation()), ""); @@ -175,9 +176,10 @@ contract DeployPuffer is BaseScript { pufferProtocol: address(proxy) }); - NoImplementation(payable(address(moduleManagerProxy))).upgradeToAndCall( - address(moduleManager), abi.encodeCall(moduleManager.initialize, (address(accessManager))) - ); + NoImplementation(payable(address(moduleManagerProxy))) + .upgradeToAndCall( + address(moduleManager), abi.encodeCall(moduleManager.initialize, (address(accessManager))) + ); // Initialize the Pool pufferProtocol.initialize({ accessManager: address(accessManager) }); @@ -215,7 +217,7 @@ contract DeployPuffer is BaseScript { pufferDepositor: address(0), // overwritten in DeployEverything weth: address(0), // overwritten in DeployEverything revenueDepositor: address(0) // overwritten in DeployEverything - }); + }); } function getStakingContract() internal returns (address) { diff --git a/mainnet-contracts/script/DeployPufferOracle.s.sol b/mainnet-contracts/script/DeployPufferOracle.s.sol index 0c39c087..e946760d 100644 --- a/mainnet-contracts/script/DeployPufferOracle.s.sol +++ b/mainnet-contracts/script/DeployPufferOracle.s.sol @@ -13,8 +13,9 @@ contract DeployPufferOracle is BaseScript { broadcast returns (address) { - PufferOracleV2 oracle = - new PufferOracleV2(GuardianModule(payable(guardianModule)), payable(pufferVault), accessManager); + PufferOracleV2 oracle = new PufferOracleV2( + GuardianModule(payable(guardianModule)), payable(pufferVault), accessManager + ); return address(oracle); } diff --git a/mainnet-contracts/script/DeployPufferWithdrawalManager.s.sol b/mainnet-contracts/script/DeployPufferWithdrawalManager.s.sol index 5f6418b5..4f97c879 100644 --- a/mainnet-contracts/script/DeployPufferWithdrawalManager.s.sol +++ b/mainnet-contracts/script/DeployPufferWithdrawalManager.s.sol @@ -27,14 +27,10 @@ contract DeployPufferWithdrawalManager is DeployerHelper { ((new PufferWithdrawalManager(BATCH_SIZE, PufferVaultV5(payable(_getPufferVault())), IWETH(_getWETH())))); withdrawalManager = PufferWithdrawalManager( - ( - payable( - new ERC1967Proxy{ salt: bytes32("PufferWithdrawalManager") }( + (payable(new ERC1967Proxy{ salt: bytes32("PufferWithdrawalManager") }( address(withdrawalManagerImpl), abi.encodeCall(PufferWithdrawalManager.initialize, address(_getAccessManager())) - ) - ) - ) + ))) ); vm.label(address(withdrawalManager), "PufferWithdrawalManagerProxy"); diff --git a/mainnet-contracts/script/DeployRevenueDepositor.s.sol b/mainnet-contracts/script/DeployRevenueDepositor.s.sol index da679499..a23a2087 100644 --- a/mainnet-contracts/script/DeployRevenueDepositor.s.sol +++ b/mainnet-contracts/script/DeployRevenueDepositor.s.sol @@ -24,22 +24,17 @@ contract DeployRevenueDepositor is DeployerHelper { new PufferRevenueDepositor({ vault: _getPufferVault(), weth: _getWETH(), aeraVault: _getAeraVault() }); revenueDepositor = PufferRevenueDepositor( - ( - payable( - new ERC1967Proxy{ salt: bytes32("RevenueDepositor") }( + (payable(new ERC1967Proxy{ salt: bytes32("RevenueDepositor") }( address(revenueDepositorImpl), abi.encodeCall(PufferRevenueDepositor.initialize, (address(_getAccessManager()))) - ) - ) - ) + ))) ); vm.label(address(revenueDepositor), "PufferRevenueDepositorProxy"); vm.label(address(revenueDepositorImpl), "PufferRevenueDepositorImplementation"); encodedCalldata = calldataGenerator.run({ - revenueDepositorProxy: address(revenueDepositor), - operationsMultisig: _getOPSMultisig() + revenueDepositorProxy: address(revenueDepositor), operationsMultisig: _getOPSMultisig() }); console.log("Queue from Timelock -> AccessManager", _getAccessManager()); diff --git a/mainnet-contracts/script/DeployerHelper.s.sol b/mainnet-contracts/script/DeployerHelper.s.sol index ed39e42a..2280e5a8 100644 --- a/mainnet-contracts/script/DeployerHelper.s.sol +++ b/mainnet-contracts/script/DeployerHelper.s.sol @@ -60,9 +60,8 @@ abstract contract DeployerHelper is Script { console.log("Deployed", contractName, "at", implementation); if (block.chainid == holesky) { - AccessManager(_getAccessManager()).execute( - proxyTarget, abi.encodeCall(UUPSUpgradeable.upgradeToAndCall, (address(implementation), data)) - ); + AccessManager(_getAccessManager()) + .execute(proxyTarget, abi.encodeCall(UUPSUpgradeable.upgradeToAndCall, (address(implementation), data))); } else { bytes memory upgradeCallData = abi.encodeCall(UUPSUpgradeable.upgradeToAndCall, (address(implementation), data)); @@ -98,9 +97,8 @@ abstract contract DeployerHelper is Script { console.log("Deployed", contractName, "at", implementation); if (block.chainid == holesky) { - AccessManager(_getAccessManager()).execute( - proxyTarget, abi.encodeCall(UUPSUpgradeable.upgradeToAndCall, (address(implementation), data)) - ); + AccessManager(_getAccessManager()) + .execute(proxyTarget, abi.encodeCall(UUPSUpgradeable.upgradeToAndCall, (address(implementation), data))); } else { bytes memory upgradeCallData = abi.encodeCall(UUPSUpgradeable.upgradeToAndCall, (address(implementation), data)); diff --git a/mainnet-contracts/script/Roles.sol b/mainnet-contracts/script/Roles.sol index f969b0b8..dfcd3df1 100644 --- a/mainnet-contracts/script/Roles.sol +++ b/mainnet-contracts/script/Roles.sol @@ -13,6 +13,7 @@ uint64 constant ROLE_ID_OPERATIONS_PAYMASTER = 23; uint64 constant ROLE_ID_OPERATIONS_COORDINATOR = 24; uint64 constant ROLE_ID_WITHDRAWAL_FINALIZER = 25; uint64 constant ROLE_ID_REVENUE_DEPOSITOR = 26; +uint64 constant ROLE_ID_VALIDATOR_EXITOR = 27; // Role assigned to validator ticket price setter uint64 constant ROLE_ID_VT_PRICER = 25; diff --git a/mainnet-contracts/script/SetupAccess.s.sol b/mainnet-contracts/script/SetupAccess.s.sol index e0349cc1..e53fa443 100644 --- a/mainnet-contracts/script/SetupAccess.s.sol +++ b/mainnet-contracts/script/SetupAccess.s.sol @@ -19,8 +19,9 @@ import { OperationsCoordinator } from "../src/OperationsCoordinator.sol"; import { ValidatorTicketPricer } from "../src/ValidatorTicketPricer.sol"; import { GenerateAccessManagerCallData } from "../script/GenerateAccessManagerCallData.sol"; import { GenerateAccessManagerCalldata2 } from "../script/AccessManagerMigrations/GenerateAccessManagerCalldata2.s.sol"; -import { GenerateRestakingOperatorCalldata } from - "../script/AccessManagerMigrations/07_GenerateRestakingOperatorCalldata.s.sol"; +import { + GenerateRestakingOperatorCalldata +} from "../script/AccessManagerMigrations/07_GenerateRestakingOperatorCalldata.s.sol"; import { GenerateFeeSetterCalldata } from "../script/AccessManagerMigrations/08_GenerateFeeSetterCalldata.s.sol"; import { @@ -151,8 +152,9 @@ contract SetupAccess is BaseScript { AccessManager.labelRole.selector, ROLE_ID_OPERATIONS_PAYMASTER, "Operations Paymaster" ); - calldatas[3] = - abi.encodeWithSelector(AccessManager.labelRole.selector, ROLE_ID_OPERATIONS_MULTISIG, "Operations Multisig"); + calldatas[3] = abi.encodeWithSelector( + AccessManager.labelRole.selector, ROLE_ID_OPERATIONS_MULTISIG, "Operations Multisig" + ); return calldatas; } diff --git a/mainnet-contracts/script/UpgradeValidatorTicket.s.sol b/mainnet-contracts/script/UpgradeValidatorTicket.s.sol index 8e3ef3ce..31ccbf21 100644 --- a/mainnet-contracts/script/UpgradeValidatorTicket.s.sol +++ b/mainnet-contracts/script/UpgradeValidatorTicket.s.sol @@ -50,10 +50,11 @@ contract UpgradeValidatorTicket is DeployerHelper { // If on testnet, upgrade and execute access control changes directly if (block.chainid == holesky) { // upgrade to implementation - AccessManager(_getAccessManager()).execute( - address(validatorTicket), - abi.encodeCall(UUPSUpgradeable.upgradeToAndCall, (address(validatorTicketImpl), "")) - ); + AccessManager(_getAccessManager()) + .execute( + address(validatorTicket), + abi.encodeCall(UUPSUpgradeable.upgradeToAndCall, (address(validatorTicketImpl), "")) + ); // execute access control changes (bool success,) = address(_getAccessManager()).call(accessManagerCallData); diff --git a/mainnet-contracts/src/CarrotVesting.sol b/mainnet-contracts/src/CarrotVesting.sol index 3360456a..4d467746 100644 --- a/mainnet-contracts/src/CarrotVesting.sol +++ b/mainnet-contracts/src/CarrotVesting.sol @@ -127,9 +127,16 @@ contract CarrotVesting is UUPSUpgradeable, Ownable2StepUpgradeable, PausableUpgr * @param permitData The permit data */ function startVestingWithPermit(Permit calldata permitData) external { - IERC20Permit(address(CARROT)).permit( - msg.sender, address(this), permitData.amount, permitData.deadline, permitData.v, permitData.r, permitData.s - ); + IERC20Permit(address(CARROT)) + .permit( + msg.sender, + address(this), + permitData.amount, + permitData.deadline, + permitData.v, + permitData.r, + permitData.s + ); _startVesting(permitData.amount); } @@ -291,7 +298,8 @@ contract CarrotVesting is UUPSUpgradeable, Ownable2StepUpgradeable, PausableUpgr require(!$.isDismantled, AlreadyDismantled()); require($.startTimestamp > 0 && block.timestamp >= $.startTimestamp, NotStarted()); require(amount > 0, InvalidAmount()); - $.vestings[msg.sender].push( + $.vestings[msg.sender] + .push( Vesting({ depositedAmount: uint128(amount), claimedAmount: 0, diff --git a/mainnet-contracts/src/GuardianModule.sol b/mainnet-contracts/src/GuardianModule.sol index fec650c9..ee320a35 100644 --- a/mainnet-contracts/src/GuardianModule.sol +++ b/mainnet-contracts/src/GuardianModule.sol @@ -159,8 +159,7 @@ contract GuardianModule is AccessManaged, IGuardianModule { // Check the signatures bool validSignatures = validateGuardiansEnclaveSignatures({ - enclaveSignatures: enclaveSignatures, - signedMessageHash: signedMessageHash + enclaveSignatures: enclaveSignatures, signedMessageHash: signedMessageHash }); if (!validSignatures) { diff --git a/mainnet-contracts/src/L1RewardManager.sol b/mainnet-contracts/src/L1RewardManager.sol index e752de23..2cdc03ea 100644 --- a/mainnet-contracts/src/L1RewardManager.sol +++ b/mainnet-contracts/src/L1RewardManager.sol @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0 <0.9.0; -import { AccessManagedUpgradeable } from - "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { IL1RewardManager } from "./interface/IL1RewardManager.sol"; import { PufferVaultV5 } from "./PufferVaultV5.sol"; import { UUPSUpgradeable } from "@openzeppelin-contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; @@ -186,7 +187,12 @@ contract L1RewardManager is bytes calldata message, address, /* _executor */ bytes calldata /* _extraData */ - ) external payable override restricted { + ) + external + payable + override + restricted + { // Ensure that only the whitelisted pufETH OFT can call this function if (oft != address(PUFETH_OFT)) { revert Unauthorized(); diff --git a/mainnet-contracts/src/PufLocker.sol b/mainnet-contracts/src/PufLocker.sol index 8f269de3..4427a4c3 100644 --- a/mainnet-contracts/src/PufLocker.sol +++ b/mainnet-contracts/src/PufLocker.sol @@ -3,8 +3,9 @@ pragma solidity >=0.8.0 <0.9.0; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { PufLockerStorage } from "./PufLockerStorage.sol"; import { IPufLocker } from "./interface/IPufLocker.sol"; import { ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; @@ -62,15 +63,17 @@ contract PufLocker is IPufLocker, AccessManagedUpgradeable, UUPSUpgradeable, Puf // To avoid that, we don't want to call the permit function if it is not necessary. if (permitData.deadline >= block.timestamp) { // https://docs.openzeppelin.com/contracts/5.x/api/token/erc20#security_considerations - try ERC20Permit(token).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try ERC20Permit(token) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } } IERC20(token).safeTransferFrom(msg.sender, address(this), permitData.amount); diff --git a/mainnet-contracts/src/PufToken.sol b/mainnet-contracts/src/PufToken.sol index aa263f0e..9a58d4e6 100644 --- a/mainnet-contracts/src/PufToken.sol +++ b/mainnet-contracts/src/PufToken.sol @@ -122,7 +122,9 @@ contract PufToken is IPufStakingPool, ERC20, ERC20Permit { onlyAllowedMigratorContract(migratorContract) whenNotPaused { - _migrate({ depositor: msg.sender, amount: amount, destination: destination, migratorContract: migratorContract }); + _migrate({ + depositor: msg.sender, amount: amount, destination: destination, migratorContract: migratorContract + }); } /** @@ -206,10 +208,7 @@ contract PufToken is IPufStakingPool, ERC20, ERC20Permit { _burn(depositor, amount); emit Migrated({ - depositor: depositor, - destination: destination, - migratorContract: migratorContract, - amount: amount + depositor: depositor, destination: destination, migratorContract: migratorContract, amount: amount }); TOKEN.safeIncreaseAllowance(migratorContract, amount); diff --git a/mainnet-contracts/src/PufferDepositor.sol b/mainnet-contracts/src/PufferDepositor.sol index 6fb64da2..ec085f81 100644 --- a/mainnet-contracts/src/PufferDepositor.sol +++ b/mainnet-contracts/src/PufferDepositor.sol @@ -3,8 +3,9 @@ pragma solidity >=0.8.0 <0.9.0; import { ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin-contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { IStETH } from "./interface/Lido/IStETH.sol"; import { IWstETH } from "./interface/Lido/IWstETH.sol"; @@ -90,15 +91,17 @@ contract PufferDepositor is IPufferDepositor, PufferDepositorStorage, AccessMana restricted returns (uint256 pufETHAmount) { - try ERC20Permit(address(tokenIn)).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try ERC20Permit(address(tokenIn)) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } return swapAndDeposit1Inch(tokenIn, permitData.amount, callData); } @@ -143,15 +146,17 @@ contract PufferDepositor is IPufferDepositor, PufferDepositorStorage, AccessMana Permit calldata permitData, bytes calldata routeCode ) public payable virtual restricted returns (uint256 pufETHAmount) { - try ERC20Permit(address(tokenIn)).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try ERC20Permit(address(tokenIn)) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } return swapAndDeposit(tokenIn, permitData.amount, amountOutMin, routeCode); } @@ -160,15 +165,17 @@ contract PufferDepositor is IPufferDepositor, PufferDepositorStorage, AccessMana * @inheritdoc IPufferDepositor */ function depositWstETH(Permit calldata permitData) external restricted returns (uint256 pufETHAmount) { - try ERC20Permit(address(_WST_ETH)).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try ERC20Permit(address(_WST_ETH)) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } SafeERC20.safeTransferFrom(IERC20(address(_WST_ETH)), msg.sender, address(this), permitData.amount); uint256 stETHAmount = _WST_ETH.unwrap(permitData.amount); @@ -180,15 +187,17 @@ contract PufferDepositor is IPufferDepositor, PufferDepositorStorage, AccessMana * @inheritdoc IPufferDepositor */ function depositStETH(Permit calldata permitData) external restricted returns (uint256 pufETHAmount) { - try ERC20Permit(address(_ST_ETH)).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try ERC20Permit(address(_ST_ETH)) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } SafeERC20.safeTransferFrom(IERC20(address(_ST_ETH)), msg.sender, address(this), permitData.amount); diff --git a/mainnet-contracts/src/PufferDepositorV2.sol b/mainnet-contracts/src/PufferDepositorV2.sol index b6079198..e03be52d 100644 --- a/mainnet-contracts/src/PufferDepositorV2.sol +++ b/mainnet-contracts/src/PufferDepositorV2.sol @@ -3,8 +3,9 @@ pragma solidity >=0.8.0 <0.9.0; import { ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin-contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { IStETH } from "./interface/Lido/IStETH.sol"; import { IWstETH } from "./interface/Lido/IWstETH.sol"; @@ -58,15 +59,17 @@ contract PufferDepositorV2 is IPufferDepositorV2, PufferDepositorStorage, Access restricted returns (uint256 pufETHAmount) { - try ERC20Permit(address(_WST_ETH)).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try ERC20Permit(address(_WST_ETH)) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } SafeERC20.safeTransferFrom(IERC20(address(_WST_ETH)), msg.sender, address(this), permitData.amount); @@ -84,15 +87,17 @@ contract PufferDepositorV2 is IPufferDepositorV2, PufferDepositorStorage, Access restricted returns (uint256 pufETHAmount) { - try ERC20Permit(address(_ST_ETH)).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try ERC20Permit(address(_ST_ETH)) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } // Transfer stETH from user to this contract. The amount received here can be 1-2 wei lower than the actual permitData.amount SafeERC20.safeTransferFrom(IERC20(address(_ST_ETH)), msg.sender, address(this), permitData.amount); diff --git a/mainnet-contracts/src/PufferL2Depositor.sol b/mainnet-contracts/src/PufferL2Depositor.sol index 33d8d314..3ace48a6 100644 --- a/mainnet-contracts/src/PufferL2Depositor.sol +++ b/mainnet-contracts/src/PufferL2Depositor.sol @@ -62,15 +62,17 @@ contract PufferL2Depositor is IPufferL2Depositor, AccessManaged { // To avoid that, we don't want to call the permit function if it is not necessary. if (permitData.deadline >= block.timestamp) { // https://docs.openzeppelin.com/contracts/5.x/api/token/erc20#security_considerations - try ERC20Permit(token).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try ERC20Permit(token) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } } IERC20(token).safeTransferFrom(msg.sender, address(this), permitData.amount); @@ -164,11 +166,7 @@ contract PufferL2Depositor is IPufferL2Depositor, AccessManaged { } emit DepositedToken({ - token: token, - depositor: msg.sender, - account: account, - tokenAmount: amount, - referralCode: referralCode + token: token, depositor: msg.sender, account: account, tokenAmount: amount, referralCode: referralCode }); } diff --git a/mainnet-contracts/src/PufferModule.sol b/mainnet-contracts/src/PufferModule.sol index 7c2e57cb..980f14ce 100644 --- a/mainnet-contracts/src/PufferModule.sol +++ b/mainnet-contracts/src/PufferModule.sol @@ -1,14 +1,15 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0 <0.9.0; -import { AccessManagedUpgradeable } from - "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { IDelegationManager } from "../src/interface/Eigenlayer-Slashing/IDelegationManager.sol"; import { IEigenPodManager } from "../src/interface/Eigenlayer-Slashing/IEigenPodManager.sol"; import { ISignatureUtils } from "../src/interface/Eigenlayer-Slashing/ISignatureUtils.sol"; import { IStrategy } from "../src/interface/Eigenlayer-Slashing/IStrategy.sol"; import { IPufferProtocol } from "./interface/IPufferProtocol.sol"; -import { IEigenPod } from "../src/interface/Eigenlayer-Slashing/IEigenPod.sol"; +import { IEigenPod, IEigenPodTypes } from "../src/interface/Eigenlayer-Slashing/IEigenPod.sol"; import { PufferModuleManager } from "./PufferModuleManager.sol"; import { Unauthorized } from "./Errors.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; @@ -120,12 +121,7 @@ contract PufferModule is Initializable, AccessManagedUpgradeable { /** * @notice Queues the withdrawal from EigenLayer for the Beacon Chain strategy */ - function queueWithdrawals(uint256 shareAmount) - external - virtual - onlyPufferModuleManager - returns (bytes32[] memory) - { + function queueWithdrawals(uint256 shareAmount) external virtual onlyPufferModuleManager returns (bytes32[] memory) { IDelegationManagerTypes.QueuedWithdrawalParams[] memory withdrawals = new IDelegationManagerTypes.QueuedWithdrawalParams[](1); @@ -136,9 +132,7 @@ contract PufferModule is Initializable, AccessManagedUpgradeable { strategies[0] = IStrategy(_BEACON_CHAIN_STRATEGY); withdrawals[0] = IDelegationManagerTypes.QueuedWithdrawalParams({ - strategies: strategies, - depositShares: shares, - withdrawer: address(this) + strategies: strategies, depositShares: shares, withdrawer: address(this) }); return EIGEN_DELEGATION_MANAGER.queueWithdrawals(withdrawals); @@ -153,9 +147,7 @@ contract PufferModule is Initializable, AccessManagedUpgradeable { bool[] calldata receiveAsTokens ) external virtual whenNotPaused onlyPufferModuleManager { EIGEN_DELEGATION_MANAGER.completeQueuedWithdrawals({ - withdrawals: withdrawals, - tokens: tokens, - receiveAsTokens: receiveAsTokens + withdrawals: withdrawals, tokens: tokens, receiveAsTokens: receiveAsTokens }); } @@ -195,6 +187,26 @@ contract PufferModule is Initializable, AccessManagedUpgradeable { return EIGEN_DELEGATION_MANAGER.undelegate(address(this)); } + /** + * @notice Triggers the validators exit for the given pubkeys + * @param pubkeys The pubkeys of the validators to exit + * @dev Only callable by the PufferModuleManager + * @dev According to EIP-7002 there is a fee for each validator exit request (See https://eips.ethereum.org/assets/eip-7002/fee_analysis) + * The fee is paid in the msg.value of this function. Since the fee is not fixed and might change, the excess amount will be kept in the PufferModule + */ + function triggerValidatorsExit(bytes[] calldata pubkeys) external payable virtual onlyPufferModuleManager { + ModuleStorage storage $ = _getPufferModuleStorage(); + + IEigenPodTypes.WithdrawalRequest[] memory requests = new IEigenPodTypes.WithdrawalRequest[](pubkeys.length); + for (uint256 i = 0; i < pubkeys.length; i++) { + requests[i] = IEigenPodTypes.WithdrawalRequest({ + pubkey: pubkeys[i], + amountGwei: 0 // This means full exit. Only value supported for 0x01 validators + }); + } + $.eigenPod.requestWithdrawal{ value: msg.value }(requests); + } + /** * @notice Sets the rewards claimer to `claimer` for the PufferModule */ diff --git a/mainnet-contracts/src/PufferModuleManager.sol b/mainnet-contracts/src/PufferModuleManager.sol index f7d6f619..e44a03c4 100644 --- a/mainnet-contracts/src/PufferModuleManager.sol +++ b/mainnet-contracts/src/PufferModuleManager.sol @@ -10,8 +10,9 @@ import { RestakingOperator } from "./RestakingOperator.sol"; import { IPufferModuleManager } from "./interface/IPufferModuleManager.sol"; import { BeaconProxy } from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol"; import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { IDelegationManagerTypes } from "../src/interface/Eigenlayer-Slashing/IDelegationManager.sol"; import { ISignatureUtils } from "../src/interface/Eigenlayer-Slashing/ISignatureUtils.sol"; @@ -71,11 +72,8 @@ contract PufferModuleManager is IPufferModuleManager, AccessManagedUpgradeable, ) external virtual restricted { address moduleAddress = IPufferProtocol(PUFFER_PROTOCOL).getModuleAddress(moduleName); - PufferModule(payable(moduleAddress)).completeQueuedWithdrawals({ - withdrawals: withdrawals, - tokens: tokens, - receiveAsTokens: receiveAsTokens - }); + PufferModule(payable(moduleAddress)) + .completeQueuedWithdrawals({ withdrawals: withdrawals, tokens: tokens, receiveAsTokens: receiveAsTokens }); uint256 sharesWithdrawn; @@ -102,16 +100,16 @@ contract PufferModuleManager is IPufferModuleManager, AccessManagedUpgradeable, } // This called from the PufferProtocol and the event is emitted there return PufferModule( - payable( - Create2.deploy({ + payable(Create2.deploy({ amount: 0, salt: moduleName, bytecode: abi.encodePacked( type(BeaconProxy).creationCode, - abi.encode(PUFFER_MODULE_BEACON, abi.encodeCall(PufferModule.initialize, (moduleName, authority()))) + abi.encode( + PUFFER_MODULE_BEACON, abi.encodeCall(PufferModule.initialize, (moduleName, authority())) + ) ) - }) - ) + })) ); } @@ -239,6 +237,22 @@ contract PufferModuleManager is IPufferModuleManager, AccessManagedUpgradeable, emit PufferModuleUndelegated(moduleName); } + /** + * @notice Triggers the validators exit for the given pubkeys + * @param moduleName The name of the Puffer module + * @param pubkeys The pubkeys of the validators to exit + * @dev Restricted to the VALIDATOR_EXITOR and PUFFER_PROTOCOL + * @dev According to EIP-7002 there is a fee for each validator exit request (See https://eips.ethereum.org/assets/eip-7002/fee_analysis) + * The fee is paid in the msg.value of this function. Since the fee is not fixed and might change, the excess amount will be kept in the PufferModule + */ + function triggerValidatorsExit(bytes32 moduleName, bytes[] calldata pubkeys) external payable virtual restricted { + require(pubkeys.length > 0, InputArrayLengthZero()); + address moduleAddress = IPufferProtocol(PUFFER_PROTOCOL).getModuleAddress(moduleName); + PufferModule(payable(moduleAddress)).triggerValidatorsExit{ value: msg.value }(pubkeys); + + emit ValidatorsExitTriggered(moduleName, pubkeys); + } + /** * @notice Calls the callRegisterOperatorToAVS function on the target restaking operator * @param restakingOperator is the address of the restaking operator diff --git a/mainnet-contracts/src/PufferProtocol.sol b/mainnet-contracts/src/PufferProtocol.sol index d910547e..e159c30e 100644 --- a/mainnet-contracts/src/PufferProtocol.sol +++ b/mainnet-contracts/src/PufferProtocol.sol @@ -2,8 +2,9 @@ pragma solidity >=0.8.0 <0.9.0; import { IPufferProtocol } from "./interface/IPufferProtocol.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { PufferProtocolStorage } from "./PufferProtocolStorage.sol"; import { PufferModuleManager } from "./PufferModuleManager.sol"; @@ -239,11 +240,7 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad } _storeValidatorInformation({ - $: $, - data: data, - pufETHAmount: bondAmount, - moduleName: moduleName, - vtAmount: receivedVtAmount + $: $, data: data, pufETHAmount: bondAmount, moduleName: moduleName, vtAmount: receivedVtAmount }); } @@ -288,6 +285,23 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad $.validators[moduleName][index].status = Status.ACTIVE; } + /** + * @inheritdoc IPufferProtocol + * @dev Restricted to Node Operators + */ + function triggerValidatorsExit(bytes32 moduleName, uint256[] calldata indices) external payable restricted { + ProtocolStorage storage $ = _getPufferProtocolStorage(); + bytes[] memory pubkeys = new bytes[](indices.length); + + for (uint256 i = 0; i < indices.length; ++i) { + Validator memory validator = $.validators[moduleName][indices[i]]; + require(validator.node == msg.sender, InvalidValidator()); + pubkeys[i] = validator.pubKey; + } + + PUFFER_MODULE_MANAGER.triggerValidatorsExit{ value: msg.value }(moduleName, pubkeys); + } + /** * @inheritdoc IPufferProtocol * @dev Restricted to Puffer Paymaster @@ -397,9 +411,7 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad // Check the signatures (reverts if invalid) GUARDIAN_MODULE.validateSkipProvisioning({ - moduleName: moduleName, - skippedIndex: skippedIndex, - guardianEOASignatures: guardianEOASignatures + moduleName: moduleName, skippedIndex: skippedIndex, guardianEOASignatures: guardianEOASignatures }); uint256 vtPenalty = $.vtPenalty; @@ -832,15 +844,17 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad } function _callPermit(address token, Permit calldata permitData) internal { - try IERC20Permit(token).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try IERC20Permit(token) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } } function _decreaseNumberOfRegisteredValidators(ProtocolStorage storage $, bytes32 moduleName) internal { diff --git a/mainnet-contracts/src/PufferRevenueDepositor.sol b/mainnet-contracts/src/PufferRevenueDepositor.sol index 915ebc71..965cf822 100644 --- a/mainnet-contracts/src/PufferRevenueDepositor.sol +++ b/mainnet-contracts/src/PufferRevenueDepositor.sol @@ -5,8 +5,9 @@ import { PufferVaultV5 } from "./PufferVaultV5.sol"; import { Math } from "@openzeppelin/contracts/utils/math/Math.sol"; import { IWETH } from "./interface/Other/IWETH.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { PufferRevenueDepositorStorage } from "./PufferRevenueDepositorStorage.sol"; import { IAeraVault, AssetValue } from "./interface/Other/IAeraVault.sol"; diff --git a/mainnet-contracts/src/PufferVaultV5.sol b/mainnet-contracts/src/PufferVaultV5.sol index 3adfce95..b8339027 100644 --- a/mainnet-contracts/src/PufferVaultV5.sol +++ b/mainnet-contracts/src/PufferVaultV5.sol @@ -4,12 +4,14 @@ pragma solidity >=0.8.0 <0.9.0; import { PufferVaultStorage } from "./PufferVaultStorage.sol"; import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import { UUPSUpgradeable } from "@openzeppelin-contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { ERC4626Upgradeable } from "@openzeppelin-contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol"; import { ERC20Upgradeable } from "@openzeppelin-contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; -import { ERC20PermitUpgradeable } from - "@openzeppelin-contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; +import { + ERC20PermitUpgradeable +} from "@openzeppelin-contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; import { IStETH } from "./interface/Lido/IStETH.sol"; import { ILidoWithdrawalQueue } from "./interface/Lido/ILidoWithdrawalQueue.sol"; import { IWETH } from "./interface/Other/IWETH.sol"; diff --git a/mainnet-contracts/src/PufferWithdrawalManager.sol b/mainnet-contracts/src/PufferWithdrawalManager.sol index b3a9ff96..aeb7156f 100644 --- a/mainnet-contracts/src/PufferWithdrawalManager.sol +++ b/mainnet-contracts/src/PufferWithdrawalManager.sol @@ -5,8 +5,9 @@ import { PufferVaultV5 } from "./PufferVaultV5.sol"; import { Math } from "@openzeppelin/contracts/utils/math/Math.sol"; import { IPufferWithdrawalManager } from "./interface/IPufferWithdrawalManager.sol"; import { PufferWithdrawalManagerStorage } from "./PufferWithdrawalManagerStorage.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; import { Permit } from "./structs/Permit.sol"; @@ -94,15 +95,12 @@ contract PufferWithdrawalManager is for (uint256 i = 0; i < BATCH_SIZE; ++i) { $.withdrawals.push(Withdrawal({ pufETHAmount: 0, pufETHToETHExchangeRate: 0, recipient: address(0) })); } - $.withdrawalBatches.push( - WithdrawalBatch({ - toBurn: 0, - toTransfer: 0, - pufETHToETHExchangeRate: 0, - withdrawalsClaimed: 0, - amountClaimed: 0 - }) - ); + $.withdrawalBatches + .push( + WithdrawalBatch({ + toBurn: 0, toTransfer: 0, pufETHToETHExchangeRate: 0, withdrawalsClaimed: 0, amountClaimed: 0 + }) + ); $.finalizedWithdrawalBatch = 0; // do it explicitly } @@ -119,15 +117,17 @@ contract PufferWithdrawalManager is * @dev Restricted in this context is like the `whenNotPaused` modifier from Pausable.sol */ function requestWithdrawalWithPermit(Permit calldata permitData, address recipient) external restricted { - try IERC20Permit(address(PUFFER_VAULT)).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - s: permitData.s, - r: permitData.r - }) { } catch { } + try IERC20Permit(address(PUFFER_VAULT)) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + s: permitData.s, + r: permitData.r + }) { } + catch { } _processWithdrawalRequest(uint128(permitData.amount), recipient); } @@ -295,11 +295,7 @@ contract PufferWithdrawalManager is // We don't want panic when the caller passes an invalid batchIdx if (batchIdx >= $.withdrawalBatches.length) { return WithdrawalBatch({ - toBurn: 0, - toTransfer: 0, - pufETHToETHExchangeRate: 0, - withdrawalsClaimed: 0, - amountClaimed: 0 + toBurn: 0, toTransfer: 0, pufETHToETHExchangeRate: 0, withdrawalsClaimed: 0, amountClaimed: 0 }); } return $.withdrawalBatches[batchIdx]; @@ -325,15 +321,12 @@ contract PufferWithdrawalManager is if (batchIndex == $.withdrawalBatches.length) { // Push empty batch when the previous batch is full - $.withdrawalBatches.push( - WithdrawalBatch({ - toBurn: 0, - toTransfer: 0, - pufETHToETHExchangeRate: 0, - withdrawalsClaimed: 0, - amountClaimed: 0 - }) - ); + $.withdrawalBatches + .push( + WithdrawalBatch({ + toBurn: 0, toTransfer: 0, pufETHToETHExchangeRate: 0, withdrawalsClaimed: 0, amountClaimed: 0 + }) + ); } uint256 pufETHToETHExchangeRate = PUFFER_VAULT.convertToAssets(1 ether); @@ -343,19 +336,17 @@ contract PufferWithdrawalManager is batch.toBurn += uint88(pufETHAmount); batch.toTransfer += uint96(expectedETHAmount); - $.withdrawals.push( - Withdrawal({ - pufETHAmount: pufETHAmount, - recipient: recipient, - pufETHToETHExchangeRate: pufETHToETHExchangeRate.toUint128() - }) - ); + $.withdrawals + .push( + Withdrawal({ + pufETHAmount: pufETHAmount, + recipient: recipient, + pufETHToETHExchangeRate: pufETHToETHExchangeRate.toUint128() + }) + ); emit WithdrawalRequested({ - withdrawalIdx: withdrawalIndex, - batchIdx: batchIndex, - pufETHAmount: pufETHAmount, - recipient: recipient + withdrawalIdx: withdrawalIndex, batchIdx: batchIndex, pufETHAmount: pufETHAmount, recipient: recipient }); } @@ -395,7 +386,8 @@ contract PufferWithdrawalManager is uint256 batchFinalizationExchangeRate, uint256 expectedETHAmount ) internal pure returns (uint256) { - uint256 batchFinalizationAmount = (pufETHBurnAmount * batchFinalizationExchangeRate) / 1 ether; + uint256 batchFinalizationAmount = + (pufETHBurnAmount * batchFinalizationExchangeRate) / 1 ether; return Math.min(expectedETHAmount, batchFinalizationAmount); } } diff --git a/mainnet-contracts/src/RestakingOperator.sol b/mainnet-contracts/src/RestakingOperator.sol index 2014f379..70c49db9 100644 --- a/mainnet-contracts/src/RestakingOperator.sol +++ b/mainnet-contracts/src/RestakingOperator.sol @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0 <0.9.0; -import { AccessManagedUpgradeable } from - "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import { IDelegationManager } from "../src/interface/Eigenlayer-Slashing/IDelegationManager.sol"; import { IAllocationManager } from "../src/interface/Eigenlayer-Slashing/IAllocationManager.sol"; diff --git a/mainnet-contracts/src/ValidatorTicket.sol b/mainnet-contracts/src/ValidatorTicket.sol index bad4e111..11a24bea 100644 --- a/mainnet-contracts/src/ValidatorTicket.sol +++ b/mainnet-contracts/src/ValidatorTicket.sol @@ -2,10 +2,12 @@ pragma solidity >=0.8.0 <0.9.0; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; -import { ERC20PermitUpgradeable } from - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + ERC20PermitUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { ValidatorTicketStorage } from "./ValidatorTicketStorage.sol"; @@ -90,10 +92,7 @@ contract ValidatorTicket is _disableInitializers(); } - function initialize(address accessManager, uint256 treasuryFeeRate, uint256 guardiansFeeRate) - external - initializer - { + function initialize(address accessManager, uint256 treasuryFeeRate, uint256 guardiansFeeRate) external initializer { __AccessManaged_init(accessManager); __ERC20_init("Puffer Validator Ticket", "VT"); __ERC20Permit_init("Puffer Validator Ticket"); @@ -154,21 +153,22 @@ contract ValidatorTicket is * @inheritdoc IValidatorTicket * @dev Restricted in this context is like the `whenNotPaused` modifier from Pausable.sol */ - function purchaseValidatorTicketWithPufETHAndPermit(address recipient, uint256 vtAmount, Permit calldata permitData) - external - virtual - restricted - returns (uint256) - { - try IERC20Permit(address(PUFFER_VAULT)).permit({ - owner: msg.sender, - spender: address(this), - value: permitData.amount, - deadline: permitData.deadline, - v: permitData.v, - r: permitData.r, - s: permitData.s - }) { } catch { } + function purchaseValidatorTicketWithPufETHAndPermit( + address recipient, + uint256 vtAmount, + Permit calldata permitData + ) external virtual restricted returns (uint256) { + try IERC20Permit(address(PUFFER_VAULT)) + .permit({ + owner: msg.sender, + spender: address(this), + value: permitData.amount, + deadline: permitData.deadline, + v: permitData.v, + r: permitData.r, + s: permitData.s + }) { } + catch { } return _processPurchaseValidatorTicketWithPufETH(recipient, vtAmount); } diff --git a/mainnet-contracts/src/ValidatorTicketPricer.sol b/mainnet-contracts/src/ValidatorTicketPricer.sol index 5369e7ee..0ba9542b 100644 --- a/mainnet-contracts/src/ValidatorTicketPricer.sol +++ b/mainnet-contracts/src/ValidatorTicketPricer.sol @@ -169,9 +169,9 @@ contract ValidatorTicketPricer is AccessManaged, IValidatorTicketPricer { */ function _postMintPrice() internal { // casting _dailyMevPayouts + _dailyConsensusRewards so that the whole expression is converted to uint256 - uint256 newPrice = ( - (_BPS_DECIMALS - _discountRateBps) * (uint256(_dailyMevPayouts) + uint256(_dailyConsensusRewards)) - ) / _BPS_DECIMALS; + uint256 newPrice = + ((_BPS_DECIMALS - _discountRateBps) * (uint256(_dailyMevPayouts) + uint256(_dailyConsensusRewards))) + / _BPS_DECIMALS; if (newPrice == 0) { revert InvalidValue(); } diff --git a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IAVSDirectory.sol b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IAVSDirectory.sol index 91434f9d..57b62568 100644 --- a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IAVSDirectory.sol +++ b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IAVSDirectory.sol @@ -7,7 +7,6 @@ import "./IStrategy.sol"; interface IAVSDirectoryErrors { /// Operator Status - /// @dev Thrown when an operator does not exist in the DelegationManager error OperatorNotRegisteredToEigenLayer(); /// @dev Thrown when an operator is already registered to an AVS. @@ -24,7 +23,6 @@ interface IAVSDirectoryTypes { enum OperatorAVSRegistrationStatus { UNREGISTERED, // Operator not registered to AVS REGISTERED // Operator registered to AVS - } /** diff --git a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IAllocationManager.sol b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IAllocationManager.sol index fd507535..495d7803 100644 --- a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IAllocationManager.sol +++ b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IAllocationManager.sol @@ -9,7 +9,6 @@ import "./IAVSRegistrar.sol"; interface IAllocationManagerErrors { /// Input Validation - /// @dev Thrown when `wadToSlash` is zero or greater than 1e18 error InvalidWadToSlash(); /// @dev Thrown when two array parameters have mismatching lengths. @@ -411,10 +410,7 @@ interface IAllocationManager is ISignatureUtils, IAllocationManagerErrors, IAllo * @param strategies the strategies to get the max magnitudes for * @return the max magnitudes for each strategy */ - function getMaxMagnitudes(address operator, IStrategy[] calldata strategies) - external - view - returns (uint64[] memory); + function getMaxMagnitudes(address operator, IStrategy[] calldata strategies) external view returns (uint64[] memory); /** * @notice Returns the maximum magnitudes each operator can allocate for the given strategy @@ -424,10 +420,7 @@ interface IAllocationManager is ISignatureUtils, IAllocationManagerErrors, IAllo * @param strategy the strategy to get the max magnitudes for * @return the max magnitudes for each operator */ - function getMaxMagnitudes(address[] calldata operators, IStrategy strategy) - external - view - returns (uint64[] memory); + function getMaxMagnitudes(address[] calldata operators, IStrategy strategy) external view returns (uint64[] memory); /** * @notice Returns the maximum magnitude an operator can allocate for the given strategies diff --git a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IDelegationManager.sol b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IDelegationManager.sol index 00f0293a..ec5c6d61 100644 --- a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IDelegationManager.sol +++ b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IDelegationManager.sol @@ -331,8 +331,12 @@ interface IDelegationManager is ISignatureUtils, IDelegationManagerErrors, IDele * @dev If the operator was slashed 100% for the strategy (the operator's maxMagnitude = 0), then increasing delegated shares is blocked and will revert. * @dev Callable only by the StrategyManager or EigenPodManager. */ - function increaseDelegatedShares(address staker, IStrategy strategy, uint256 prevDepositShares, uint256 addedShares) - external; + function increaseDelegatedShares( + address staker, + IStrategy strategy, + uint256 prevDepositShares, + uint256 addedShares + ) external; /** * @notice If the staker is delegated, decreases its operator's shares in response to @@ -343,8 +347,11 @@ interface IDelegationManager is ISignatureUtils, IDelegationManagerErrors, IDele * @dev Note: `beaconChainSlashingFactorDecrease` are assumed to ALWAYS be < 1 WAD. * These invariants are maintained in the EigenPodManager. */ - function decreaseDelegatedShares(address staker, uint256 curDepositShares, uint64 beaconChainSlashingFactorDecrease) - external; + function decreaseDelegatedShares( + address staker, + uint256 curDepositShares, + uint64 beaconChainSlashingFactorDecrease + ) external; /** * @notice Decreases the operators shares in storage after a slash and burns the corresponding Strategy shares @@ -404,10 +411,7 @@ interface IDelegationManager is ISignatureUtils, IDelegationManagerErrors, IDele * @param operator the operator to get shares for * @param strategies the strategies to get shares for */ - function getOperatorShares(address operator, IStrategy[] memory strategies) - external - view - returns (uint256[] memory); + function getOperatorShares(address operator, IStrategy[] memory strategies) external view returns (uint256[] memory); /** * @notice Returns the shares that a set of operators have delegated to them in a set of strategies diff --git a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IEigenPod.sol b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IEigenPod.sol index b465f711..9c6aacf2 100644 --- a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IEigenPod.sol +++ b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IEigenPod.sol @@ -4,6 +4,7 @@ pragma solidity >=0.5.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../libraries/BeaconChainProofs.sol"; +import "./ISemVerMixin.sol"; import "./IEigenPodManager.sol"; interface IEigenPodErrors { @@ -42,8 +43,6 @@ interface IEigenPodErrors { /// @dev Thrown when amount exceeds `restakedExecutionLayerGwei`. error InsufficientWithdrawableBalance(); - /// @dev Thrown when provided `amountGwei` is not a multiple of gwei. - error AmountMustBeMultipleOfGwei(); /// Validator Status @@ -60,6 +59,17 @@ interface IEigenPodErrors { /// @dev Thrown when a validator has not been slashed on the beacon chain. error ValidatorNotSlashedOnBeaconChain(); + /// Consolidation and Withdrawal Requests + + /// @dev Thrown when a predeploy request is initiated with insufficient msg.value + error InsufficientFunds(); + /// @dev Thrown when refunding excess fees from a predeploy fails + error RefundFailed(); + /// @dev Thrown when calling the predeploy fails + error PredeployFailed(); + /// @dev Thrown when querying a predeploy for its current fee fails + error FeeQueryFailed(); + /// Misc /// @dev Thrown when an invalid block root is returned by the EIP-4788 oracle. @@ -68,24 +78,27 @@ interface IEigenPodErrors { error MsgValueNot32ETH(); /// @dev Thrown when provided `beaconTimestamp` is too far in the past. error BeaconTimestampTooFarInPast(); + /// @dev Thrown when the pectraForkTimestamp returned from the EigenPodManager is zero + error ForkTimestampZero(); } interface IEigenPodTypes { enum VALIDATOR_STATUS { - INACTIVE, // doesn't exist + INACTIVE, // doesnt exist ACTIVE, // staked on ethpos and withdrawal credentials are pointed to the EigenPod WITHDRAWN // withdrawn from the Beacon Chain - } + /** + * @param validatorIndex index of the validator on the beacon chain + * @param restakedBalanceGwei amount of beacon chain ETH restaked on EigenLayer in gwei + * @param lastCheckpointedAt timestamp of the validator's most recent balance update + * @param status last recorded status of the validator + */ struct ValidatorInfo { - // index of the validator in the beacon chain uint64 validatorIndex; - // amount of beacon chain ETH restaked on EigenLayer in gwei uint64 restakedBalanceGwei; - //timestamp of the validator's most recent balance update uint64 lastCheckpointedAt; - // status of the validator VALIDATOR_STATUS status; } @@ -96,6 +109,30 @@ interface IEigenPodTypes { int64 balanceDeltasGwei; uint64 prevBeaconBalanceGwei; } + + /** + * @param srcPubkey the pubkey of the source validator for the consolidation + * @param targetPubkey the pubkey of the target validator for the consolidation + * @dev Note that if srcPubkey == targetPubkey, this is a "switch request," and will + * change the validator's withdrawal credential type from 0x01 to 0x02. + * For more notes on usage, see `requestConsolidation` + */ + struct ConsolidationRequest { + bytes srcPubkey; + bytes targetPubkey; + } + + /** + * @param pubkey the pubkey of the validator to withdraw from + * @param amountGwei the amount (in gwei) to withdraw from the beacon chain to the pod + * @dev Note that if amountGwei == 0, this is a "full exit request," and will fully exit + * the validator to the pod. + * For more notes on usage, see `requestWithdrawal` + */ + struct WithdrawalRequest { + bytes pubkey; + uint64 amountGwei; + } } interface IEigenPodEvents is IEigenPodTypes { @@ -131,6 +168,18 @@ interface IEigenPodEvents is IEigenPodTypes { /// @notice Emitted when a validaor is proven to have 0 balance at a given checkpoint event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex); + + /// @notice Emitted when a consolidation request is initiated where source == target + event SwitchToCompoundingRequested(bytes32 indexed validatorPubkeyHash); + + /// @notice Emitted when a standard consolidation request is initiated + event ConsolidationRequested(bytes32 indexed sourcePubkeyHash, bytes32 indexed targetPubkeyHash); + + /// @notice Emitted when a withdrawal request is initiated where request.amountGwei == 0 + event ExitRequested(bytes32 indexed validatorPubkeyHash); + + /// @notice Emitted when a partial withdrawal request is initiated + event WithdrawalRequested(bytes32 indexed validatorPubkeyHash, uint64 withdrawalAmountGwei); } /** @@ -140,19 +189,18 @@ interface IEigenPodEvents is IEigenPodTypes { * @dev Note that all beacon chain balances are stored as gwei within the beacon chain datastructures. We choose * to account balances in terms of gwei in the EigenPod contract and convert to wei when making calls to other contracts */ -interface IEigenPod is IEigenPodErrors, IEigenPodEvents { +interface IEigenPod is IEigenPodErrors, IEigenPodEvents, ISemVerMixin { /// @notice Used to initialize the pointers to contracts crucial to the pod's functionality, in beacon proxy construction from EigenPodManager function initialize(address owner) external; /// @notice Called by EigenPodManager when the owner wants to create another ETH validator. + /// @dev This function only supports staking to a 0x01 validator. For compounding validators, please interact directly with the deposit contract. function stake(bytes calldata pubkey, bytes calldata signature, bytes32 depositDataRoot) external payable; /** - * @notice Transfers `amountWei` in ether from this contract to the specified `recipient` address - * @notice Called by EigenPodManager to withdrawBeaconChainETH that has been added to the EigenPod's balance due to a withdrawal from the beacon chain. - * @dev The podOwner must have already proved sufficient withdrawals, so that this pod's `restakedExecutionLayerGwei` exceeds the - * `amountWei` input (when converted to GWEI). - * @dev Reverts if `amountWei` is not a whole Gwei amount + * @notice Transfers `amountWei` from this contract to the `recipient`. Only callable by the EigenPodManager as part + * of the DelegationManager's withdrawal flow. + * @dev `amountWei` is not required to be a whole Gwei amount. Amounts less than a Gwei multiple may be unrecoverable due to Gwei conversion. */ function withdrawRestakedBeaconChainETH(address recipient, uint256 amount) external; @@ -243,16 +291,105 @@ interface IEigenPod is IEigenPodErrors, IEigenPodEvents { BeaconChainProofs.ValidatorProof calldata proof ) external; + /// @notice Allows the owner or proof submitter to initiate one or more requests to + /// consolidate their validators on the beacon chain. + /// @param requests An array of requests consisting of the source and target pubkeys + /// of the validators to be consolidated + /// @dev Both the source and target validator MUST have active withdrawal credentials + /// pointed at the pod + /// @dev The consolidation request predeploy requires a fee is sent with each request; + /// this is pulled from msg.value. After submitting all requests, any remaining fee is + /// refunded to the caller by calling its fallback function. + /// @dev This contract exposes `getConsolidationRequestFee` to query the current fee for + /// a single request. If submitting multiple requests in a single block, the total fee + /// is equal to (fee * requests.length). This fee is updated at the end of each block. + /// + /// (See https://eips.ethereum.org/EIPS/eip-7251#fee-calculation for details) + /// + /// @dev Note on beacon chain behavior: + /// - If request.srcPubkey == request.targetPubkey, this is a "switch" consolidation. Once + /// processed on the beacon chain, the validator's withdrawal credentials will be changed + /// to compounding (0x02). + /// - The rest of the notes assume src != target. + /// - The target validator MUST already have 0x02 credentials. The source validator can have either. + /// - Consoldiation sets the source validator's exit_epoch and withdrawable_epoch, similar to an exit. + /// When the exit epoch is reached, an epoch sweep will process the consolidation and transfer balance + /// from the source to the target validator. + /// - Consolidation transfers min(srcValidator.effective_balance, state.balance[srcIndex]) to the target. + /// This may not be the entirety of the source validator's balance; any remainder will be moved to the + /// pod when hit by a subsequent withdrawal sweep. + /// + /// @dev Note that consolidation requests CAN FAIL for a variety of reasons. Failures occur when the request + /// is processed on the beacon chain, and are invisible to the pod. The pod and predeploy cannot guarantee + /// a request will succeed; it's up to the pod owner to determine this for themselves. If your request fails, + /// you can retry by initiating another request via this method. + /// + /// Some requirements that are NOT checked by the pod: + /// - If request.srcPubkey == request.targetPubkey, the validator MUST have 0x01 credentials + /// - If request.srcPubkey != request.targetPubkey, the target validator MUST have 0x02 credentials + /// - Both the source and target validators MUST be active and MUST NOT have initiated exits + /// - The source validator MUST NOT have pending partial withdrawal requests (via `requestWithdrawal`) + /// - If the source validator is slashed after requesting consolidation (but before processing), + /// the consolidation will be skipped. + /// + /// For further reference, see consolidation processing at block and epoch boundaries: + /// - Block: https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#new-process_consolidation_request + /// - Epoch: https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#new-process_pending_consolidations + function requestConsolidation(ConsolidationRequest[] calldata requests) external payable; + + /// @notice Allows the owner or proof submitter to initiate one or more requests to + /// withdraw funds from validators on the beacon chain. + /// @param requests An array of requests consisting of the source validator and an + /// amount to withdraw + /// @dev The withdrawal request predeploy requires a fee is sent with each request; + /// this is pulled from msg.value. After submitting all requests, any remaining fee is + /// refunded to the caller by calling its fallback function. + /// @dev This contract exposes `getWithdrawalRequestFee` to query the current fee for + /// a single request. If submitting multiple requests in a single block, the total fee + /// is equal to (fee * requests.length). This fee is updated at the end of each block. + /// + /// (See https://eips.ethereum.org/EIPS/eip-7002#fee-update-rule for details) + /// + /// @dev Note on beacon chain behavior: + /// - Withdrawal requests have two types: full exit requests, and partial exit requests. + /// Partial exit requests will be skipped if the validator has 0x01 withdrawal credentials. + /// If you want your validators to have access to partial exits, use `requestConsolidation` + /// to change their withdrawal credentials to compounding (0x02). + /// - If request.amount == 0, this is a FULL exit request. A full exit request initiates a + /// standard validator exit. + /// - Other amounts are treated as PARTIAL exit requests. A partial exit request will NOT result + /// in a validator with less than 32 ETH balance. Any requested amount above this is ignored. + /// - The actual amount withdrawn for a partial exit is given by the formula: + /// min(request.amount, state.balances[vIdx] - 32 ETH - pending_balance_to_withdraw) + /// (where `pending_balance_to_withdraw` is the sum of any outstanding partial exit requests) + /// (Note that this means you may request more than is actually withdrawn!) + /// + /// @dev Note that withdrawal requests CAN FAIL for a variety of reasons. Failures occur when the request + /// is processed on the beacon chain, and are invisible to the pod. The pod and predeploy cannot guarantee + /// a request will succeed; it's up to the pod owner to determine this for themselves. If your request fails, + /// you can retry by initiating another request via this method. + /// + /// Some requirements that are NOT checked by the pod: + /// - request.pubkey MUST be a valid validator pubkey + /// - request.pubkey MUST belong to a validator whose withdrawal credentials are this pod + /// - If request.amount is for a partial exit, the validator MUST have 0x02 withdrawal credentials + /// - If request.amount is for a full exit, the validator MUST NOT have any pending partial exits + /// - The validator MUST be active and MUST NOT have initiated exit + /// + /// For further reference: https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#new-process_withdrawal_request + function requestWithdrawal(WithdrawalRequest[] calldata requests) external payable; + /// @notice called by owner of a pod to remove any ERC20s deposited in the pod function recoverTokens(IERC20[] memory tokenList, uint256[] memory amountsToWithdraw, address recipient) external; /// @notice Allows the owner of a pod to update the proof submitter, a permissioned - /// address that can call `startCheckpoint` and `verifyWithdrawalCredentials`. + /// address that can call various EigenPod methods, but cannot trigger asset withdrawals + /// from the DelegationManager. /// @dev Note that EITHER the podOwner OR proofSubmitter can access these methods, /// so it's fine to set your proofSubmitter to 0 if you want the podOwner to be the /// only address that can call these methods. /// @param newProofSubmitter The new proof submitter address. If set to 0, only the - /// pod owner will be able to call `startCheckpoint` and `verifyWithdrawalCredentials` + /// pod owner will be able to call EigenPod methods. function setProofSubmitter(address newProofSubmitter) external; /** @@ -267,7 +404,8 @@ interface IEigenPod is IEigenPodErrors, IEigenPodEvents { /// @dev If this address is NOT set, only the podOwner can call `startCheckpoint` and `verifyWithdrawalCredentials` function proofSubmitter() external view returns (address); - /// @notice the amount of execution layer ETH in this contract that is staked in EigenLayer (i.e. withdrawn from beaconchain but not EigenLayer), + /// @notice Native ETH in the pod that has been accounted for in a checkpoint (denominated in gwei). + /// This amount is withdrawable from the pod via the DelegationManager withdrawal flow. function withdrawableRestakedExecutionLayerGwei() external view returns (uint64); /// @notice The single EigenPodManager for EigenLayer @@ -282,10 +420,10 @@ interface IEigenPod is IEigenPodErrors, IEigenPodEvents { /// @notice Returns the validatorInfo struct for the provided pubkey function validatorPubkeyToInfo(bytes calldata validatorPubkey) external view returns (ValidatorInfo memory); - /// @notice This returns the status of a given validator + /// @notice Returns the validator status for a given validator pubkey hash function validatorStatus(bytes32 pubkeyHash) external view returns (VALIDATOR_STATUS); - /// @notice This returns the status of a given validator pubkey + /// @notice Returns the validator status for a given validator pubkey function validatorStatus(bytes calldata validatorPubkey) external view returns (VALIDATOR_STATUS); /// @notice Number of validators with proven withdrawal credentials, who do not have proven full withdrawals @@ -298,6 +436,8 @@ interface IEigenPod is IEigenPodErrors, IEigenPodEvents { function currentCheckpointTimestamp() external view returns (uint64); /// @notice Returns the currently-active checkpoint + /// To save gas on checkpoint creation, we don't delete checkpoints when they're completed. + /// If there's not an active checkpoint, this method returns an empty Checkpoint. function currentCheckpoint() external view returns (Checkpoint memory); /// @notice For each checkpoint, the total balance attributed to exited validators, in gwei @@ -335,4 +475,14 @@ interface IEigenPod is IEigenPodErrors, IEigenPodEvents { /// to an existing slot within the last 24 hours. If the slot at `timestamp` was skipped, this method /// will revert. function getParentBlockRoot(uint64 timestamp) external view returns (bytes32); + + /// @notice Returns the fee required to add a consolidation request to the EIP-7251 predeploy this block. + /// @dev Note that the predeploy updates its fee every block according to https://eips.ethereum.org/EIPS/eip-7251#fee-calculation + /// Consider overestimating the amount sent to ensure the fee does not update before your transaction. + function getConsolidationRequestFee() external view returns (uint256); + + /// @notice Returns the current fee required to add a withdrawal request to the EIP-7002 predeploy. + /// @dev Note that the predeploy updates its fee every block according to https://eips.ethereum.org/EIPS/eip-7002#fee-update-rule + /// Consider overestimating the amount sent to ensure the fee does not update before your transaction. + function getWithdrawalRequestFee() external view returns (uint256); } diff --git a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IEigenPodManager.sol b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IEigenPodManager.sol index 9e4e4428..5a0f0081 100644 --- a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IEigenPodManager.sol +++ b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IEigenPodManager.sol @@ -109,8 +109,11 @@ interface IEigenPodManager is * @dev Callable only by the podOwner's EigenPod contract. * @dev Reverts if `sharesDelta` is not a whole Gwei amount */ - function recordBeaconChainETHBalanceUpdate(address podOwner, uint256 prevRestakedBalanceWei, int256 balanceDeltaWei) - external; + function recordBeaconChainETHBalanceUpdate( + address podOwner, + uint256 prevRestakedBalanceWei, + int256 balanceDeltaWei + ) external; /// @notice Returns the address of the `podOwner`'s EigenPod if it has been deployed. function ownerToPod(address podOwner) external view returns (IEigenPod); diff --git a/mainnet-contracts/src/interface/Eigenlayer-Slashing/ISemVerMixin.sol b/mainnet-contracts/src/interface/Eigenlayer-Slashing/ISemVerMixin.sol new file mode 100644 index 00000000..206cf38d --- /dev/null +++ b/mainnet-contracts/src/interface/Eigenlayer-Slashing/ISemVerMixin.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +/// @title ISemVerMixin +/// @notice A mixin interface that provides semantic versioning functionality. +/// @dev Follows SemVer 2.0.0 specification (https://semver.org/) +interface ISemVerMixin { + /// @notice Returns the semantic version string of the contract. + /// @return The version string in SemVer format (e.g., "v1.1.1") + function version() external view returns (string memory); +} diff --git a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IStrategyManager.sol b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IStrategyManager.sol index 067882f8..23cefc5f 100644 --- a/mainnet-contracts/src/interface/Eigenlayer-Slashing/IStrategyManager.sol +++ b/mainnet-contracts/src/interface/Eigenlayer-Slashing/IStrategyManager.sol @@ -59,8 +59,7 @@ interface IStrategyManager is IStrategyManagerErrors, IStrategyManagerEvents, IS * @param initialStrategyWhitelister The initial value of `strategyWhitelister` to set. * @param initialPausedStatus The initial value of `_paused` to set. */ - function initialize(address initialOwner, address initialStrategyWhitelister, uint256 initialPausedStatus) - external; + function initialize(address initialOwner, address initialStrategyWhitelister, uint256 initialPausedStatus) external; /** * @notice Deposits `amount` of `token` into the specified `strategy`, with the resultant shares credited to `msg.sender` diff --git a/mainnet-contracts/src/interface/IPufferModuleManager.sol b/mainnet-contracts/src/interface/IPufferModuleManager.sol index fa5b754f..32f3cd1a 100644 --- a/mainnet-contracts/src/interface/IPufferModuleManager.sol +++ b/mainnet-contracts/src/interface/IPufferModuleManager.sol @@ -14,6 +14,11 @@ interface IPufferModuleManager { */ error ForbiddenModuleName(); + /** + * @notice Thrown if the input array length is zero + */ + error InputArrayLengthZero(); + /** * @notice Emitted when the Custom Call from the restakingOperator is successful * @dev Signature "0x80b240e4b7a31d61bdee28b97592a7c0ad486cb27d11ee5c6b90530db4e949ff" @@ -73,6 +78,14 @@ interface IPufferModuleManager { */ event PufferModuleUndelegated(bytes32 indexed moduleName); + /** + * @notice Emitted when the validators exit is triggered + * @param moduleName the module name to be exited + * @param pubkeys the pubkeys of the validators to exit + * @dev Signature "0x456e0aba5f7f36ec541f2f550d3f5895eb7d1ae057f45e8683952ac182254e5d" + */ + event ValidatorsExitTriggered(bytes32 indexed moduleName, bytes[] pubkeys); + /** * @notice Emitted when the restaking operator avs signature proof is updated * @param restakingOperator is the address of the restaking operator diff --git a/mainnet-contracts/src/interface/IPufferProtocol.sol b/mainnet-contracts/src/interface/IPufferProtocol.sol index f6a87a69..8f88f5d3 100644 --- a/mainnet-contracts/src/interface/IPufferProtocol.sol +++ b/mainnet-contracts/src/interface/IPufferProtocol.sol @@ -68,6 +68,12 @@ interface IPufferProtocol { */ error InvalidValidatorState(Status status); + /** + * @notice Thrown when the validator is not owned by the sender + * @dev Signature "682a6e7c" + */ + error InvalidValidator(); + /** * @notice Thrown if the sender did not send enough ETH in the transaction * @dev Signature "0x242b035c" @@ -210,6 +216,16 @@ interface IPufferProtocol { */ function withdrawValidatorTickets(uint96 amount, address recipient) external; + /** + * @notice Triggers the validators exit for the given indices + * @param moduleName The name of the Puffer module + * @param indices The indices of the validators to exit + * @dev Restricted to Node Operators + * @dev According to EIP-7002 there is a fee for each validator exit request (See https://eips.ethereum.org/assets/eip-7002/fee_analysis) + * The fee is paid in the msg.value of this function. Since the fee is not fixed and might change, the excess amount will be kept in the PufferModule + */ + function triggerValidatorsExit(bytes32 moduleName, uint256[] calldata indices) external payable; + /** * @notice Batch settling of validator withdrawals * diff --git a/mainnet-contracts/src/interface/IValidatorTicket.sol b/mainnet-contracts/src/interface/IValidatorTicket.sol index 035a88f5..9ec7fe2d 100644 --- a/mainnet-contracts/src/interface/IValidatorTicket.sol +++ b/mainnet-contracts/src/interface/IValidatorTicket.sol @@ -80,9 +80,11 @@ interface IValidatorTicket { * @param permitData The permit data for the pufETH transfer * @return pufEthUsed The amount of pufETH used for the purchase */ - function purchaseValidatorTicketWithPufETHAndPermit(address recipient, uint256 vtAmount, Permit calldata permitData) - external - returns (uint256 pufEthUsed); + function purchaseValidatorTicketWithPufETHAndPermit( + address recipient, + uint256 vtAmount, + Permit calldata permitData + ) external returns (uint256 pufEthUsed); /** * @notice Retrieves the current guardians fee rate diff --git a/mainnet-contracts/src/interface/Lido/IStETH.sol b/mainnet-contracts/src/interface/Lido/IStETH.sol index fc174c8e..f6a8182a 100644 --- a/mainnet-contracts/src/interface/Lido/IStETH.sol +++ b/mainnet-contracts/src/interface/Lido/IStETH.sol @@ -18,9 +18,7 @@ interface IStETH is IERC20 { function transferShares(address _recipient, uint256 _sharesAmount) external returns (uint256); - function transferSharesFrom(address _sender, address _recipient, uint256 _sharesAmount) - external - returns (uint256); + function transferSharesFrom(address _sender, address _recipient, uint256 _sharesAmount) external returns (uint256); /** * @return the amount of tokens in existence. diff --git a/mainnet-contracts/src/interface/Other/IAeraVault.sol b/mainnet-contracts/src/interface/Other/IAeraVault.sol index 8c137901..33ebfda5 100644 --- a/mainnet-contracts/src/interface/Other/IAeraVault.sol +++ b/mainnet-contracts/src/interface/Other/IAeraVault.sol @@ -14,7 +14,6 @@ struct AssetValue { /// Copied and modified https://github.com/aera-finance/aera-contracts-public/blob/main/v2/interfaces/IVault.sol interface IAeraVault { /// ERRORS /// - error Aera__AssetRegistryIsZeroAddress(); error Aera__AssetRegistryIsNotValid(address assetRegistry); error Aera__AssetRegistryHasInvalidVault(); diff --git a/mainnet-contracts/src/interface/libraries/BN254.sol b/mainnet-contracts/src/interface/libraries/BN254.sol index ce7fcbbe..9ac36aa3 100644 --- a/mainnet-contracts/src/interface/libraries/BN254.sol +++ b/mainnet-contracts/src/interface/libraries/BN254.sol @@ -29,9 +29,11 @@ pragma solidity >=0.8.0 <0.9.0; */ library BN254 { // modulus for the underlying field F_p of the elliptic curve - uint256 internal constant FP_MODULUS = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + uint256 internal constant FP_MODULUS = + 21888242871839275222246405745257275088696311157297823662689037894645226208583; // modulus for the underlying field F_r of the elliptic curve - uint256 internal constant FR_MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + uint256 internal constant FR_MODULUS = + 21888242871839275222246405745257275088548364400416034343698204186575808495617; struct G1Point { uint256 X; @@ -75,7 +77,8 @@ library BN254 { return G2Point([nG2x1, nG2x0], [nG2y1, nG2y0]); } - bytes32 internal constant powersOfTauMerkleRoot = 0x22c998e49752bbb1918ba87d6d59dd0e83620a311ba91dd4b2cc84990b31b56f; + bytes32 internal constant powersOfTauMerkleRoot = + 0x22c998e49752bbb1918ba87d6d59dd0e83620a311ba91dd4b2cc84990b31b56f; /** * @param p Some point in G1. @@ -222,11 +225,13 @@ library BN254 { * @notice This function is functionally the same as pairing(), however it specifies a gas limit * the user can set, as a precompile may use the entire gas budget if it reverts. */ - function safePairing(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2, uint256 pairingGas) - internal - view - returns (bool, bool) - { + function safePairing( + G1Point memory a1, + G2Point memory a2, + G1Point memory b1, + G2Point memory b2, + uint256 pairingGas + ) internal view returns (bool, bool) { G1Point[2] memory p1 = [a1, b1]; G2Point[2] memory p2 = [a2, b2]; diff --git a/mainnet-contracts/src/l2/xPufETH.sol b/mainnet-contracts/src/l2/xPufETH.sol index 9e34fda1..369dc176 100644 --- a/mainnet-contracts/src/l2/xPufETH.sol +++ b/mainnet-contracts/src/l2/xPufETH.sol @@ -3,10 +3,12 @@ pragma solidity >=0.8.4 <0.9.0; import { IXERC20 } from "../interface/IXERC20.sol"; import { UUPSUpgradeable } from "@openzeppelin-contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import { AccessManagedUpgradeable } from - "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; -import { ERC20PermitUpgradeable } from - "@openzeppelin-contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; +import { + AccessManagedUpgradeable +} from "@openzeppelin-contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol"; +import { + ERC20PermitUpgradeable +} from "@openzeppelin-contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; import { xPufETHStorage } from "./xPufETHStorage.sol"; /** diff --git a/mainnet-contracts/test/MainnetForkTestHelper.sol b/mainnet-contracts/test/MainnetForkTestHelper.sol index 5e5e2f89..1f10aa38 100644 --- a/mainnet-contracts/test/MainnetForkTestHelper.sol +++ b/mainnet-contracts/test/MainnetForkTestHelper.sol @@ -171,15 +171,15 @@ contract MainnetForkTestHelper is Test, DeployerHelper { (address(newImplementation), abi.encodeCall(PufferVaultV5.initialize, (address(accessManager)))) ); - (bool success,) = address(timelock).call( - abi.encodeWithSelector(Timelock.executeTransaction.selector, address(pufferVault), upgradeCd, 1) - ); + (bool success,) = address(timelock) + .call(abi.encodeWithSelector(Timelock.executeTransaction.selector, address(pufferVault), upgradeCd, 1)); vm.expectEmit(true, true, true, true); emit ERC1967Utils.Upgraded(address(newImplementation)); - UUPSUpgradeable(pufferVault).upgradeToAndCall( - address(newImplementation), abi.encodeCall(PufferVaultV5.initialize, (address(accessManager))) - ); + UUPSUpgradeable(pufferVault) + .upgradeToAndCall( + address(newImplementation), abi.encodeCall(PufferVaultV5.initialize, (address(accessManager))) + ); // Upgrade PufferDepositor PufferDepositorV2 newDepositorImplementation = @@ -198,18 +198,20 @@ contract MainnetForkTestHelper is Test, DeployerHelper { // Upgrade PufferDepositor - no initializer here emit ERC1967Utils.Upgraded(address(newDepositorImplementation)); - (success,) = address(timelock).call( - abi.encodeWithSelector(Timelock.executeTransaction.selector, address(accessManager), upgradeCd, 1) - ); + (success,) = address(timelock) + .call(abi.encodeWithSelector(Timelock.executeTransaction.selector, address(accessManager), upgradeCd, 1)); // Setup access bytes memory encodedMulticall = new GenerateAccessManagerCallData().run(address(pufferVault), address(pufferDepositor)); // Timelock is the owner of the AccessManager - (success,) = address(timelock).call( - abi.encodeWithSelector(Timelock.executeTransaction.selector, address(accessManager), encodedMulticall, 1) - ); + (success,) = address(timelock) + .call( + abi.encodeWithSelector( + Timelock.executeTransaction.selector, address(accessManager), encodedMulticall, 1 + ) + ); require(success, "failed upgrade tx"); vm.stopPrank(); diff --git a/mainnet-contracts/test/fork-tests/PufferModuleManager.integration.t.sol b/mainnet-contracts/test/fork-tests/PufferModuleManager.integration.t.sol index 7fd56baf..4e260f6f 100644 --- a/mainnet-contracts/test/fork-tests/PufferModuleManager.integration.t.sol +++ b/mainnet-contracts/test/fork-tests/PufferModuleManager.integration.t.sol @@ -43,28 +43,26 @@ contract PufferModuleManagerIntegrationTest is IntegrationTestHelper { // buy weth vm.startPrank(0xA85Fdcb45aaFF3C310a47FE309D4a35FAfbdc0ad); Weth(0x94373a4919B3240D86eA41593D5eBa789FEF3848).deposit{ value: 500 ether }(); - Weth(0x94373a4919B3240D86eA41593D5eBa789FEF3848).approve( - 0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6, type(uint256).max - ); + Weth(0x94373a4919B3240D86eA41593D5eBa789FEF3848) + .approve(0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6, type(uint256).max); // deposit into weth strategy - IStrategyManager(0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6).depositIntoStrategy( - IStrategy(0x80528D6e9A2BAbFc766965E0E26d5aB08D9CFaF9), - IERC20(0x94373a4919B3240D86eA41593D5eBa789FEF3848), - 500 ether - ); + IStrategyManager(0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6) + .depositIntoStrategy( + IStrategy(0x80528D6e9A2BAbFc766965E0E26d5aB08D9CFaF9), + IERC20(0x94373a4919B3240D86eA41593D5eBa789FEF3848), + 500 ether + ); ISignatureUtils.SignatureWithExpiry memory signatureWithExpiry; - IDelegationManager(0xA44151489861Fe9e3055d95adC98FbD462B948e7).delegateTo( - restakingOperator, signatureWithExpiry, bytes32(0) - ); + IDelegationManager(0xA44151489861Fe9e3055d95adC98FbD462B948e7) + .delegateTo(restakingOperator, signatureWithExpiry, bytes32(0)); } // Creates a new restaking operator and returns it // metadataURI is used as seed for create2 in EL function _createRestakingOperator() internal returns (RestakingOperator) { RestakingOperator operator = moduleManager.createNewRestakingOperator({ - metadataURI: "https://puffer.fi/metadata.json", - allocationDelay: 0 + metadataURI: "https://puffer.fi/metadata.json", allocationDelay: 0 }); assertTrue(address(operator).code.length > 0, "operator deployed"); diff --git a/mainnet-contracts/test/fork-tests/PufferWithdrawalManager.fork.t.sol b/mainnet-contracts/test/fork-tests/PufferWithdrawalManager.fork.t.sol index 529df9ed..c122a8e7 100644 --- a/mainnet-contracts/test/fork-tests/PufferWithdrawalManager.fork.t.sol +++ b/mainnet-contracts/test/fork-tests/PufferWithdrawalManager.fork.t.sol @@ -210,7 +210,7 @@ contract PufferWithdrawalManagerForkTest is MainnetForkTestHelper { // | // Expected WETH amount before batch 1 is finalized (10x1000 ETH) | uint256 expectedAttackerWETH = // | - (attackerAmount + 0.01 ether * (batchSize - 1)) * pufferVault.convertToAssets(1 ether) / 1 ether; // | + (attackerAmount + 0.01 ether * (batchSize - 1)) * pufferVault.convertToAssets(1 ether) / 1 ether; // | // | // Finalize the batch | vm.startPrank(_getPaymaster()); // | diff --git a/mainnet-contracts/test/fork-tests/RestakingOperator.fork.t.sol b/mainnet-contracts/test/fork-tests/RestakingOperator.fork.t.sol index 9379a43c..fb168910 100644 --- a/mainnet-contracts/test/fork-tests/RestakingOperator.fork.t.sol +++ b/mainnet-contracts/test/fork-tests/RestakingOperator.fork.t.sol @@ -8,8 +8,9 @@ import { RestakingOperatorController } from "../../src/RestakingOperatorControll import { UpgradeableBeacon } from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import { IPufferModuleManager } from "../../src/interface/IPufferModuleManager.sol"; import { ERC1967Utils } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol"; -import { GenerateRestakingOperatorCalldata } from - "../../script/AccessManagerMigrations/07_GenerateRestakingOperatorCalldata.s.sol"; +import { + GenerateRestakingOperatorCalldata +} from "../../script/AccessManagerMigrations/07_GenerateRestakingOperatorCalldata.s.sol"; import { AccessManager } from "@openzeppelin/contracts/access/manager/AccessManager.sol"; import { ROLE_ID_DAO } from "../../script/Roles.sol"; import { InvalidAddress, Unauthorized } from "../../src/Errors.sol"; @@ -97,18 +98,18 @@ contract RestakingOperatorForkTest is MainnetForkTestHelper { modifier allowUpdateOperatorAVSSocket() { vm.startPrank(OPERATIONS_MULTISIG); - AVSContractsRegistry(AVS_CONTRACTS_REGISTRY_ADDRESS).setAvsRegistryCoordinator( - EIGEN_DA_ADDRESS, UPDATE_SOCKET_SELECTOR, true - ); + AVSContractsRegistry(AVS_CONTRACTS_REGISTRY_ADDRESS) + .setAvsRegistryCoordinator(EIGEN_DA_ADDRESS, UPDATE_SOCKET_SELECTOR, true); vm.stopPrank(); _; } modifier allowExpensiveRegister() { vm.startPrank(OPERATIONS_MULTISIG); - AVSContractsRegistry(AVS_CONTRACTS_REGISTRY_ADDRESS).setAvsRegistryCoordinator( - address(avsRegistryCoordinatorMock), AvsRegistryCoordinatorMock.expensiveRegister.selector, true - ); + AVSContractsRegistry(AVS_CONTRACTS_REGISTRY_ADDRESS) + .setAvsRegistryCoordinator( + address(avsRegistryCoordinatorMock), AvsRegistryCoordinatorMock.expensiveRegister.selector, true + ); vm.stopPrank(); _; } diff --git a/mainnet-contracts/test/handlers/PufferProtocolHandler.sol b/mainnet-contracts/test/handlers/PufferProtocolHandler.sol index 5c9cc944..03c6c44b 100644 --- a/mainnet-contracts/test/handlers/PufferProtocolHandler.sol +++ b/mainnet-contracts/test/handlers/PufferProtocolHandler.sol @@ -548,14 +548,12 @@ contract PufferProtocolHandler is Test { // mock signature copied from some random deposit transaction signature: mockValidatorSignature, depositDataRoot: pufferProtocol.getDepositDataRoot({ - pubKey: pubKey, - signature: mockValidatorSignature, - withdrawalCredentials: withdrawalCredentials + pubKey: pubKey, signature: mockValidatorSignature, withdrawalCredentials: withdrawalCredentials }), blsEncryptedPrivKeyShares: new bytes[](3), blsPubKeySet: new bytes(48), raveEvidence: new bytes(1) // Guardians are checking it off chain - }); + }); return validatorData; } @@ -611,9 +609,7 @@ contract PufferProtocolHandler is Test { mockValidatorSignature, withdrawalCredentials, pufferProtocol.getDepositDataRoot({ - pubKey: pubKey, - signature: mockValidatorSignature, - withdrawalCredentials: withdrawalCredentials + pubKey: pubKey, signature: mockValidatorSignature, withdrawalCredentials: withdrawalCredentials }) ); diff --git a/mainnet-contracts/test/helpers/GuardiansRaveEvidence.sol b/mainnet-contracts/test/helpers/GuardiansRaveEvidence.sol index b12f1af3..84ff3b87 100644 --- a/mainnet-contracts/test/helpers/GuardiansRaveEvidence.sol +++ b/mainnet-contracts/test/helpers/GuardiansRaveEvidence.sol @@ -22,20 +22,17 @@ contract Guardian3RaveEvidence is MockEvidence { // The leaf x509 signing certificate's signature over the report function sig() public pure override returns (bytes memory) { // base64 decoded signature as hex - return - hex"2c3c7862299e87f941e5a9a49b96a1bc9e2fec4fc15e9ea64e8c3d6a4894cbef433248ac21402f165062936b12ffd75e6b8c4015c34991b75a558390434dcb70a184e24fec38f50929826281ae31793ea02fc3b51f009906e9febbf20abecee32b2dbb831f677babacbc4057030c4650ad4d83dc5b6b28aef78b49c26777c04820856bd36c514f0e8693c0ba7cd94a191d2418f2b0d7d2533013e5a9815b3cb785b0575648267b7990c070b26614b1de1896ade6391364157ebe06112b7a884ff059586cba4f68a02a2440136e16f5b9b65be0d20823ceb773c92191fc615cbab568b809b5beead47201161238b96815f0e9d2c37c4400e4ac794dcf2b1b3599"; + return hex"2c3c7862299e87f941e5a9a49b96a1bc9e2fec4fc15e9ea64e8c3d6a4894cbef433248ac21402f165062936b12ffd75e6b8c4015c34991b75a558390434dcb70a184e24fec38f50929826281ae31793ea02fc3b51f009906e9febbf20abecee32b2dbb831f677babacbc4057030c4650ad4d83dc5b6b28aef78b49c26777c04820856bd36c514f0e8693c0ba7cd94a191d2418f2b0d7d2533013e5a9815b3cb785b0575648267b7990c070b26614b1de1896ade6391364157ebe06112b7a884ff059586cba4f68a02a2440136e16f5b9b65be0d20823ceb773c92191fc615cbab568b809b5beead47201161238b96815f0e9d2c37c4400e4ac794dcf2b1b3599"; } // The leaf x509 signing certificate used to sign the report function signingCert() public pure override returns (bytes memory) { - return - hex"308204a130820309a003020102020900d107765d32a3b096300d06092a864886f70d01010b0500307e310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341301e170d3136313132323039333635385a170d3236313132303039333635385a307b310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e312d302b06035504030c24496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e6730820122300d06092a864886f70d01010105000382010f003082010a0282010100a97a2de0e66ea6147c9ee745ac0162686c7192099afc4b3f040fad6de093511d74e802f510d716038157dcaf84f4104bd3fed7e6b8f99c8817fd1ff5b9b864296c3d81fa8f1b729e02d21d72ffee4ced725efe74bea68fbc4d4244286fcdd4bf64406a439a15bcb4cf67754489c423972b4a80df5c2e7c5bc2dbaf2d42bb7b244f7c95bf92c75d3b33fc5410678a89589d1083da3acc459f2704cd99598c275e7c1878e00757e5bdb4e840226c11c0a17ff79c80b15c1ddb5af21cc2417061fbd2a2da819ed3b72b7efaa3bfebe2805c9b8ac19aa346512d484cfc81941e15f55881cc127e8f7aa12300cd5afb5742fa1d20cb467a5beb1c666cf76a368978b50203010001a381a43081a1301f0603551d2304183016801478437b76a67ebcd0af7e4237eb357c3b8701513c300e0603551d0f0101ff0404030206c0300c0603551d130101ff0402300030600603551d1f045930573055a053a051864f687474703a2f2f7472757374656473657276696365732e696e74656c2e636f6d2f636f6e74656e742f43524c2f5347582f4174746573746174696f6e5265706f72745369676e696e6743412e63726c300d06092a864886f70d01010b050003820181006708b61b5c2bd215473e2b46af99284fbb939d3f3b152c996f1a6af3b329bd220b1d3b610f6bce2e6753bded304db21912f385256216cfcba456bd96940be892f5690c260d1ef84f1606040222e5fe08e5326808212a447cfdd64a46e94bf29f6b4b9a721d25b3c4e2f62f58baed5d77c505248f0f801f9fbfb7fd752080095cee80938b339f6dbb4e165600e20e4a718812d49d9901e310a9b51d66c79909c6996599fae6d76a79ef145d9943bf1d3e35d3b42d1fb9a45cbe8ee334c166eee7d32fcdc9935db8ec8bb1d8eb3779dd8ab92b6e387f0147450f1e381d08581fb83df33b15e000a59be57ea94a3a52dc64bdaec959b3464c91e725bbdaea3d99e857e380a23c9d9fb1ef58e9e42d71f12130f9261d7234d6c37e2b03dba40dfdfb13ac4ad8e13fd3756356b6b50015a3ec9580b815d87c2cef715cd28df00bbf2a3c403ebf6691b3f05edd9143803ca085cff57e053eec2f8fea46ea778a68c9be885bc28225bc5f309be4a2b74d3a03945319dd3c7122fed6ff53bb8b8cb3a03c"; + return hex"308204a130820309a003020102020900d107765d32a3b096300d06092a864886f70d01010b0500307e310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341301e170d3136313132323039333635385a170d3236313132303039333635385a307b310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e312d302b06035504030c24496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e6730820122300d06092a864886f70d01010105000382010f003082010a0282010100a97a2de0e66ea6147c9ee745ac0162686c7192099afc4b3f040fad6de093511d74e802f510d716038157dcaf84f4104bd3fed7e6b8f99c8817fd1ff5b9b864296c3d81fa8f1b729e02d21d72ffee4ced725efe74bea68fbc4d4244286fcdd4bf64406a439a15bcb4cf67754489c423972b4a80df5c2e7c5bc2dbaf2d42bb7b244f7c95bf92c75d3b33fc5410678a89589d1083da3acc459f2704cd99598c275e7c1878e00757e5bdb4e840226c11c0a17ff79c80b15c1ddb5af21cc2417061fbd2a2da819ed3b72b7efaa3bfebe2805c9b8ac19aa346512d484cfc81941e15f55881cc127e8f7aa12300cd5afb5742fa1d20cb467a5beb1c666cf76a368978b50203010001a381a43081a1301f0603551d2304183016801478437b76a67ebcd0af7e4237eb357c3b8701513c300e0603551d0f0101ff0404030206c0300c0603551d130101ff0402300030600603551d1f045930573055a053a051864f687474703a2f2f7472757374656473657276696365732e696e74656c2e636f6d2f636f6e74656e742f43524c2f5347582f4174746573746174696f6e5265706f72745369676e696e6743412e63726c300d06092a864886f70d01010b050003820181006708b61b5c2bd215473e2b46af99284fbb939d3f3b152c996f1a6af3b329bd220b1d3b610f6bce2e6753bded304db21912f385256216cfcba456bd96940be892f5690c260d1ef84f1606040222e5fe08e5326808212a447cfdd64a46e94bf29f6b4b9a721d25b3c4e2f62f58baed5d77c505248f0f801f9fbfb7fd752080095cee80938b339f6dbb4e165600e20e4a718812d49d9901e310a9b51d66c79909c6996599fae6d76a79ef145d9943bf1d3e35d3b42d1fb9a45cbe8ee334c166eee7d32fcdc9935db8ec8bb1d8eb3779dd8ab92b6e387f0147450f1e381d08581fb83df33b15e000a59be57ea94a3a52dc64bdaec959b3464c91e725bbdaea3d99e857e380a23c9d9fb1ef58e9e42d71f12130f9261d7234d6c37e2b03dba40dfdfb13ac4ad8e13fd3756356b6b50015a3ec9580b815d87c2cef715cd28df00bbf2a3c403ebf6691b3f05edd9143803ca085cff57e053eec2f8fea46ea778a68c9be885bc28225bc5f309be4a2b74d3a03945319dd3c7122fed6ff53bb8b8cb3a03c"; } // The extracted RSA modulus of the leaf x509 signing certificate function signingMod() public pure override returns (bytes memory) { - return - hex"9F3C647EB5773CBB512D2732C0D7415EBB55A0FA9EDE2E649199E6821DB910D53177370977466A6A5E4786CCD2DDEBD4149D6A2F6325529DD10CC98737B0779C1A07E29C47A1AE004948476C489F45A5A15D7AC8ECC6ACC645ADB43D87679DF59C093BC5A2E9696C5478541B979E754B573914BE55D32FF4C09DDF27219934CD990527B3F92ED78FBF29246ABECB71240EF39C2D7107B447545A7FFB10EB060A68A98580219E36910952683892D6A5E2A80803193E407531404E36B315623799AA825074409754A2DFE8F5AFD5FE631E1FC2AF3808906F28A790D9DD9FE060939B125790C5805D037DF56A99531B96DE69DE33ED226CC1207D1042B5C9AB7F404FC711C0FE4769FB9578B1DC0EC469EA1A25E0FF9914886EF2699B235BB4847DD6FF40B606E6170793C2FB98B314587F9CFD257362DFEAB10B3BD2D97673A1A4BD44C453AAF47FC1F2D3D0F384F74A06F89C089F0DA6CDB7FCEEE8C9821A8E54F25C0416D18C46839A5F8012FBDD3DC74D256279ADC2C0D55AFF6F0622425D1B"; + return hex"9F3C647EB5773CBB512D2732C0D7415EBB55A0FA9EDE2E649199E6821DB910D53177370977466A6A5E4786CCD2DDEBD4149D6A2F6325529DD10CC98737B0779C1A07E29C47A1AE004948476C489F45A5A15D7AC8ECC6ACC645ADB43D87679DF59C093BC5A2E9696C5478541B979E754B573914BE55D32FF4C09DDF27219934CD990527B3F92ED78FBF29246ABECB71240EF39C2D7107B447545A7FFB10EB060A68A98580219E36910952683892D6A5E2A80803193E407531404E36B315623799AA825074409754A2DFE8F5AFD5FE631E1FC2AF3808906F28A790D9DD9FE060939B125790C5805D037DF56A99531B96DE69DE33ED226CC1207D1042B5C9AB7F404FC711C0FE4769FB9578B1DC0EC469EA1A25E0FF9914886EF2699B235BB4847DD6FF40B606E6170793C2FB98B314587F9CFD257362DFEAB10B3BD2D97673A1A4BD44C453AAF47FC1F2D3D0F384F74A06F89C089F0DA6CDB7FCEEE8C9821A8E54F25C0416D18C46839A5F8012FBDD3DC74D256279ADC2C0D55AFF6F0622425D1B"; } // The extracted RSA exponent of the leaf x509 signing certificate @@ -56,8 +53,7 @@ contract Guardian3RaveEvidence is MockEvidence { // The expected payload value in this specific report function payload() public pure override returns (bytes memory) { // This is a hex-encoded 48 byte BLS public key - return - hex"04a55b152177219971a93a64aafc2d61baeaf86526963caa260e71efa2b865527e0307d7bda85312dd6ff23bcc88f2bf228da6295239f72c31b686c48b7b69cdfd"; + return hex"04a55b152177219971a93a64aafc2d61baeaf86526963caa260e71efa2b865527e0307d7bda85312dd6ff23bcc88f2bf228da6295239f72c31b686c48b7b69cdfd"; } } @@ -80,20 +76,17 @@ contract Guardian2RaveEvidence is MockEvidence { // The leaf x509 signing certificate's signature over the report function sig() public pure override returns (bytes memory) { // base64 decoded signature as hex - return - hex"77d614e10b4f29730c14681ea0808758c22f3ffd833020fcd572dc445ca9abd2ea3e2abdcfd5a04f0975202c5f8c17812a5701346d8f75427b16455da264673e02bedb15d06945ab566d39788e586b73a0259f024a68a27b1fa40964f0b695f3394a5cd3a7af283447f5ff8adccf8091640086de1067cf85fb8ee5db5073bb6894478a9a8bee8292bcb839a10529d82300f3c9cbd548279eae92809f99d0fd6dd7280fe1a6b250d5c1e5219afa7032c4771b393d7fb0269027184013cc6bec4ec40a6699bdc967d67c57035c12f129d59559b98c7f6588aa3658bcf3542a221941ee91b100b80ca895b19464b5570537573ddb0426a09a88b2eca50875809b0e"; + return hex"77d614e10b4f29730c14681ea0808758c22f3ffd833020fcd572dc445ca9abd2ea3e2abdcfd5a04f0975202c5f8c17812a5701346d8f75427b16455da264673e02bedb15d06945ab566d39788e586b73a0259f024a68a27b1fa40964f0b695f3394a5cd3a7af283447f5ff8adccf8091640086de1067cf85fb8ee5db5073bb6894478a9a8bee8292bcb839a10529d82300f3c9cbd548279eae92809f99d0fd6dd7280fe1a6b250d5c1e5219afa7032c4771b393d7fb0269027184013cc6bec4ec40a6699bdc967d67c57035c12f129d59559b98c7f6588aa3658bcf3542a221941ee91b100b80ca895b19464b5570537573ddb0426a09a88b2eca50875809b0e"; } // The leaf x509 signing certificate used to sign the report function signingCert() public pure override returns (bytes memory) { - return - hex"308204a130820309a003020102020900d107765d32a3b096300d06092a864886f70d01010b0500307e310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341301e170d3136313132323039333635385a170d3236313132303039333635385a307b310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e312d302b06035504030c24496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e6730820122300d06092a864886f70d01010105000382010f003082010a0282010100a97a2de0e66ea6147c9ee745ac0162686c7192099afc4b3f040fad6de093511d74e802f510d716038157dcaf84f4104bd3fed7e6b8f99c8817fd1ff5b9b864296c3d81fa8f1b729e02d21d72ffee4ced725efe74bea68fbc4d4244286fcdd4bf64406a439a15bcb4cf67754489c423972b4a80df5c2e7c5bc2dbaf2d42bb7b244f7c95bf92c75d3b33fc5410678a89589d1083da3acc459f2704cd99598c275e7c1878e00757e5bdb4e840226c11c0a17ff79c80b15c1ddb5af21cc2417061fbd2a2da819ed3b72b7efaa3bfebe2805c9b8ac19aa346512d484cfc81941e15f55881cc127e8f7aa12300cd5afb5742fa1d20cb467a5beb1c666cf76a368978b50203010001a381a43081a1301f0603551d2304183016801478437b76a67ebcd0af7e4237eb357c3b8701513c300e0603551d0f0101ff0404030206c0300c0603551d130101ff0402300030600603551d1f045930573055a053a051864f687474703a2f2f7472757374656473657276696365732e696e74656c2e636f6d2f636f6e74656e742f43524c2f5347582f4174746573746174696f6e5265706f72745369676e696e6743412e63726c300d06092a864886f70d01010b050003820181006708b61b5c2bd215473e2b46af99284fbb939d3f3b152c996f1a6af3b329bd220b1d3b610f6bce2e6753bded304db21912f385256216cfcba456bd96940be892f5690c260d1ef84f1606040222e5fe08e5326808212a447cfdd64a46e94bf29f6b4b9a721d25b3c4e2f62f58baed5d77c505248f0f801f9fbfb7fd752080095cee80938b339f6dbb4e165600e20e4a718812d49d9901e310a9b51d66c79909c6996599fae6d76a79ef145d9943bf1d3e35d3b42d1fb9a45cbe8ee334c166eee7d32fcdc9935db8ec8bb1d8eb3779dd8ab92b6e387f0147450f1e381d08581fb83df33b15e000a59be57ea94a3a52dc64bdaec959b3464c91e725bbdaea3d99e857e380a23c9d9fb1ef58e9e42d71f12130f9261d7234d6c37e2b03dba40dfdfb13ac4ad8e13fd3756356b6b50015a3ec9580b815d87c2cef715cd28df00bbf2a3c403ebf6691b3f05edd9143803ca085cff57e053eec2f8fea46ea778a68c9be885bc28225bc5f309be4a2b74d3a03945319dd3c7122fed6ff53bb8b8cb3a03c"; + return hex"308204a130820309a003020102020900d107765d32a3b096300d06092a864886f70d01010b0500307e310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341301e170d3136313132323039333635385a170d3236313132303039333635385a307b310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e312d302b06035504030c24496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e6730820122300d06092a864886f70d01010105000382010f003082010a0282010100a97a2de0e66ea6147c9ee745ac0162686c7192099afc4b3f040fad6de093511d74e802f510d716038157dcaf84f4104bd3fed7e6b8f99c8817fd1ff5b9b864296c3d81fa8f1b729e02d21d72ffee4ced725efe74bea68fbc4d4244286fcdd4bf64406a439a15bcb4cf67754489c423972b4a80df5c2e7c5bc2dbaf2d42bb7b244f7c95bf92c75d3b33fc5410678a89589d1083da3acc459f2704cd99598c275e7c1878e00757e5bdb4e840226c11c0a17ff79c80b15c1ddb5af21cc2417061fbd2a2da819ed3b72b7efaa3bfebe2805c9b8ac19aa346512d484cfc81941e15f55881cc127e8f7aa12300cd5afb5742fa1d20cb467a5beb1c666cf76a368978b50203010001a381a43081a1301f0603551d2304183016801478437b76a67ebcd0af7e4237eb357c3b8701513c300e0603551d0f0101ff0404030206c0300c0603551d130101ff0402300030600603551d1f045930573055a053a051864f687474703a2f2f7472757374656473657276696365732e696e74656c2e636f6d2f636f6e74656e742f43524c2f5347582f4174746573746174696f6e5265706f72745369676e696e6743412e63726c300d06092a864886f70d01010b050003820181006708b61b5c2bd215473e2b46af99284fbb939d3f3b152c996f1a6af3b329bd220b1d3b610f6bce2e6753bded304db21912f385256216cfcba456bd96940be892f5690c260d1ef84f1606040222e5fe08e5326808212a447cfdd64a46e94bf29f6b4b9a721d25b3c4e2f62f58baed5d77c505248f0f801f9fbfb7fd752080095cee80938b339f6dbb4e165600e20e4a718812d49d9901e310a9b51d66c79909c6996599fae6d76a79ef145d9943bf1d3e35d3b42d1fb9a45cbe8ee334c166eee7d32fcdc9935db8ec8bb1d8eb3779dd8ab92b6e387f0147450f1e381d08581fb83df33b15e000a59be57ea94a3a52dc64bdaec959b3464c91e725bbdaea3d99e857e380a23c9d9fb1ef58e9e42d71f12130f9261d7234d6c37e2b03dba40dfdfb13ac4ad8e13fd3756356b6b50015a3ec9580b815d87c2cef715cd28df00bbf2a3c403ebf6691b3f05edd9143803ca085cff57e053eec2f8fea46ea778a68c9be885bc28225bc5f309be4a2b74d3a03945319dd3c7122fed6ff53bb8b8cb3a03c"; } // The extracted RSA modulus of the leaf x509 signing certificate function signingMod() public pure override returns (bytes memory) { - return - hex"9F3C647EB5773CBB512D2732C0D7415EBB55A0FA9EDE2E649199E6821DB910D53177370977466A6A5E4786CCD2DDEBD4149D6A2F6325529DD10CC98737B0779C1A07E29C47A1AE004948476C489F45A5A15D7AC8ECC6ACC645ADB43D87679DF59C093BC5A2E9696C5478541B979E754B573914BE55D32FF4C09DDF27219934CD990527B3F92ED78FBF29246ABECB71240EF39C2D7107B447545A7FFB10EB060A68A98580219E36910952683892D6A5E2A80803193E407531404E36B315623799AA825074409754A2DFE8F5AFD5FE631E1FC2AF3808906F28A790D9DD9FE060939B125790C5805D037DF56A99531B96DE69DE33ED226CC1207D1042B5C9AB7F404FC711C0FE4769FB9578B1DC0EC469EA1A25E0FF9914886EF2699B235BB4847DD6FF40B606E6170793C2FB98B314587F9CFD257362DFEAB10B3BD2D97673A1A4BD44C453AAF47FC1F2D3D0F384F74A06F89C089F0DA6CDB7FCEEE8C9821A8E54F25C0416D18C46839A5F8012FBDD3DC74D256279ADC2C0D55AFF6F0622425D1B"; + return hex"9F3C647EB5773CBB512D2732C0D7415EBB55A0FA9EDE2E649199E6821DB910D53177370977466A6A5E4786CCD2DDEBD4149D6A2F6325529DD10CC98737B0779C1A07E29C47A1AE004948476C489F45A5A15D7AC8ECC6ACC645ADB43D87679DF59C093BC5A2E9696C5478541B979E754B573914BE55D32FF4C09DDF27219934CD990527B3F92ED78FBF29246ABECB71240EF39C2D7107B447545A7FFB10EB060A68A98580219E36910952683892D6A5E2A80803193E407531404E36B315623799AA825074409754A2DFE8F5AFD5FE631E1FC2AF3808906F28A790D9DD9FE060939B125790C5805D037DF56A99531B96DE69DE33ED226CC1207D1042B5C9AB7F404FC711C0FE4769FB9578B1DC0EC469EA1A25E0FF9914886EF2699B235BB4847DD6FF40B606E6170793C2FB98B314587F9CFD257362DFEAB10B3BD2D97673A1A4BD44C453AAF47FC1F2D3D0F384F74A06F89C089F0DA6CDB7FCEEE8C9821A8E54F25C0416D18C46839A5F8012FBDD3DC74D256279ADC2C0D55AFF6F0622425D1B"; } // The extracted RSA exponent of the leaf x509 signing certificate @@ -114,8 +107,7 @@ contract Guardian2RaveEvidence is MockEvidence { // The expected payload value in this specific report function payload() public pure override returns (bytes memory) { // This is a hex-encoded 48 byte BLS public key - return - hex"04f050c3ce5d575600af388f41876e2962499a97bc8fcfa4a12adf7e4a486a3be9a1db0efd899c09723f83fe490e8215fd596a5f03c819e28a8b95f3cce6238613"; + return hex"04f050c3ce5d575600af388f41876e2962499a97bc8fcfa4a12adf7e4a486a3be9a1db0efd899c09723f83fe490e8215fd596a5f03c819e28a8b95f3cce6238613"; } } @@ -138,20 +130,17 @@ contract Guardian1RaveEvidence is MockEvidence { // The leaf x509 signing certificate's signature over the report function sig() public pure override returns (bytes memory) { // base64 decoded signature as hex - return - hex"6cc5a3354c3504677252a3ee19a9d4c64eb8e8ed2bcdd8a7fcfeee88eb8214c0975730b03aeec9b1f56e7cd37030da73b63c8fefb85de1fd2ae70f4d485db8228c76c6dc5da2ce5458c172852d2faec9cca97a1ef4cc19280b84b841e05a7ee33207db18496a3fb515f978ed161d4b7e4c585e76641605be2c31418e04ac35686fa0841b3680d24dac35d8edbfa4c7549b712830b1c0064ae4c0463428ebd0ee833f341fcb2125e9c06d9e67d41f2dc3afe26b1e81d5dbaed1eab6a656e40b9188206f8fdc2745d90db2ebcb671ee44932b9ca7f607c8107bd0c96689bd6aaf9dcdd03afcb433925cacf994527121b79a425a32a86984af5434005b8f422faaa"; + return hex"6cc5a3354c3504677252a3ee19a9d4c64eb8e8ed2bcdd8a7fcfeee88eb8214c0975730b03aeec9b1f56e7cd37030da73b63c8fefb85de1fd2ae70f4d485db8228c76c6dc5da2ce5458c172852d2faec9cca97a1ef4cc19280b84b841e05a7ee33207db18496a3fb515f978ed161d4b7e4c585e76641605be2c31418e04ac35686fa0841b3680d24dac35d8edbfa4c7549b712830b1c0064ae4c0463428ebd0ee833f341fcb2125e9c06d9e67d41f2dc3afe26b1e81d5dbaed1eab6a656e40b9188206f8fdc2745d90db2ebcb671ee44932b9ca7f607c8107bd0c96689bd6aaf9dcdd03afcb433925cacf994527121b79a425a32a86984af5434005b8f422faaa"; } // The leaf x509 signing certificate used to sign the report function signingCert() public pure override returns (bytes memory) { - return - hex"308204a130820309a003020102020900d107765d32a3b096300d06092a864886f70d01010b0500307e310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341301e170d3136313132323039333635385a170d3236313132303039333635385a307b310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e312d302b06035504030c24496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e6730820122300d06092a864886f70d01010105000382010f003082010a0282010100a97a2de0e66ea6147c9ee745ac0162686c7192099afc4b3f040fad6de093511d74e802f510d716038157dcaf84f4104bd3fed7e6b8f99c8817fd1ff5b9b864296c3d81fa8f1b729e02d21d72ffee4ced725efe74bea68fbc4d4244286fcdd4bf64406a439a15bcb4cf67754489c423972b4a80df5c2e7c5bc2dbaf2d42bb7b244f7c95bf92c75d3b33fc5410678a89589d1083da3acc459f2704cd99598c275e7c1878e00757e5bdb4e840226c11c0a17ff79c80b15c1ddb5af21cc2417061fbd2a2da819ed3b72b7efaa3bfebe2805c9b8ac19aa346512d484cfc81941e15f55881cc127e8f7aa12300cd5afb5742fa1d20cb467a5beb1c666cf76a368978b50203010001a381a43081a1301f0603551d2304183016801478437b76a67ebcd0af7e4237eb357c3b8701513c300e0603551d0f0101ff0404030206c0300c0603551d130101ff0402300030600603551d1f045930573055a053a051864f687474703a2f2f7472757374656473657276696365732e696e74656c2e636f6d2f636f6e74656e742f43524c2f5347582f4174746573746174696f6e5265706f72745369676e696e6743412e63726c300d06092a864886f70d01010b050003820181006708b61b5c2bd215473e2b46af99284fbb939d3f3b152c996f1a6af3b329bd220b1d3b610f6bce2e6753bded304db21912f385256216cfcba456bd96940be892f5690c260d1ef84f1606040222e5fe08e5326808212a447cfdd64a46e94bf29f6b4b9a721d25b3c4e2f62f58baed5d77c505248f0f801f9fbfb7fd752080095cee80938b339f6dbb4e165600e20e4a718812d49d9901e310a9b51d66c79909c6996599fae6d76a79ef145d9943bf1d3e35d3b42d1fb9a45cbe8ee334c166eee7d32fcdc9935db8ec8bb1d8eb3779dd8ab92b6e387f0147450f1e381d08581fb83df33b15e000a59be57ea94a3a52dc64bdaec959b3464c91e725bbdaea3d99e857e380a23c9d9fb1ef58e9e42d71f12130f9261d7234d6c37e2b03dba40dfdfb13ac4ad8e13fd3756356b6b50015a3ec9580b815d87c2cef715cd28df00bbf2a3c403ebf6691b3f05edd9143803ca085cff57e053eec2f8fea46ea778a68c9be885bc28225bc5f309be4a2b74d3a03945319dd3c7122fed6ff53bb8b8cb3a03c"; + return hex"308204a130820309a003020102020900d107765d32a3b096300d06092a864886f70d01010b0500307e310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341301e170d3136313132323039333635385a170d3236313132303039333635385a307b310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e312d302b06035504030c24496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e6730820122300d06092a864886f70d01010105000382010f003082010a0282010100a97a2de0e66ea6147c9ee745ac0162686c7192099afc4b3f040fad6de093511d74e802f510d716038157dcaf84f4104bd3fed7e6b8f99c8817fd1ff5b9b864296c3d81fa8f1b729e02d21d72ffee4ced725efe74bea68fbc4d4244286fcdd4bf64406a439a15bcb4cf67754489c423972b4a80df5c2e7c5bc2dbaf2d42bb7b244f7c95bf92c75d3b33fc5410678a89589d1083da3acc459f2704cd99598c275e7c1878e00757e5bdb4e840226c11c0a17ff79c80b15c1ddb5af21cc2417061fbd2a2da819ed3b72b7efaa3bfebe2805c9b8ac19aa346512d484cfc81941e15f55881cc127e8f7aa12300cd5afb5742fa1d20cb467a5beb1c666cf76a368978b50203010001a381a43081a1301f0603551d2304183016801478437b76a67ebcd0af7e4237eb357c3b8701513c300e0603551d0f0101ff0404030206c0300c0603551d130101ff0402300030600603551d1f045930573055a053a051864f687474703a2f2f7472757374656473657276696365732e696e74656c2e636f6d2f636f6e74656e742f43524c2f5347582f4174746573746174696f6e5265706f72745369676e696e6743412e63726c300d06092a864886f70d01010b050003820181006708b61b5c2bd215473e2b46af99284fbb939d3f3b152c996f1a6af3b329bd220b1d3b610f6bce2e6753bded304db21912f385256216cfcba456bd96940be892f5690c260d1ef84f1606040222e5fe08e5326808212a447cfdd64a46e94bf29f6b4b9a721d25b3c4e2f62f58baed5d77c505248f0f801f9fbfb7fd752080095cee80938b339f6dbb4e165600e20e4a718812d49d9901e310a9b51d66c79909c6996599fae6d76a79ef145d9943bf1d3e35d3b42d1fb9a45cbe8ee334c166eee7d32fcdc9935db8ec8bb1d8eb3779dd8ab92b6e387f0147450f1e381d08581fb83df33b15e000a59be57ea94a3a52dc64bdaec959b3464c91e725bbdaea3d99e857e380a23c9d9fb1ef58e9e42d71f12130f9261d7234d6c37e2b03dba40dfdfb13ac4ad8e13fd3756356b6b50015a3ec9580b815d87c2cef715cd28df00bbf2a3c403ebf6691b3f05edd9143803ca085cff57e053eec2f8fea46ea778a68c9be885bc28225bc5f309be4a2b74d3a03945319dd3c7122fed6ff53bb8b8cb3a03c"; } // The extracted RSA modulus of the leaf x509 signing certificate function signingMod() public pure override returns (bytes memory) { - return - hex"9F3C647EB5773CBB512D2732C0D7415EBB55A0FA9EDE2E649199E6821DB910D53177370977466A6A5E4786CCD2DDEBD4149D6A2F6325529DD10CC98737B0779C1A07E29C47A1AE004948476C489F45A5A15D7AC8ECC6ACC645ADB43D87679DF59C093BC5A2E9696C5478541B979E754B573914BE55D32FF4C09DDF27219934CD990527B3F92ED78FBF29246ABECB71240EF39C2D7107B447545A7FFB10EB060A68A98580219E36910952683892D6A5E2A80803193E407531404E36B315623799AA825074409754A2DFE8F5AFD5FE631E1FC2AF3808906F28A790D9DD9FE060939B125790C5805D037DF56A99531B96DE69DE33ED226CC1207D1042B5C9AB7F404FC711C0FE4769FB9578B1DC0EC469EA1A25E0FF9914886EF2699B235BB4847DD6FF40B606E6170793C2FB98B314587F9CFD257362DFEAB10B3BD2D97673A1A4BD44C453AAF47FC1F2D3D0F384F74A06F89C089F0DA6CDB7FCEEE8C9821A8E54F25C0416D18C46839A5F8012FBDD3DC74D256279ADC2C0D55AFF6F0622425D1B"; + return hex"9F3C647EB5773CBB512D2732C0D7415EBB55A0FA9EDE2E649199E6821DB910D53177370977466A6A5E4786CCD2DDEBD4149D6A2F6325529DD10CC98737B0779C1A07E29C47A1AE004948476C489F45A5A15D7AC8ECC6ACC645ADB43D87679DF59C093BC5A2E9696C5478541B979E754B573914BE55D32FF4C09DDF27219934CD990527B3F92ED78FBF29246ABECB71240EF39C2D7107B447545A7FFB10EB060A68A98580219E36910952683892D6A5E2A80803193E407531404E36B315623799AA825074409754A2DFE8F5AFD5FE631E1FC2AF3808906F28A790D9DD9FE060939B125790C5805D037DF56A99531B96DE69DE33ED226CC1207D1042B5C9AB7F404FC711C0FE4769FB9578B1DC0EC469EA1A25E0FF9914886EF2699B235BB4847DD6FF40B606E6170793C2FB98B314587F9CFD257362DFEAB10B3BD2D97673A1A4BD44C453AAF47FC1F2D3D0F384F74A06F89C089F0DA6CDB7FCEEE8C9821A8E54F25C0416D18C46839A5F8012FBDD3DC74D256279ADC2C0D55AFF6F0622425D1B"; } // The extracted RSA exponent of the leaf x509 signing certificate @@ -172,7 +161,6 @@ contract Guardian1RaveEvidence is MockEvidence { // The expected payload value in this specific report function payload() public pure override returns (bytes memory) { // This is a hex-encoded 48 byte BLS public key - return - hex"04caf1f9cd82a1284626d405d285250fd6c4f58c469fda05d7fd4f29318aae38e7ccc6f4eaced74d3e2aa3fc0576093860d3045263c4183d694a39911ee9031c73"; + return hex"04caf1f9cd82a1284626d405d285250fd6c4f58c469fda05d7fd4f29318aae38e7ccc6f4eaced74d3e2aa3fc0576093860d3045263c4183d694a39911ee9031c73"; } } diff --git a/mainnet-contracts/test/mocks/DelegationManagerMock.sol b/mainnet-contracts/test/mocks/DelegationManagerMock.sol index 49f5b402..9677c0cc 100644 --- a/mainnet-contracts/test/mocks/DelegationManagerMock.sol +++ b/mainnet-contracts/test/mocks/DelegationManagerMock.sol @@ -23,14 +23,15 @@ contract DelegationManagerMock { mapping(address => address) public delegatedTo; function registerAsOperator(address initDelegationApprover, uint32 allocationDelay, string calldata metadataURI) - external - { } + external { } function delegateTo( address operator, IDelegationManager.SignatureWithExpiry memory, /*approverSignatureAndExpiry*/ bytes32 /*approverSalt*/ - ) external { + ) + external + { delegatedTo[msg.sender] = operator; } @@ -47,9 +48,25 @@ contract DelegationManagerMock { return withdrawalRoot; } - function increaseDelegatedShares(address, /*staker*/ IStrategy, /*strategy*/ uint256 /*shares*/ ) external pure { } - - function decreaseDelegatedShares(address, /*staker*/ IStrategy, /*strategy*/ uint256 /*shares*/ ) external pure { } + function increaseDelegatedShares( + address, + /*staker*/ + IStrategy, + /*strategy*/ + uint256 /*shares*/ + ) + external + pure { } + + function decreaseDelegatedShares( + address, + /*staker*/ + IStrategy, + /*strategy*/ + uint256 /*shares*/ + ) + external + pure { } function earningsReceiver(address operator) external pure returns (address) { return operator; @@ -59,7 +76,13 @@ contract DelegationManagerMock { return operator; } - function stakerOptOutWindowBlocks(address /*operator*/ ) external pure returns (uint256) { + function stakerOptOutWindowBlocks( + address /*operator*/ + ) + external + pure + returns (uint256) + { return 0; } @@ -71,7 +94,13 @@ contract DelegationManagerMock { * @notice Minimum delay enforced by this contract per Strategy for completing queued withdrawals. Measured in blocks, and adjustable by this contract's owner, * up to a maximum of `MAX_WITHDRAWAL_DELAY_BLOCKS`. Minimum value is 0 (i.e. no delay enforced). */ - function strategyWithdrawalDelayBlocks(IStrategy /*strategy*/ ) external pure returns (uint256) { + function strategyWithdrawalDelayBlocks( + IStrategy /*strategy*/ + ) + external + pure + returns (uint256) + { return 0; } @@ -81,7 +110,13 @@ contract DelegationManagerMock { returns (uint256[] memory) { } - function getWithdrawalDelay(IStrategy[] calldata /*strategies*/ ) public pure returns (uint256) { + function getWithdrawalDelay( + IStrategy[] calldata /*strategies*/ + ) + public + pure + returns (uint256) + { return 0; } @@ -89,19 +124,41 @@ contract DelegationManagerMock { return (delegatedTo[staker] != address(0)); } - function isNotDelegated(address /*staker*/ ) external pure returns (bool) { } + function isNotDelegated( + address /*staker*/ + ) + external + pure + returns (bool) + { } // function isOperator(address /*operator*/) external pure returns (bool) {} - function stakerNonce(address /*staker*/ ) external pure returns (uint256) { } + function stakerNonce( + address /*staker*/ + ) + external + pure + returns (uint256) + { } - function delegationApproverSaltIsSpent(address, /*delegationApprover*/ bytes32 /*salt*/ ) + function delegationApproverSaltIsSpent( + address, + /*delegationApprover*/ + bytes32 /*salt*/ + ) external pure returns (bool) { } - function calculateCurrentStakerDelegationDigestHash(address, /*staker*/ address, /*operator*/ uint256 /*expiry*/ ) + function calculateCurrentStakerDelegationDigestHash( + address, + /*staker*/ + address, + /*operator*/ + uint256 /*expiry*/ + ) external view returns (bytes32) @@ -112,7 +169,11 @@ contract DelegationManagerMock { uint256, /*stakerNonce*/ address, /*operator*/ uint256 /*expiry*/ - ) external view returns (bytes32) { } + ) + external + view + returns (bytes32) + { } function calculateDelegationApprovalDigestHash( address, /*staker*/ @@ -120,15 +181,31 @@ contract DelegationManagerMock { address, /*_delegationApprover*/ bytes32, /*approverSalt*/ uint256 /*expiry*/ - ) external view returns (bytes32) { } + ) + external + view + returns (bytes32) + { } - function calculateStakerDigestHash(address, /*staker*/ address, /*operator*/ uint256 /*expiry*/ ) + function calculateStakerDigestHash( + address, + /*staker*/ + address, + /*operator*/ + uint256 /*expiry*/ + ) external pure returns (bytes32 stakerDigestHash) { } - function calculateApproverDigestHash(address, /*staker*/ address, /*operator*/ uint256 /*expiry*/ ) + function calculateApproverDigestHash( + address, + /*staker*/ + address, + /*operator*/ + uint256 /*expiry*/ + ) external pure returns (bytes32 approverDigestHash) @@ -139,7 +216,11 @@ contract DelegationManagerMock { address, /*avs*/ bytes32, /*salt*/ uint256 /*expiry*/ - ) external pure returns (bytes32 digestHash) { } + ) + external + pure + returns (bytes32 digestHash) + { } function DOMAIN_TYPEHASH() external view returns (bytes32) { } @@ -153,7 +234,11 @@ contract DelegationManagerMock { function cumulativeWithdrawalsQueued(address staker) external view returns (uint256) { } - function calculateWithdrawalRoot(IDelegationManager.Withdrawal memory withdrawal) external pure returns (bytes32) { } + function calculateWithdrawalRoot(IDelegationManager.Withdrawal memory withdrawal) + external + pure + returns (bytes32) + { } function operatorSaltIsSpent(address avs, bytes32 salt) external view returns (bool) { } @@ -177,8 +262,7 @@ contract DelegationManagerMock { ) external { } function removeShares(IStrategyManager strategyManager, address staker, IStrategy strategy, uint256 shares) - external - { } + external { } function withdrawSharesAsTokens( IStrategyManager strategyManager, diff --git a/mainnet-contracts/test/mocks/EigenPodManagerMock.sol b/mainnet-contracts/test/mocks/EigenPodManagerMock.sol index 67312086..3911ff45 100644 --- a/mainnet-contracts/test/mocks/EigenPodManagerMock.sol +++ b/mainnet-contracts/test/mocks/EigenPodManagerMock.sol @@ -63,9 +63,11 @@ contract EigenPodManagerMock is IEigenPodManager, Test { * @dev Callable only by the podOwner's EigenPod contract. * @dev Reverts if `sharesDelta` is not a whole Gwei amount */ - function recordBeaconChainETHBalanceUpdate(address podOwner, uint256 prevRestakedBalanceWei, int256 balanceDeltaWei) - external - { } + function recordBeaconChainETHBalanceUpdate( + address podOwner, + uint256 prevRestakedBalanceWei, + int256 balanceDeltaWei + ) external { } /// @notice Returns the address of the `podOwner`'s EigenPod if it has been deployed. function ownerToPod(address podOwner) external view returns (IEigenPod) { } diff --git a/mainnet-contracts/test/mocks/stETHMock.sol b/mainnet-contracts/test/mocks/stETHMock.sol index 7cad3cc0..a782a98a 100644 --- a/mainnet-contracts/test/mocks/stETHMock.sol +++ b/mainnet-contracts/test/mocks/stETHMock.sol @@ -23,7 +23,13 @@ contract stETHMock is IStETH, ERC20, ERC20Burnable { _burn(holder, amount); } - function submit(address /*referral*/ ) external payable returns (uint256) { + function submit( + address /*referral*/ + ) + external + payable + returns (uint256) + { uint256 sharesToMint = getSharesByPooledEth(msg.value); _mint(msg.sender, sharesToMint); return sharesToMint; diff --git a/mainnet-contracts/test/unit/EnclaveVerifier.t.sol b/mainnet-contracts/test/unit/EnclaveVerifier.t.sol index c64573a4..f67092d1 100644 --- a/mainnet-contracts/test/unit/EnclaveVerifier.t.sol +++ b/mainnet-contracts/test/unit/EnclaveVerifier.t.sol @@ -8,7 +8,9 @@ import { RaveEvidence } from "../../src/struct/RaveEvidence.sol"; import { MockEvidence } from "rave-test/mocks/MockEvidence.sol"; import { UnitTestHelper } from "../helpers/UnitTestHelper.sol"; import { - Guardian1RaveEvidence, Guardian2RaveEvidence, Guardian3RaveEvidence + Guardian1RaveEvidence, + Guardian2RaveEvidence, + Guardian3RaveEvidence } from "../helpers/GuardiansRaveEvidence.sol"; contract EnclaveVerifierTest is UnitTestHelper { @@ -75,11 +77,7 @@ contract EnclaveVerifierTest is UnitTestHelper { vm.expectRevert(IEnclaveVerifier.StaleEvidence.selector); verifier.verifyEvidence({ - blockNumber: 0, - evidence: evidence, - raveCommitment: commitment, - mrenclave: mrenclave, - mrsigner: mrsigner + blockNumber: 0, evidence: evidence, raveCommitment: commitment, mrenclave: mrenclave, mrsigner: mrsigner }); } diff --git a/mainnet-contracts/test/unit/L1RewardManager.t.sol b/mainnet-contracts/test/unit/L1RewardManager.t.sol index 2b148dd4..3d7c210f 100644 --- a/mainnet-contracts/test/unit/L1RewardManager.t.sol +++ b/mainnet-contracts/test/unit/L1RewardManager.t.sol @@ -20,8 +20,9 @@ import { ROLE_ID_VAULT_WITHDRAWER } from "../../script/Roles.sol"; import { InvalidAddress, Unauthorized } from "mainnet-contracts/src/Errors.sol"; -import { GenerateRewardManagerCalldata } from - "../../script/AccessManagerMigrations/03_GenerateRewardManagerCalldata.s.sol"; +import { + GenerateRewardManagerCalldata +} from "../../script/AccessManagerMigrations/03_GenerateRewardManagerCalldata.s.sol"; //LayerZero imports import { Packet } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol"; @@ -38,7 +39,8 @@ import { ERC20Mock } from "../mocks/ERC20Mock.sol"; import { OFTAdapterMock } from "partners-layerzero/test/mocks/OFTAdapterMock.sol"; import { OFTMock } from "partners-layerzero/test/mocks/OFTMock.sol"; import { - IOAppOptionsType3, EnforcedOptionParam + IOAppOptionsType3, + EnforcedOptionParam } from "@layerzerolabs/oapp-evm/contracts/oapp/libs/OAppOptionsType3.sol"; // import { IOFT } from "../../src/interface/LayerZero/IOFT.sol"; @@ -121,9 +123,10 @@ contract L1RewardManagerTest is UnitTestHelper, TestHelperOz5 { L2RewardManager l2RewardManagerImpl = new L2RewardManager(address(l1RewardManagerProxy), address(xpufETH)); - UUPSUpgradeable(address(l2RewardManagerProxy)).upgradeToAndCall( - address(l2RewardManagerImpl), abi.encodeCall(L2RewardManager.initialize, (address(accessManager))) - ); + UUPSUpgradeable(address(l2RewardManagerProxy)) + .upgradeToAndCall( + address(l2RewardManagerImpl), abi.encodeCall(L2RewardManager.initialize, (address(accessManager))) + ); l2RewardManager = L2RewardManager(address(l2RewardManagerProxy)); l1RewardManager = L1RewardManager(address(l1RewardManagerProxy)); @@ -156,9 +159,8 @@ contract L1RewardManagerTest is UnitTestHelper, TestHelperOz5 { accessManager.setTargetFunctionRole(address(pufferVault), pmmSelectors, ROLE_ID_VAULT_WITHDRAWER); accessManager.grantRole(ROLE_ID_VAULT_WITHDRAWER, address(pufferModuleManager), 0); - bytes memory cd = new GenerateRewardManagerCalldata().generateL1Calldata( - address(l1RewardManager), address(layerzeroL1Endpoint) - ); + bytes memory cd = new GenerateRewardManagerCalldata() + .generateL1Calldata(address(l1RewardManager), address(layerzeroL1Endpoint)); (bool s,) = address(accessManager).call(cd); require(s, "failed setupAccess GenerateRewardManagerCalldata"); @@ -404,13 +406,14 @@ contract L1RewardManagerTest is UnitTestHelper, TestHelperOz5 { allowedDailyFrequency allowMintAmount(100 ether) { - IL1RewardManager.MintAndBridgeParams memory params = IL1RewardManager.MintAndBridgeParams({ - rewardsAmount: 1 ether, - startEpoch: 1, - endEpoch: 2, - rewardsRoot: bytes32(hex"aabbccdd"), - rewardsURI: "uri" - }); + IL1RewardManager.MintAndBridgeParams memory params = + IL1RewardManager.MintAndBridgeParams({ + rewardsAmount: 1 ether, + startEpoch: 1, + endEpoch: 2, + rewardsRoot: bytes32(hex"aabbccdd"), + rewardsURI: "uri" + }); // ✅ Use arbitrary value for LayerZero fees uint256 layerZeroFee = 0.01 ether; @@ -486,9 +489,7 @@ contract L1RewardManagerTest is UnitTestHelper, TestHelperOz5 { // Test that we can call setEnforcedOptions (this means the interface is working) EnforcedOptionParam[] memory testOptions = new EnforcedOptionParam[](1); testOptions[0] = EnforcedOptionParam({ - eid: dstEid, - msgType: 1, - options: OptionsBuilder.newOptions().addExecutorLzReceiveOption(50000, 0) + eid: dstEid, msgType: 1, options: OptionsBuilder.newOptions().addExecutorLzReceiveOption(50000, 0) }); // This should not revert, indicating the enforced options functionality is available @@ -798,11 +799,7 @@ contract L1RewardManagerTest is UnitTestHelper, TestHelperOz5 { assertEq(l1RewardManager.getCurrentIntervalEndEpoch(), 350, "currentIntervalEndEpoch should be updated to 350"); } - function testRevert_MintAfterRevertWithInvalidStartEpoch() - public - allowedDailyFrequency - allowMintAmount(100 ether) - { + function testRevert_MintAfterRevertWithInvalidStartEpoch() public allowedDailyFrequency allowMintAmount(100 ether) { // First mint IL1RewardManager.MintAndBridgeParams memory params1 = IL1RewardManager.MintAndBridgeParams({ rewardsAmount: 100 ether, @@ -949,7 +946,11 @@ contract L1RewardManagerTest is UnitTestHelper, TestHelperOz5 { uint32 _srcEid, uint256 _amountLD, bytes memory _composeMsg // 0x[composeFrom][composeMsg] - ) internal pure returns (bytes memory _msg) { + ) + internal + pure + returns (bytes memory _msg) + { _msg = abi.encodePacked(_nonce, _srcEid, _amountLD, _composeMsg); } } diff --git a/mainnet-contracts/test/unit/PUFER.t.sol b/mainnet-contracts/test/unit/PUFER.t.sol index 10a09987..0f53f187 100644 --- a/mainnet-contracts/test/unit/PUFER.t.sol +++ b/mainnet-contracts/test/unit/PUFER.t.sol @@ -5,8 +5,9 @@ import { PUFFER } from "../../src/PUFFER.sol"; import { UnitTestHelper } from "../helpers/UnitTestHelper.sol"; contract MockLocker { -// do nothing -} + // do nothing + + } contract PUFFERTest is UnitTestHelper { address owner = makeAddr("multisig"); diff --git a/mainnet-contracts/test/unit/PufferModuleManager.t.sol b/mainnet-contracts/test/unit/PufferModuleManager.t.sol index afd284a2..19067a86 100644 --- a/mainnet-contracts/test/unit/PufferModuleManager.t.sol +++ b/mainnet-contracts/test/unit/PufferModuleManager.t.sol @@ -62,9 +62,8 @@ contract PufferModuleManagerTest is UnitTestHelper { vm.stopPrank(); // No restaking is a custom default module (non beacon upgradeable) - (bool success,) = pufferProtocol.getModuleAddress(bytes32("DEGEN")).call( - abi.encodeCall(PufferModuleUpgrade.getMagicValue, ()) - ); + (bool success,) = pufferProtocol.getModuleAddress(bytes32("DEGEN")) + .call(abi.encodeCall(PufferModuleUpgrade.getMagicValue, ())); assertTrue(!success, "should not succeed"); @@ -74,9 +73,8 @@ contract PufferModuleManagerTest is UnitTestHelper { accessManager.execute(moduleBeacon, abi.encodeCall(UpgradeableBeacon.upgradeTo, address(upgrade))); vm.stopPrank(); - (bool s, bytes memory data) = pufferProtocol.getModuleAddress(bytes32("DEGEN")).call( - abi.encodeCall(PufferModuleUpgrade.getMagicValue, ()) - ); + (bool s, bytes memory data) = pufferProtocol.getModuleAddress(bytes32("DEGEN")) + .call(abi.encodeCall(PufferModuleUpgrade.getMagicValue, ())); assertTrue(s, "should succeed"); assertEq(abi.decode(data, (uint256)), 1337, "got the number"); } @@ -120,9 +118,7 @@ contract PufferModuleManagerTest is UnitTestHelper { address mockAvs = makeAddr("mockAvs"); IAllocationManagerTypes.DeregisterParams memory deregisterParams = IAllocationManagerTypes.DeregisterParams({ - operator: address(operator), - avs: mockAvs, - operatorSetIds: new uint32[](1) + operator: address(operator), avs: mockAvs, operatorSetIds: new uint32[](1) }); vm.expectRevert(Unauthorized.selector); @@ -363,8 +359,7 @@ contract PufferModuleManagerTest is UnitTestHelper { function _createRestakingOperator() internal returns (RestakingOperator) { RestakingOperator operator = pufferModuleManager.createNewRestakingOperator({ - metadataURI: "https://puffer.fi/metadata.json", - allocationDelay: 500 + metadataURI: "https://puffer.fi/metadata.json", allocationDelay: 500 }); return operator; diff --git a/mainnet-contracts/test/unit/PufferProtocol.t.sol b/mainnet-contracts/test/unit/PufferProtocol.t.sol index bff105a3..f7045f10 100644 --- a/mainnet-contracts/test/unit/PufferProtocol.t.sol +++ b/mainnet-contracts/test/unit/PufferProtocol.t.sol @@ -251,7 +251,7 @@ contract PufferProtocolTest is UnitTestHelper { blsEncryptedPrivKeyShares: new bytes[](3), blsPubKeySet: new bytes(48), raveEvidence: new bytes(0) // No rave - }); + }); vm.expectEmit(true, true, true, true); emit ValidatorKeyRegistered(pubKey, 0, PUFFER_MODULE_0, false); @@ -1445,8 +1445,7 @@ contract PufferProtocolTest is UnitTestHelper { vm.stopPrank(); // this contract has the PAYMASTER role, so we need to stop the prank pufferProtocol.batchHandleWithdrawals({ - validatorInfos: stopInfos, - guardianEOASignatures: _getHandleBatchWithdrawalMessage(stopInfos) + validatorInfos: stopInfos, guardianEOASignatures: _getHandleBatchWithdrawalMessage(stopInfos) }); } @@ -1869,9 +1868,7 @@ contract PufferProtocolTest is UnitTestHelper { _validatorSignature(), withdrawalCredentials, pufferProtocol.getDepositDataRoot({ - pubKey: pubKey, - signature: _validatorSignature(), - withdrawalCredentials: withdrawalCredentials + pubKey: pubKey, signature: _validatorSignature(), withdrawalCredentials: withdrawalCredentials }) ); @@ -1970,14 +1967,12 @@ contract PufferProtocolTest is UnitTestHelper { blsPubKey: pubKey, // key length must be 48 byte signature: validatorSignature, depositDataRoot: pufferProtocol.getDepositDataRoot({ - pubKey: pubKey, - signature: validatorSignature, - withdrawalCredentials: withdrawalCredentials + pubKey: pubKey, signature: validatorSignature, withdrawalCredentials: withdrawalCredentials }), blsEncryptedPrivKeyShares: new bytes[](3), blsPubKeySet: new bytes(48), raveEvidence: bytes("mock rave") // Guardians are checking it off chain - }); + }); return validatorData; } diff --git a/mainnet-contracts/test/unit/PufferWithdrawalManager.t.sol b/mainnet-contracts/test/unit/PufferWithdrawalManager.t.sol index c843ea86..f368a35b 100644 --- a/mainnet-contracts/test/unit/PufferWithdrawalManager.t.sol +++ b/mainnet-contracts/test/unit/PufferWithdrawalManager.t.sol @@ -8,8 +8,9 @@ import { IPufferWithdrawalManager } from "src/interface/IPufferWithdrawalManager import { AccessManager } from "@openzeppelin/contracts/access/manager/AccessManager.sol"; import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import { Permit } from "../../src/structs/Permit.sol"; -import { Generate2StepWithdrawalsCalldata } from - "../../script/AccessManagerMigrations/04_Generate2StepWithdrawalsCalldata.s.sol"; +import { + Generate2StepWithdrawalsCalldata +} from "../../script/AccessManagerMigrations/04_Generate2StepWithdrawalsCalldata.s.sol"; import { PufferWithdrawalManagerTests } from "../mocks/PufferWithdrawalManagerTests.sol"; import { PufferVaultV5 } from "../../src/PufferVaultV5.sol"; import { IWETH } from "../../src/interface/Other/IWETH.sol"; @@ -43,27 +44,24 @@ contract PufferWithdrawalManagerTest is UnitTestHelper { // deploy an ERC1967Proxy withdrawalManager = PufferWithdrawalManager( - ( - payable( - new ERC1967Proxy{ salt: bytes32("PufferWithdrawalManager") }( + (payable(new ERC1967Proxy{ salt: bytes32("PufferWithdrawalManager") }( address(withdrawalManagerImpl), abi.encodeCall(PufferWithdrawalManager.initialize, address(accessManager)) - ) - ) - ) + ))) ); vm.label(address(withdrawalManager), "PufferWithdrawalManager"); vm.startPrank(_broadcaster); - bytes memory encodedCalldata = new Generate2StepWithdrawalsCalldata().run({ - pufferVaultProxy: address(pufferVault), - withdrawalManagerProxy: address(withdrawalManager), - paymaster: PAYMASTER, - withdrawalFinalizer: DAO, - pufferProtocolProxy: address(pufferProtocol) - }); + bytes memory encodedCalldata = new Generate2StepWithdrawalsCalldata() + .run({ + pufferVaultProxy: address(pufferVault), + withdrawalManagerProxy: address(withdrawalManager), + paymaster: PAYMASTER, + withdrawalFinalizer: DAO, + pufferProtocolProxy: address(pufferProtocol) + }); (bool success,) = address(accessManager).call(encodedCalldata); require(success, "AccessManager.call failed"); @@ -715,27 +713,24 @@ contract PufferWithdrawalManagerTest is UnitTestHelper { // deploy an ERC1967Proxy withdrawalManager = PufferWithdrawalManager( - ( - payable( - new ERC1967Proxy{ salt: bytes32("newManager") }( + (payable(new ERC1967Proxy{ salt: bytes32("newManager") }( address(withdrawalManagerImpl), abi.encodeCall(PufferWithdrawalManager.initialize, address(accessManager)) - ) - ) - ) + ))) ); vm.label(address(withdrawalManager), "PufferWithdrawalManager"); vm.startPrank(_broadcaster); - bytes memory encodedCalldata = new Generate2StepWithdrawalsCalldata().run({ - pufferVaultProxy: address(pufferVault), - withdrawalManagerProxy: address(withdrawalManager), - paymaster: PAYMASTER, - withdrawalFinalizer: DAO, - pufferProtocolProxy: address(pufferProtocol) - }); + bytes memory encodedCalldata = new Generate2StepWithdrawalsCalldata() + .run({ + pufferVaultProxy: address(pufferVault), + withdrawalManagerProxy: address(withdrawalManager), + paymaster: PAYMASTER, + withdrawalFinalizer: DAO, + pufferProtocolProxy: address(pufferProtocol) + }); (bool success,) = address(accessManager).call(encodedCalldata); require(success, "AccessManager.call failed"); diff --git a/mainnet-contracts/test/unit/ValidatorTicketPricer.t.sol b/mainnet-contracts/test/unit/ValidatorTicketPricer.t.sol index 46879d9b..e5271739 100644 --- a/mainnet-contracts/test/unit/ValidatorTicketPricer.t.sol +++ b/mainnet-contracts/test/unit/ValidatorTicketPricer.t.sol @@ -118,9 +118,9 @@ contract ValidatorTicketPricerTest is UnitTestHelper { validatorTicketPricer.setDailyRewardsAndPostMintPrice(mevPayouts, consensusRewards); uint16 _BPS_DECIMALS = 1e4; - uint256 expectedPrice = ( - (_BPS_DECIMALS - validatorTicketPricer.getDiscountRateBps()) * (mevPayouts + consensusRewards) - ) / _BPS_DECIMALS; + uint256 expectedPrice = + ((_BPS_DECIMALS - validatorTicketPricer.getDiscountRateBps()) * (mevPayouts + consensusRewards)) + / _BPS_DECIMALS; assertEq(pufferOracle.getValidatorTicketPrice(), expectedPrice); } @@ -131,9 +131,8 @@ contract ValidatorTicketPricerTest is UnitTestHelper { validatorTicketPricer.setDailyMevPayoutsChangeToleranceBps(newValue); assertEq(validatorTicketPricer.getDailyMevPayoutsChangeToleranceBps(), newValue); } else { - (bool success,) = address(validatorTicketPricer).call( - abi.encodeWithSignature("setDailyMevPayoutsChangeToleranceBps(uint16)", newValue) - ); + (bool success,) = address(validatorTicketPricer) + .call(abi.encodeWithSignature("setDailyMevPayoutsChangeToleranceBps(uint16)", newValue)); assertTrue(!success); } } @@ -144,9 +143,8 @@ contract ValidatorTicketPricerTest is UnitTestHelper { validatorTicketPricer.setDailyConsensusRewardsChangeToleranceBps(newValue); assertEq(validatorTicketPricer.getDailyConsensusRewardsChangeToleranceBps(), newValue); } else { - (bool success,) = address(validatorTicketPricer).call( - abi.encodeWithSignature("setDailyConsensusRewardsChangeToleranceBps(uint16)", newValue) - ); + (bool success,) = address(validatorTicketPricer) + .call(abi.encodeWithSignature("setDailyConsensusRewardsChangeToleranceBps(uint16)", newValue)); assertTrue(!success); } } @@ -171,9 +169,8 @@ contract ValidatorTicketPricerTest is UnitTestHelper { uint104 oldValue = validatorTicketPricer.getDailyMevPayouts(); uint16 tolerance = validatorTicketPricer.getDailyMevPayoutsChangeToleranceBps(); if ( - tolerance == 0 - || newValue <= oldValue + (oldValue * tolerance / 1e4) - && newValue >= oldValue - (oldValue * tolerance / 1e4) + tolerance == 0 || newValue <= oldValue + (oldValue * tolerance / 1e4) + && newValue >= oldValue - (oldValue * tolerance / 1e4) ) { validatorTicketPricer.setDailyMevPayouts(newValue); assertEq(validatorTicketPricer.getDailyMevPayouts(), newValue); @@ -195,9 +192,8 @@ contract ValidatorTicketPricerTest is UnitTestHelper { uint104 oldValue = validatorTicketPricer.getDailyConsensusRewards(); uint16 tolerance = validatorTicketPricer.getDailyConsensusRewardsChangeToleranceBps(); if ( - tolerance == 0 - || newValue <= oldValue + (oldValue * tolerance / 1e4) - && newValue >= oldValue - (oldValue * tolerance / 1e4) + tolerance == 0 || newValue <= oldValue + (oldValue * tolerance / 1e4) + && newValue >= oldValue - (oldValue * tolerance / 1e4) ) { validatorTicketPricer.setDailyConsensusRewards(newValue); assertEq(validatorTicketPricer.getDailyConsensusRewards(), newValue); @@ -206,9 +202,8 @@ contract ValidatorTicketPricerTest is UnitTestHelper { * (validatorTicketPricer.getDailyMevPayouts() + newValue) / 1e4; assertEq(pufferOracle.getValidatorTicketPrice(), expectedPrice); } else { - (bool success,) = address(validatorTicketPricer).call( - abi.encodeWithSignature("setDailyConsensusRewards(uint104)", newValue) - ); + (bool success,) = address(validatorTicketPricer) + .call(abi.encodeWithSignature("setDailyConsensusRewards(uint104)", newValue)); assertTrue(!success); } } @@ -224,12 +219,11 @@ contract ValidatorTicketPricerTest is UnitTestHelper { uint104 oldConsensusRewards = validatorTicketPricer.getDailyConsensusRewards(); uint16 consensusTolerance = validatorTicketPricer.getDailyConsensusRewardsChangeToleranceBps(); - bool mevValid = mevTolerance == 0 - || mevPayouts <= oldMevPayouts + (oldMevPayouts * mevTolerance / 1e4) - && mevPayouts >= oldMevPayouts - (oldMevPayouts * mevTolerance / 1e4); + bool mevValid = mevTolerance == 0 || mevPayouts <= oldMevPayouts + (oldMevPayouts * mevTolerance / 1e4) + && mevPayouts >= oldMevPayouts - (oldMevPayouts * mevTolerance / 1e4); bool consensusValid = consensusTolerance == 0 || consensusRewards <= oldConsensusRewards + (oldConsensusRewards * consensusTolerance / 1e4) - && consensusRewards >= oldConsensusRewards - (oldConsensusRewards * consensusTolerance / 1e4); + && consensusRewards >= oldConsensusRewards - (oldConsensusRewards * consensusTolerance / 1e4); if (mevValid && consensusValid) { validatorTicketPricer.setDailyRewardsAndPostMintPrice(mevPayouts, consensusRewards); @@ -239,11 +233,12 @@ contract ValidatorTicketPricerTest is UnitTestHelper { (1e4 - validatorTicketPricer.getDiscountRateBps()) * (mevPayouts + consensusRewards) / 1e4; assertEq(pufferOracle.getValidatorTicketPrice(), expectedPrice); } else { - (bool success,) = address(validatorTicketPricer).call( - abi.encodeWithSignature( - "setDailyRewardsAndPostMintPrice(uint104,uint104)", mevPayouts, consensusRewards - ) - ); + (bool success,) = address(validatorTicketPricer) + .call( + abi.encodeWithSignature( + "setDailyRewardsAndPostMintPrice(uint104,uint104)", mevPayouts, consensusRewards + ) + ); assertTrue(!success); } }