diff --git a/README.md b/README.md index 0edc06365..431f58c8c 100644 --- a/README.md +++ b/README.md @@ -183,10 +183,10 @@ You can view the deployed contract addresses below, or check out the code itself | -------- | -------- | -------- | -------- | | [`DelegationManager`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/core/DelegationManager.sol) | [`0xA44151489861Fe9e3055d95adC98FbD462B948e7`](https://holesky.etherscan.io/address/0xA44151489861Fe9e3055d95adC98FbD462B948e7) | [`0x83f8...0D76`](https://holesky.etherscan.io/address/0x83f8F8f0BB125F7870F6bfCf76853f874C330D76) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) | | [`StrategyManager`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/core/StrategyManager.sol) | [`0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6`](https://holesky.etherscan.io/address/0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6) | [`0x59f7...3a18`](https://holesky.etherscan.io/address/0x59f766A603C53f3AC8Be43bBe158c1519b193a18) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) | -| [`EigenPodManager`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/pods/EigenPodManager.sol) | [`0x30770d7E3e71112d7A6b7259542D1f680a70e315`](https://holesky.etherscan.io/address/0x30770d7E3e71112d7A6b7259542D1f680a70e315) | [`0x5265...4a7B`](https://holesky.etherscan.io/address/0x5265C162f7d5F3fE3175a78828ab16bf5E324a7B) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) | +| [`EigenPodManager`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/pods/EigenPodManager.sol) | [`0x30770d7E3e71112d7A6b7259542D1f680a70e315`](https://holesky.etherscan.io/address/0x30770d7E3e71112d7A6b7259542D1f680a70e315) | [`0x91A6...CCc5`](https://holesky.etherscan.io/address/0x91A6525a4a843F5a5B633905300c33F79413CCc5) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) | | [`AVSDirectory`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/core/AVSDirectory.sol) | [`0x055733000064333CaDDbC92763c58BF0192fFeBf`](https://holesky.etherscan.io/address/0x055733000064333CaDDbC92763c58BF0192fFeBf) | [`0xEF5B...3e3a`](https://holesky.etherscan.io/address/0xEF5BA995Bc7722fd1e163edF8Dc09375de3d3e3a) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) | | [`Slasher`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/core/Slasher.sol) | [`0xcAe751b75833ef09627549868A04E32679386e7C`](https://holesky.etherscan.io/address/0xcAe751b75833ef09627549868A04E32679386e7C) | [`0x9971...345A`](https://holesky.etherscan.io/address/0x99715D255E34a39bE9943b82F281CA734bcF345A) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) | -| [`RewardsCoordinator`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/core/RewardsCoordinator.sol) | [`0xAcc1fb458a1317E886dB376Fc8141540537E68fE`](https://holesky.etherscan.io/address/0xAcc1fb458a1317E886dB376Fc8141540537E68fE) | [`0x123C...3D02`](https://holesky.etherscan.io/address/0x123C1A3543DBCA3f704E703dDda7FAAaA8e43D02) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) | +| [`RewardsCoordinator`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/core/RewardsCoordinator.sol) | [`0xAcc1fb458a1317E886dB376Fc8141540537E68fE`](https://holesky.etherscan.io/address/0xAcc1fb458a1317E886dB376Fc8141540537E68fE) | [`0xe546...7f97`](https://holesky.etherscan.io/address/0xe54625095656206AC1B42819875343453c447f97) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) | ###### Strategies @@ -227,9 +227,8 @@ The following strategies differ significantly from the other strategies deployed | Name | Proxy | Implementation | Notes | | -------- | -------- | -------- | -------- | -| [`EigenPod (beacon)`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/pods/EigenPod.sol) | [`0x7261C2bd75a7ACE1762f6d7FAe8F63215581832D`](https://holesky.etherscan.io/address/0x7261C2bd75a7ACE1762f6d7FAe8F63215581832D) | [`0xe98f...641c`](https://holesky.etherscan.io/address/0xe98f9298344527608A1BCC23907B8145F9Cb641c) | - Beacon: [`BeaconProxy`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/beacon/BeaconProxy.sol)
- Pods: [`UpgradeableBeacon`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/beacon/UpgradeableBeacon.sol) | +| [`EigenPod (beacon)`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/pods/EigenPod.sol) | [`0x7261C2bd75a7ACE1762f6d7FAe8F63215581832D`](https://holesky.etherscan.io/address/0x7261C2bd75a7ACE1762f6d7FAe8F63215581832D) | [`0x10ad...319c`](https://holesky.etherscan.io/address/0x10ad7e30e3F52076C8462D573530f4461377319c) | - Beacon: [`BeaconProxy`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/beacon/BeaconProxy.sol)
- Pods: [`UpgradeableBeacon`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/beacon/UpgradeableBeacon.sol) | | [`DelayedWithdrawalRouter`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/pods/DelayedWithdrawalRouter.sol) | [`0x642c646053eaf2254f088e9019ACD73d9AE0FA32`](https://holesky.etherscan.io/address/0x642c646053eaf2254f088e9019ACD73d9AE0FA32) | [`0xcE8b...3407`](https://holesky.etherscan.io/address/0xcE8b8D99773a718423F8040a6e52c06a4ce63407) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) | -| [`EigenLayerBeaconOracle`](https://github.com/succinctlabs/eigenlayer-beacon-oracle/blob/main/contracts/src/EigenLayerBeaconOracle.sol) | - | [`0x4C11...8f25`](https://holesky.etherscan.io/address/0x4C116BB629bff7A8373c2378bBd919f8349B8f25) | Provided by [Succinct](https://succinct.xyz/) | ###### EIGEN/bEIGEN diff --git a/audits/M4 Mainnet (PEPE) - Sigma Prime - Jul 2024.pdf b/audits/M4 Mainnet (PEPE) - Sigma Prime - Jul 2024.pdf new file mode 100644 index 000000000..d073fe6f5 Binary files /dev/null and b/audits/M4 Mainnet (PEPE) - Sigma Prime - Jul 2024.pdf differ diff --git a/certora/harnesses/EigenPodHarness.sol b/certora/harnesses/EigenPodHarness.sol index 0462b9e1a..1845cff7a 100644 --- a/certora/harnesses/EigenPodHarness.sol +++ b/certora/harnesses/EigenPodHarness.sol @@ -7,12 +7,11 @@ contract EigenPodHarness is EigenPod { constructor( IETHPOSDeposit _ethPOS, - IDelayedWithdrawalRouter _delayedWithdrawalRouter, IEigenPodManager _eigenPodManager, uint64 _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, uint64 _GENESIS_TIME ) - EigenPod(_ethPOS, _delayedWithdrawalRouter, _eigenPodManager, _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, _GENESIS_TIME) {} + EigenPod(_ethPOS, _eigenPodManager, _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, _GENESIS_TIME) {} function get_validatorIndex(bytes32 pubkeyHash) public view returns (uint64) { return _validatorPubkeyHashToInfo[pubkeyHash].validatorIndex; diff --git a/certora/scripts/core/verifyStrategyManager.sh b/certora/scripts/core/verifyStrategyManager.sh index 347d8b36c..7f3b1c5d2 100644 --- a/certora/scripts/core/verifyStrategyManager.sh +++ b/certora/scripts/core/verifyStrategyManager.sh @@ -7,7 +7,7 @@ solc-select use 0.8.12 certoraRun certora/harnesses/StrategyManagerHarness.sol \ lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol \ - src/contracts/pods/EigenPodManager.sol src/contracts/pods/EigenPod.sol src/contracts/pods/DelayedWithdrawalRouter.sol \ + src/contracts/pods/EigenPodManager.sol src/contracts/pods/EigenPod.sol \ src/contracts/strategies/StrategyBase.sol src/contracts/core/DelegationManager.sol \ src/contracts/core/Slasher.sol src/contracts/permissions/PauserRegistry.sol \ --verify StrategyManagerHarness:certora/specs/core/StrategyManager.spec \ diff --git a/certora/scripts/pods/verifyEigenPod.sh b/certora/scripts/pods/verifyEigenPod.sh index 457d09d3e..d4bc140a8 100644 --- a/certora/scripts/pods/verifyEigenPod.sh +++ b/certora/scripts/pods/verifyEigenPod.sh @@ -3,23 +3,21 @@ then RULE="--rule $2" fi -solc-select use 0.8.12 +# solc-select use 0.8.12 -certoraRun certora/harnesses/EigenPodHarness.sol \ - src/contracts/core/DelegationManager.sol src/contracts/pods/EigenPodManager.sol \ - src/contracts/core/Slasher.sol src/contracts/permissions/PauserRegistry.sol \ - src/contracts/core/StrategyManager.sol \ - src/contracts/strategies/StrategyBase.sol \ - lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol \ - lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol \ - --verify EigenPodHarness:certora/specs/pods/EigenPod.spec \ - --solc_via_ir \ - --solc_optimize 1 \ - --optimistic_loop \ - --prover_args '-recursionEntryLimit 3' \ - --optimistic_hashing \ - --parametric_contracts EigenPodHarness \ - $RULE \ - --loop_iter 1 \ - --packages @openzeppelin=lib/openzeppelin-contracts @openzeppelin-upgrades=lib/openzeppelin-contracts-upgradeable \ - --msg "EigenPod $1 $2" \ +# certoraRun certora/harnesses/EigenPodHarness.sol \ +# src/contracts/core/DelegationManager.sol src/contracts/pods/EigenPodManager.sol \ +# src/contracts/core/Slasher.sol src/contracts/permissions/PauserRegistry.sol \ +# src/contracts/core/StrategyManager.sol \ +# src/contracts/strategies/StrategyBase.sol \ +# lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol \ +# lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol \ +# --verify EigenPodHarness:certora/specs/pods/EigenPod.spec \ +# --optimistic_loop \ +# --prover_args '-recursionEntryLimit 3' \ +# --optimistic_hashing \ +# --parametric_contracts EigenPodHarness \ +# $RULE \ +# --loop_iter 1 \ +# --packages @openzeppelin=lib/openzeppelin-contracts @openzeppelin-upgrades=lib/openzeppelin-contracts-upgradeable \ +# --msg "EigenPod $1 $2" \ diff --git a/certora/scripts/pods/verifyEigenPodManager.sh b/certora/scripts/pods/verifyEigenPodManager.sh index d059305e1..428f89ba3 100644 --- a/certora/scripts/pods/verifyEigenPodManager.sh +++ b/certora/scripts/pods/verifyEigenPodManager.sh @@ -3,19 +3,17 @@ then RULE="--rule $2" fi -solc-select use 0.8.12 +# solc-select use 0.8.12 -certoraRun certora/harnesses/EigenPodManagerHarness.sol \ - src/contracts/core/DelegationManager.sol src/contracts/pods/EigenPod.sol src/contracts/strategies/StrategyBase.sol src/contracts/core/StrategyManager.sol \ - src/contracts/core/Slasher.sol src/contracts/permissions/PauserRegistry.sol \ - --verify EigenPodManagerHarness:certora/specs/pods/EigenPodManager.spec \ - --solc_via_ir \ - --solc_optimize 1 \ - --optimistic_loop \ - --optimistic_fallback \ - --optimistic_hashing \ - --parametric_contracts EigenPodManagerHarness \ - $RULE \ - --loop_iter 3 \ - --packages @openzeppelin=lib/openzeppelin-contracts @openzeppelin-upgrades=lib/openzeppelin-contracts-upgradeable \ - --msg "EigenPodManager $1 $2" \ +# certoraRun certora/harnesses/EigenPodManagerHarness.sol \ +# src/contracts/core/DelegationManager.sol src/contracts/pods/EigenPod.sol src/contracts/strategies/StrategyBase.sol src/contracts/core/StrategyManager.sol \ +# src/contracts/core/Slasher.sol src/contracts/permissions/PauserRegistry.sol \ +# --verify EigenPodManagerHarness:certora/specs/pods/EigenPodManager.spec \ +# --optimistic_loop \ +# --optimistic_fallback \ +# --optimistic_hashing \ +# --parametric_contracts EigenPodManagerHarness \ +# $RULE \ +# --loop_iter 3 \ +# --packages @openzeppelin=lib/openzeppelin-contracts @openzeppelin-upgrades=lib/openzeppelin-contracts-upgradeable \ +# --msg "EigenPodManager $1 $2" \ diff --git a/certora/specs/core/Slasher.spec b/certora/specs/core/Slasher.spec index 1ecdbd2de..c5d2013c9 100644 --- a/certora/specs/core/Slasher.spec +++ b/certora/specs/core/Slasher.spec @@ -27,9 +27,6 @@ methods { // external calls to EigenPod function _.withdrawRestakedBeaconChainETH(address,uint256) external => DISPATCHER(true); - // external calls to DelayedWithdrawalRouter (from EigenPod) - function _.createDelayedWithdrawal(address, address) external => DISPATCHER(true); - // external calls to PauserRegistry function _.isPauser(address) external => DISPATCHER(true); function _.unpauser() external => DISPATCHER(true); diff --git a/certora/specs/core/StrategyManager.spec b/certora/specs/core/StrategyManager.spec index 43cd8e20f..58b157aea 100644 --- a/certora/specs/core/StrategyManager.spec +++ b/certora/specs/core/StrategyManager.spec @@ -31,9 +31,6 @@ methods { // external calls to EigenPod function _.withdrawRestakedBeaconChainETH(address,uint256) external => DISPATCHER(true); - - // external calls to DelayedWithdrawalRouter (from EigenPod) - function _.createDelayedWithdrawal(address, address) external => DISPATCHER(true); // external calls to PauserRegistry function _.isPauser(address) external => DISPATCHER(true); diff --git a/certora/specs/pods/EigenPod.spec b/certora/specs/pods/EigenPod.spec index 9b62f2278..9f22ecb84 100644 --- a/certora/specs/pods/EigenPod.spec +++ b/certora/specs/pods/EigenPod.spec @@ -71,7 +71,6 @@ methods { function validatorPubkeyHashToInfo(bytes32 validatorPubkeyHash) external returns (IEigenPod.ValidatorInfo) envfree; function provenWithdrawal(bytes32 validatorPubkeyHash, uint64 slot) external returns (bool) envfree; function validatorStatus(bytes32 pubkeyHash) external returns (IEigenPod.VALIDATOR_STATUS) envfree; - function delayedWithdrawalRouter() external returns (address) envfree; function nonBeaconChainETHBalanceWei() external returns (uint256) envfree; // harnessed functions diff --git a/certora/specs/pods/EigenPodManager.spec b/certora/specs/pods/EigenPodManager.spec index a0dc5115b..11a4be72b 100644 --- a/certora/specs/pods/EigenPodManager.spec +++ b/certora/specs/pods/EigenPodManager.spec @@ -26,7 +26,6 @@ methods { // external calls to EigenPod function _.withdrawRestakedBeaconChainETH(address,uint256) external => DISPATCHER(true); - // external calls to PauserRegistry function _.isPauser(address) external => DISPATCHER(true); function _.unpauser() external => DISPATCHER(true); @@ -36,7 +35,6 @@ methods { function getPod(address podOwner) external returns (address) envfree; function ethPOS() external returns (address) envfree; function eigenPodBeacon() external returns (address) envfree; - function beaconChainOracle() external returns (address) envfree; function getBlockRootAtTimestamp(uint64 timestamp) external returns (bytes32) envfree; function strategyManager() external returns (address) envfree; function slasher() external returns (address) envfree; diff --git a/docs/README.md b/docs/README.md index 31cd86580..4e6597b73 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ [middleware-repo]: https://github.com/Layr-Labs/eigenlayer-middleware/ -## EigenLayer M2 Docs +## EigenLayer Docs - v0.4.0 Release This repo contains the EigenLayer core contracts, which enable restaking of liquid staking tokens (LSTs) and beacon chain ETH to secure new services, called AVSs (actively validated services). For more info on AVSs, check out the EigenLayer middleware contracts [here][middleware-repo]. @@ -33,16 +33,14 @@ This document provides an overview of system components, contracts, and user rol | -------- | -------- | -------- | | [`EigenPodManager.sol`](../src/contracts/pods/EigenPodManager.sol) | Singleton | Transparent proxy | | [`EigenPod.sol`](../src/contracts/pods/EigenPod.sol) | Instanced, deployed per-user | Beacon proxy | -| [`DelayedWithdrawalRouter.sol`](../src/contracts/pods/DelayedWithdrawalRouter.sol) | Singleton | Transparent proxy | -| [`succinctlabs/EigenLayerBeaconOracle.sol`](https://github.com/succinctlabs/telepathy-contracts/blob/main/external/integrations/eigenlayer/EigenLayerBeaconOracle.sol) | Singleton | UUPS proxy | [`0x40B1...9f2c`](https://goerli.etherscan.io/address/0x40B10ddD29a2cfF33DBC420AE5bbDa0649049f2c) | These contracts work together to enable native ETH restaking: -* Users deploy `EigenPods` via the `EigenPodManager`, which contain beacon chain state proof logic used to verify a validator's withdrawal credentials, balance, and exit. An `EigenPod's` main role is to serve as the withdrawal address for one or more of a user's validators. +* Users deploy `EigenPods` via the `EigenPodManager`, which contain beacon chain state proof logic used to verify a validator's withdrawal credentials and current balances. An `EigenPod's` main role is to serve as the fee recipient and/or withdrawal credentials for one or more of a user's validators. * The `EigenPodManager` handles `EigenPod` creation and accounting+interactions between users with restaked native ETH and the `DelegationManager`. -* The `DelayedWithdrawalRouter` imposes a 7-day delay on completing partial beacon chain withdrawals from an `EigenPod`. This is primarily to add a stopgap against a hack being able to instantly withdraw funds (note that all withdrawals from EigenLayer -- other than partial withdrawals earned by validators -- are initiated via the `DelegationManager`). -* The `EigenLayerBeaconOracle` provides beacon chain block roots for use in various proofs. The oracle is supplied by Succinct's Telepathy protocol ([docs link](https://docs.telepathy.xyz/)). -See full documentation in [`/core/EigenPodManager.md`](./core/EigenPodManager.md). +See full documentation in: +* [`/core/EigenPodManager.md`](./core/EigenPodManager.md) +* [`/core/EigenPod.md`](./core/EigenPod.md) #### StrategyManager @@ -123,8 +121,7 @@ Stakers can restake any combination of these: a Staker may hold ALL of these ass * Stakers **withdraw** assets via the DelegationManager, *no matter what assets they're withdrawing* * Stakers **delegate** to an Operator via the DelegationManager -Unimplemented as of M2: -* Stakers earn yield by delegating to an Operator as the Operator provides services to an AVS +*Unimplemented as of v0.4.0:* * Stakers are at risk of being slashed if the Operator misbehaves ##### Operator @@ -136,8 +133,7 @@ An Operator is a user who helps run the software built on top of EigenLayer (AVS * Operators can **deposit** and **withdraw** assets just like Stakers can * Operators can opt in to providing services for an AVS using that AVS's middleware contracts. See the [EigenLayer middleware][middleware-repo] repo for more details. -*Unimplemented as of M2:* -* Operators earn fees as part of the services they provide +*Unimplemented as of v0.4.0:* * Operators may be slashed by the services they register with (if they misbehave) --- @@ -170,18 +166,18 @@ This flow is mostly useful if a Staker wants to change which Operator they are d Completing a queued withdrawal as tokens is roughly the same for both native ETH and LSTs. -However, note that *before* a withdrawal can be completed, native ETH stakers will need to perform additional steps, detailed in the "Withdrawal Processing" diagrams below. +However, note that *before* a withdrawal can be completed, native ETH stakers will need to perform additional steps, detailed in the diagrams below. ![.](./images/Staker%20Flow%20Diagrams/Complete%20Withdrawal%20as%20Tokens.png) -##### Withdrawal Processing: Validator Exits +##### `EigenPods`: Processing Validator Exits If a Staker wants to fully withdraw from the beacon chain, they need to perform these additional steps before their withdrawal is completable: ![.](./images/Staker%20Flow%20Diagrams/Validator%20Exits.png) -##### Withdrawal Processing: Partial Beacon Chain Withdrawals +##### `EigenPods`: Processing Validator Yield -If a Staker wants to withdraw consensus rewards from the beacon chain, they do NOT go through the `DelegationManager`. This is the only withdrawal type that is not initiated in the `DelegationManager`: +As the Staker's `EigenPod` accumulates consensus layer or execution layer yield, the `EigenPod's` balance will increase. The Staker can Checkpoint their validator to claim this yield as shares, which can either remain staked in EigenLayer or be withdrawn via the `DelegationManager` withdrawal queue: -![.](./images/Staker%20Flow%20Diagrams/Partial%20Withdrawals.png) \ No newline at end of file +![.](./images/Staker%20Flow%20Diagrams/Validator%20Yield.png) \ No newline at end of file diff --git a/docs/core/EigenPod.md b/docs/core/EigenPod.md new file mode 100644 index 000000000..b33e5d5da --- /dev/null +++ b/docs/core/EigenPod.md @@ -0,0 +1,411 @@ +[eip-4788]: https://eips.ethereum.org/EIPS/eip-4788 +[custom-types]: https://eth2book.info/capella/part3/config/types/#custom-types +[validator-container]: https://eth2book.info/capella/part3/containers/dependencies/#validator + +## EigenPod + +| File | Type | Proxy | +| -------- | -------- | -------- | +| [`EigenPod.sol`](../../src/contracts/pods/EigenPod.sol) | Instanced, deployed per-user | Beacon proxy | + +An `EigenPod` is deployed via the `EigenPodManager` by a Staker (referred to in this doc as the _Pod Owner_). `EigenPods` allow a Pod Owner to restake one or more beacon chain validators, earning shares which can be delegated to Operators to earn yield. When a Pod Owner begins running a validator on the beacon chain, they choose _withdrawal credentials_ for that validator. Withdrawal credentials are the ETH address to which: +* A validator's _principal_ is sent when the validator exits the beacon chain +* A validator's _consensus rewards_ are sent as the validator proposes/attests to blocks on the beacon chain + +Additionally, when running validator node software, a validator is configured with a _fee recipient_. The fee recipient receives: +* _Execution layer rewards_ when the validator proposes a block +* _MEV rewards_ if the validator is running MEV-boost/other custom block proposer software + +**An `EigenPod` may serve as EITHER/BOTH the withdrawal credentials OR the fee recipient for your validators.** In prior releases, it was only possible to use an `EigenPod` for withdrawal credentials. However, this is no longer the case! + +--- + +The **primary goal** of the `EigenPod` system is to **ensure that shares are backed 1:1** with ETH that is _either already in the `EigenPod`, or will eventually flow through the `EigenPod`._ To support this goal, `EigenPods`: +* serve as the withdrawal credentials for one or more beacon chain validators controlled by the Pod Owner +* validate beacon chain state proofs +* interpret these proofs to add or remove shares in the beacon chain ETH strategy + +Because beacon chain proofs are processed asynchronously from the beacon chain itself, there is an inherent _lag_ between an event on the beacon chain and a corresponding share update in any affected `EigenPods`. Therefore, the **secondary goals** of the `EigenPod` system are to **minimize lag where possible** and to **ensure various timing windows cannot (i) create unbacked shares or (ii) prevent the withdrawal of existing shares.** + +#### High-level Concepts + +* [Restaking Beacon Chain ETH](#restaking-beacon-chain-eth) +* [Checkpointing Validators](#checkpointing-validators) +* [Staleness Proofs](#staleness-proofs) +* [Other Methods](#other-methods) + +#### Important Definitions + +**_Pod Owner_**: A Staker who has deployed an `EigenPod` is a _Pod Owner_. The terms are used interchangeably in this document. +* _Pod Owners_ can only deploy a single `EigenPod`, but can restake any number of beacon chain validators from the same `EigenPod`. +* _Pod Owners_ can delegate their `EigenPodManager` shares to Operators (via `DelegationManager`). +* These shares correspond to the amount of restaked beacon chain ETH held by the _Pod Owner_ via their `EigenPod`. + +**_Proof Submitter_**: An address designated by the Pod Owner with permissions to call certain `EigenPod` methods. This role is provided to allow Pod Owners to manage their day-to-day `EigenPod` tasks via hot wallets, rather than the Pod Owner address which controls all funds. The Proof Submitter can call `verifyWithdrawalCredentials` and `startCheckpoint`. See [`setProofSubmitter` docs](#setproofsubmitter) for more details. + +**_Active validator set_**: This term is used frequently in this document to describe the set of validators whose withdrawal credentials have been verified to be pointed at an `EigenPod`. The _active validator set_ is used to determine the number of proofs required to complete a checkpoint (see [Checkpointing Validators](#checkpointing-validators)). +* A validator enters the _active validator set_ when their withdrawal credentials are verified (see [`verifyWithdrawalCredentials`](#verifywithdrawalcredentials)) +* A validator leaves the _active validator set_ when a checkpoint proof shows they have 0 balance (see [`verifyCheckpointProofs`](#verifycheckpointproofs)) + +In the implementation, the _active validator set_ is comprised of two state variables: +* `uint256 activeValidatorCount` + * incremented by 1 when a validator enters the _active validator set_ + * decremented by 1 when a validator leaves the _active validator set_ +* `mapping(bytes32 => ValidatorInfo) _validatorPubkeyHashToInfo` (specifically, the `status` field) + * `VALIDATOR_STATUS.INACTIVE -> VALIDATOR_STATUS.ACTIVE` when entering the _active validator set_ + * `VALIDATOR_STATUS.ACTIVE -> VALIDATOR_STATUS.WITHDRAWN` when leaving the _active validator set_ + +**_Checkpoint_**: A snapshot of `EigenPod` and beacon chain state used to update the _Pod Owner's_ shares based on a combination of beacon chain balance and native ETH balance. Checkpoints allow an `EigenPod` to account for validator exits, partial withdrawals of consensus rewards, or execution layer fees earned by their validators. Completing a checkpoint will account for these amounts in the `EigenPod`, enabling the _Pod Owner_ to compound their restaked shares or withdraw accumulated yield. + +Only one _checkpoint_ can be active at a time in a given `EigenPod`. The pod's _current checkpoint_ is represented by the following data structure: + +```solidity +struct Checkpoint { + bytes32 beaconBlockRoot; // proofs are verified against a beacon block root + uint24 proofsRemaining; // number of proofs remaining before the checkpoint is completed + uint64 podBalanceGwei; // native ETH that will be awarded shares when the checkpoint is completed + int128 balanceDeltasGwei; // total change in beacon chain balance tracked across submitted proofs +} +``` + +Checkpoints are completed by submitting one beacon chain proof per validator in the pod's _active validator set_. See [Checkpointing Validators](#checkpointing-validators) for details. + +--- + +### Restaking Beacon Chain ETH + +If a Pod Owner has validators whose withdrawal credentials are an `EigenPod`, the Pod Owner can use `verifyWithdrawalCredentials` to begin restaking ETH while it is still on the beacon chain. Once a validator's withdrawal credentials are verified: +* the Pod Owner receives delegatable shares via `EigenPodManager.podOwnerShares` +* the validator enters the pod's _active validator set_, and must be included in future checkpoint proofs (see [Checkpointing Validators](#checkpointing-validators)) + +_Methods:_ +* [`verifyWithdrawalCredentials`](#verifywithdrawalcredentials) + +#### `verifyWithdrawalCredentials` + +```solidity +function verifyWithdrawalCredentials( + uint64 beaconTimestamp, + BeaconChainProofs.StateRootProof calldata stateRootProof, + uint40[] calldata validatorIndices, + bytes[] calldata validatorFieldsProofs, + bytes32[][] calldata validatorFields +) + external + onlyOwnerOrProofSubmitter + onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_CREDENTIALS) + +struct StateRootProof { + bytes32 beaconStateRoot; + bytes proof; +} +``` + +This method first verifies a beacon state root against a beacon block root returned by the [EIP-4788 oracle][eip-4788]. Then, it verifies one or more withdrawal credential proofs against the beacon state root. Finally, the Pod Owner is awarded shares according to the sum of the effective balance of each verified validator (via `EigenPodManager.recordBeaconChainETHBalanceUpdate`). + +A withdrawal credential proof uses a validator's [`ValidatorIndex`][custom-types] and a merkle proof to prove the existence of a [`Validator` container][validator-container] at a given block. The beacon chain `Validator` container holds important information used in this method: +* `pubkey`: A BLS pubkey hash, used to uniquely identify the validator within the `EigenPod` +* `withdrawal_credentials`: Used to verify that the validator will withdraw its principal to this `EigenPod` if it exits the beacon chain +* `effective_balance`: The balance of the validator, updated once per epoch and capped at 32 ETH. Used to award shares to the Pod Owner +* `activation_epoch`: Initially set to `type(uint64).max`, this value is updated when a validator reaches a balance of at least 32 ETH, designating the validator is ready to become active on the beacon chain. **This method requires that a validator is either already active, or in the process of activating on the beacon chain.** +* `exit_epoch`: Initially set to `type(uint64).max`, this value is updated when a validator initiates exit from the beacon chain. **This method requires that a validator has not initiated an exit from the beacon chain.** + * If a validator has been exited prior to calling `verifyWithdrawalCredentials`, their ETH can be accounted for, awarded shares, and/or withdrawn via the checkpoint system (see [Checkpointing Validators](#checkpointing-validators)). + +_Note that it is not required to verify your validator's withdrawal credentials_, unless you want to receive shares for ETH on the beacon chain. You may choose to use your `EigenPod` without verifying withdrawal credentials; you will still be able to withdraw yield (or receive shares for yield) via the [checkpoint system](#checkpointing-validators). + +*Effects*: +* For each set of unique verified withdrawal credentials: + * `activeValidatorCount` is increased by 1 + * The validator's info is recorded in state (`_validatorPubkeyHashToInfo[pubkeyHash]`): + * `validatorIndex` is recorded from the passed-in `validatorIndices` + * `restakedBalanceGwei` is set to the validator's effective balance + * `lastCheckpointedAt` is set to either the `lastCheckpointTimestamp` or `currentCheckpointTimestamp` + * `VALIDATOR_STATUS` moves from `INACTIVE` to `ACTIVE` +* The Pod Owner is awarded shares according to the sum of effective balances proven. See [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](./EigenPodManager.md#recordbeaconchainethbalanceupdate) + +*Requirements*: +* Caller MUST be EITHER the Pod Owner or Proof Submitter +* Pause status MUST NOT be set: `PAUSED_EIGENPODS_VERIFY_CREDENTIALS` +* Input array lengths MUST be equal +* `beaconTimestamp`: + * MUST be greater than `currentCheckpointTimestamp` + * MUST be queryable via the [EIP-4788 oracle][eip-4788]. Generally, this means `beaconTimestamp` corresponds to a valid beacon block created within the last 8192 blocks (~27 hours). +* `stateRootProof` MUST verify a `beaconStateRoot` against the `beaconBlockRoot` returned from the EIP-4788 oracle +* For each validator: + * The validator MUST NOT have been previously-verified (`VALIDATOR_STATUS` should be `INACTIVE`) + * The validator's `activation_epoch` MUST NOT equal `type(uint64).max` (aka `FAR_FUTURE_EPOCH`) + * The validator's `exit_epoch` MUST equal `type(uint64).max` (aka `FAR_FUTURE_EPOCH`) + * The validator's `withdrawal_credentials` MUST be pointed to the `EigenPod` + * `validatorFieldsProof` MUST be a valid merkle proof of the corresponding `validatorFields` under the `beaconStateRoot` at the given `validatorIndex` +* See [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](./EigenPodManager.md#recordbeaconchainethbalanceupdate) + +--- + +### Checkpointing Validators + +Checkpoint proofs comprise the bulk of proofs submitted to an `EigenPod`. Completing a checkpoint means submitting _one checkpoint proof for each validator_ in the pod's _active validator set._ + +`EigenPods` use checkpoints to detect: +* when validators have exited from the beacon chain, leaving the pod's _active validator set_ +* when the pod has accumulated fees / partial withdrawals from validators +* whether any validators on the beacon chain have increased/decreased in balance + +When a checkpoint is completed, shares are updated accordingly for each of these events. Shares can be withdrawn via the `DelegationManager` withdrawal queue (see [DelegationManager: Undelegating and Withdrawing](./DelegationManager.md#undelegating-and-withdrawing)), which means an `EigenPod's` checkpoint proofs also play an important role in allowing Pod Owners to exit funds from the system. + +_Important Notes:_ +* `EigenPods` can only have **one active checkpoint** at a given time, and once started, checkpoints **cannot be cancelled** (only completed) +* Checkpoint proofs are based entirely off of _current balance_ proofs. Even though partial/full withdrawals are processed via checkpoint proofs, this system does NOT use withdrawal proofs. + +_Methods:_ +* [`startCheckpoint`](#startcheckpoint) +* [`verifyCheckpointProofs`](#verifycheckpointproofs) + +#### `startCheckpoint` + +```solidity +function startCheckpoint(bool revertIfNoBalance) + external + onlyOwnerOrProofSubmitter() + onlyWhenNotPaused(PAUSED_START_CHECKPOINT) +``` + +This method allows a Pod Owner (or Proof Submitter) to start a checkpoint, beginning the process of proving a pod's _active validator set_. `startCheckpoint` takes a snapshot of three things: +* `podBalanceGwei`: the `EigenPod's` native ETH balance, minus any balance already credited with shares through previous checkpoints + * Note: if `revertIfNoBalance == true`, this method will revert if `podBalanceGwei == 0`. This is to allow a Pod Owner to avoid creating a checkpoint unintentionally. +* `activeValidatorCount`: the number of validators in the pod's _active validator set_, aka the number of validators with verified withdrawal credentials who have NOT been proven exited via a previous checkpoint + * This becomes the checkpoint's `proofsRemaining`, or the number of proofs that need to be submitted to `verifyCheckpointProofs` to complete the checkpoint +* `beaconBlockRoot`: the beacon block root of the previous slot, fetched by querying the [EIP-4788 oracle][eip-4788] with the current `block.timestamp` + * This is used as the single source of truth for all proofs submitted for this checkpoint + +`startCheckpoint` plays a very important role in the security of the checkpoint process: it guarantees that _the pod's native ETH balance and any beacon balances proven in the checkpoint are 100% distinct_. That is: if a partial/full exit is processed in the block before `startCheckpoint` is called, then: +* The withdrawn ETH is already in the pod when `startCheckpoint` is called, and is factored into `podBalanceGwei` +* A proof of the validator's current balance against `beaconBlockRoot` will NOT include the withdrawn ETH + +This guarantee means that, if we use the checkpoint to sum up the beacon chain balance of the pod's _active validator set_, **we can award guaranteed-backed shares** according to the sum of the pod's beacon chain balance and its native ETH balance. + +*Effects*: +* Sets `currentCheckpointTimestamp` to `block.timestamp` +* Creates a new `Checkpoint`: + * `beaconBlockRoot`: set to the current block's parent beacon block root, fetched by querying the [EIP-4788 oracle][eip-4788] using `block.timestamp` as input. + * `proofsRemaining`: set to the current value of `activeValidatorCount` (note that this value MAY be 0) + * `podBalanceGwei`: set to the pod's native ETH balance, minus any balance already accounted for in previous checkpoints + * `balanceDeltasGwei`: set to 0 initially +* If `checkpoint.proofsRemaining == 0`, the new checkpoint is auto-completed: + * `withdrawableRestakedExecutionLayerGwei` is increased by `checkpoint.podBalanceGwei` + * `lastCheckpointTimestamp` is set to `currentCheckpointTimestamp` + * `currentCheckpointTimestamp` and `_currentCheckpoint` are deleted + * The Pod Owner's shares are updated (see [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](./EigenPodManager.md#recordbeaconchainethbalanceupdate)) + +*Requirements*: +* Caller MUST be EITHER the Pod Owner or Proof Submitter +* Pause status MUST NOT be set: `PAUSED_START_CHECKPOINT` +* A checkpoint MUST NOT be active (`currentCheckpointTimestamp == 0`) +* The last checkpoint completed MUST NOT have been started in the current block (`lastCheckpointTimestamp != block.timestamp`) +* If `revertIfNoBalance == true`, the pod's native ETH balance MUST contain some nonzero value not already accounted for in the _Pod Owner's_ shares + +#### `verifyCheckpointProofs` + +```solidity +function verifyCheckpointProofs( + BeaconChainProofs.BalanceContainerProof calldata balanceContainerProof, + BeaconChainProofs.BalanceProof[] calldata proofs +) + external + onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_CHECKPOINT_PROOFS) + +struct BalanceContainerProof { + bytes32 balanceContainerRoot; + bytes proof; +} + +struct BalanceProof { + bytes32 pubkeyHash; + bytes32 balanceRoot; + bytes proof; +} +``` + +`verifyCheckpointProofs` is used to make progress on (or complete) the pod's current checkpoint. This method accepts one or more merkle proofs of validators' _current balances_ against a `balanceContainerRoot`. Additionally, a `balanceContainerProof` verifies this `balanceContainerRoot` against the _current checkpoint's_ `beaconBlockRoot`. + +Proofs submitted to this method concern a validator's _current balance,_ NOT their _effective balance_. The _current balance_ is updated every slot, while _effective balances_ are updated roughly once per epoch. Current balances are stored in the [`BeaconState.balances` field](https://eth2book.info/capella/part3/containers/state/#beaconstate). + +For each validator submitted via `proofs`: +* The validator's `status` should be `ACTIVE`. That is, its withdrawal credentials are verified (see [`verifyWithdrawalCredentials`](#verifywithdrawalcredentials)), and it has a nonzero balance as of the last time it was seen in a checkpoint proof. +* The validator's `lastCheckpointedAt` should be less than `currentCheckpointTimestamp`. This is to prevent a validator from counting towards a checkpoint's progression more than once. + +If either of these two conditions is not met, _the proof will be skipped but execution will continue_. Execution continues without reverting to prevent a potential griefing vector where anyone could frontrun a batch of proofs, submit one proof from the batch, and cause the batch to revert. + +Each valid proof submitted decreases the _current checkpoint's_ `proofsRemaining` by 1. If `proofsRemaining` hits 0 the checkpoint is automatically completed, updating the Pod Owner's shares accordingly. + +*Effects*: +* For each validator successfully checkpointed: + * The number of proofs remaining in the checkpoint is decreased (`checkpoint.proofsRemaining--`) + * A balance delta is calculated using the validator's previous `restakedBalanceGwei`. This delta is added to `checkpoint.balanceDeltasGwei` to track the total beacon chain balance delta. + * The validator's `restakedBalanceGwei` and `lastCheckpointedAt` fields are updated. Additionally, if the proof shows that the validator has a balance of 0, the validator's status is moved to `VALIDATOR_STATUS.WITHDRAWN` and the pod's `activeValidatorCount` is decreased. +* If the checkpoint's `proofsRemaining` drops to 0, the checkpoint is automatically completed: + * `checkpoint.podBalanceGwei` is added to `withdrawableRestakedExecutionLayerGwei`, rendering it accounted for in future checkpoints + * `lastCheckpointTimestamp` is set to `currentCheckpointTimestamp`, and both `_currentCheckpoint` and `currentCheckpointTimestamp` are deleted. + * The Pod Owner's total share delta is calculated as the sum of `checkpoint.podBalanceGwei` and `checkpoint.balanceDeltasGwei`, and forwarded to the `EigenPodManager` (see [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](./EigenPodManager.md#recordbeaconchainethbalanceupdate)) + +*Requirements*: +* Pause status MUST NOT be set: `PAUSED_EIGENPODS_VERIFY_CHECKPOINT_PROOFS` +* A checkpoint MUST currently be active (`currentCheckpointTimestamp != 0`) +* `balanceContainerProof` MUST contain a valid merkle proof of the beacon chain's balances container against `_currentCheckpoint.beaconBlockRoot` +* Each `proof` in `proofs` MUST contain a valid merkle proof of the validator's `balanceRoot` against `balanceContainerProof.balanceContainerRoot` + +--- + +### Staleness Proofs + +Regular checkpointing of validators plays an important role in the health of the system, as a completed checkpoint ensures that the pod's shares and backing assets are up to date. + +Typically, checkpoints can only be started by the Pod Owner (see [`startCheckpoint`](#startcheckpoint)). This is because completing a checkpoint with a lot of validators has the potential to be an expensive operation, so gating `startCheckpoint` to only be callable by the Pod Owner prevents a griefing vector where anyone can cheaply force the Pod Owner to perform a checkpoint. + +In most cases, Pod Owners are incentivized to perform their own regular checkpoints, as completing checkpoints is the only way to access yield sent to the pod. However, if beacon chain validators are slashed, it's possible that a Pod Owner no longer has an incentive to start/complete a checkpoint. After all, they would be losing shares equal to the slashed amount. Unless they have enough unclaimed yield in the pod to make up for this, they only stand to lose by completing a checkpoint. + +In this case, `verifyStaleBalance` can be used to allow a third party to start a checkpoint on the Pod Owner's behalf. + +*Methods*: +* [`verifyStaleBalance`](#verifystalebalance) + +#### `verifyStaleBalance` + +```solidity +function verifyStaleBalance( + uint64 beaconTimestamp, + BeaconChainProofs.StateRootProof calldata stateRootProof, + BeaconChainProofs.ValidatorProof calldata proof +) + external + onlyWhenNotPaused(PAUSED_START_CHECKPOINT) + onlyWhenNotPaused(PAUSED_VERIFY_STALE_BALANCE) +``` + +Allows anyone to prove that a validator in the pod's _active validator set_ was slashed on the beacon chain. A successful proof allows the caller to start a checkpoint. Note that if the pod currently has an active checkpoint, the existing checkpoint needs to be completed before `verifyStaleBalance` can start a checkpoint. + +A valid proof has the following requirements: +* The `beaconTimestamp` MUST be newer than the timestamp the validator was last checkpointed at +* The validator in question MUST be in the _active validator set_ (have the status `VALIDATOR_STATUS.ACTIVE`) +* The proof MUST show that the validator has been slashed + +If these requirements are met and the proofs are valid against a beacon block root given by `beaconTimestamp`, a checkpoint is started. + +*Effects*: +* Sets `currentCheckpointTimestamp` to `block.timestamp` +* Creates a new `Checkpoint`: + * `beaconBlockRoot`: set to the current block's parent beacon block root, fetched by querying the [EIP-4788 oracle][eip-4788] using `block.timestamp` as input. + * `proofsRemaining`: set to the current value of `activeValidatorCount` + * `podBalanceGwei`: set to the pod's native ETH balance, minus any balance already accounted for in previous checkpoints + * `balanceDeltasGwei`: set to 0 initially + +*Requirements*: +* Pause status MUST NOT be set: `PAUSED_START_CHECKPOINT` +* Pause status MUST NOT be set: `PAUSED_VERIFY_STALE_BALANCE` +* A checkpoint MUST NOT be active (`currentCheckpointTimestamp == 0`) +* The last checkpoint completed MUST NOT be the current block +* For the validator given by `proof.validatorFields`: + * `beaconTimestamp` MUST be greater than `validatorInfo.lastCheckpointedAt` + * `validatorInfo.status` MUST be `VALIDATOR_STATUS.ACTIVE` + * `proof.validatorFields` MUST show that the validator is slashed +* `stateRootProof` MUST verify a `beaconStateRoot` against the `beaconBlockRoot` returned from the EIP-4788 oracle +* The `ValidatorProof` MUST contain a valid merkle proof of the corresponding `validatorFields` under the `beaconStateRoot` at `validatorInfo.validatorIndex` + +--- + +### Other Methods + +Minor methods that do not fit well into other sections: +* [`setProofSubmitter`](#setproofsubmitter) +* [`stake`](#stake) +* [`withdrawRestakedBeaconChainETH`](#withdrawrestakedbeaconchaineth) +* [`recoverTokens`](#recovertokens) + +#### `setProofSubmitter` + +```solidity +function setProofSubmitter(address newProofSubmitter) external onlyEigenPodOwner +``` + +Allows the Pod Owner to update the Proof Submitter address for the `EigenPod`. The Proof Submitter can call `verifyWithdrawalCredentials` and `startCheckpoint` just like the Pod Owner. This is intended to allow the Pod Owner to create a hot wallet to manage calls to these methods. + +If set, EITHER the Pod Owner OR Proof Submitter may call `verifyWithdrawalCredentials`/`startCheckpoint`. + +The Pod Owner can call this with `newProofSubmitter == 0` to remove the current Proof Submitter. If there is no designated Proof Submitter, ONLY the Pod Owner can call `verifyWithdrawalCredentials`/`startCheckpoint`. + +*Effects*: +* Updates `proofSubmitter` to `newProofSubmitter` + +*Requirements*: +* Caller MUST be the Pod Owner + +#### `stake` + +```solidity +function stake( + bytes calldata pubkey, + bytes calldata signature, + bytes32 depositDataRoot +) + external + payable + onlyEigenPodManager +``` + +Handles the call to the beacon chain deposit contract. Only called via `EigenPodManager.stake`. + +*Effects*: +* Deposits 32 ETH into the beacon chain deposit contract, and provides the pod's address as the deposit's withdrawal credentials + +*Requirements*: +* Caller MUST be the `EigenPodManager` +* Call value MUST be 32 ETH +* Deposit contract `deposit` method MUST succeed given the provided `pubkey`, `signature`, and `depositDataRoot` + +#### `withdrawRestakedBeaconChainETH` + +```solidity +function withdrawRestakedBeaconChainETH( + address recipient, + uint256 amountWei +) + external + onlyEigenPodManager +``` + +The `EigenPodManager` calls this method when withdrawing a Pod Owner's shares as tokens (native ETH). The input `amountWei` is converted to Gwei and subtracted from `withdrawableRestakedExecutionLayerGwei`, which tracks native ETH balance that has been accounted for in a checkpoint (see [Checkpointing Validators](#checkpointing-validators)). + +If the `EigenPod` does not have `amountWei` available to transfer, this method will revert + +*Effects*: +* Decreases the pod's `withdrawableRestakedExecutionLayerGwei` by `amountWei / GWEI_TO_WEI` +* Sends `amountWei` ETH to `recipient` + +*Requirements*: +* `amountWei / GWEI_TO_WEI` MUST NOT be greater than the proven `withdrawableRestakedExecutionLayerGwei` +* Pod MUST have at least `amountWei` ETH balance +* `recipient` MUST NOT revert when transferred `amountWei` +* `amountWei` MUST be a whole Gwei amount + +#### `recoverTokens` + +```solidity +function recoverTokens( + IERC20[] memory tokenList, + uint256[] memory amountsToWithdraw, + address recipient +) + external + onlyEigenPodOwner + onlyWhenNotPaused(PAUSED_NON_PROOF_WITHDRAWALS) +``` + +Allows the Pod Owner to rescue ERC20 tokens accidentally sent to the `EigenPod`. + +*Effects:* +* Calls `transfer` on each of the ERC20's in `tokenList`, sending the corresponding `amountsToWithdraw` to the `recipient` + +*Requirements:* +* Caller MUST be the Pod Owner +* Pause status MUST NOT be set: `PAUSED_NON_PROOF_WITHDRAWALS` +* `tokenList` and `amountsToWithdraw` MUST have equal lengths + diff --git a/docs/core/EigenPodManager.md b/docs/core/EigenPodManager.md index a036f9c73..fde955d9f 100644 --- a/docs/core/EigenPodManager.md +++ b/docs/core/EigenPodManager.md @@ -1,88 +1,48 @@ ## EigenPodManager - - | File | Type | Proxy | | -------- | -------- | -------- | | [`EigenPodManager.sol`](../../src/contracts/pods/EigenPodManager.sol) | Singleton | Transparent proxy | | [`EigenPod.sol`](../../src/contracts/pods/EigenPod.sol) | Instanced, deployed per-user | Beacon proxy | -| [`DelayedWithdrawalRouter.sol`](../../src/contracts/pods/DelayedWithdrawalRouter.sol) | Singleton | Transparent proxy | -| [`succinctlabs/EigenLayerBeaconOracle.sol`](https://github.com/succinctlabs/telepathy-contracts/blob/main/external/integrations/eigenlayer/EigenLayerBeaconOracle.sol) | Singleton | UUPS Proxy | - -The `EigenPodManager` and `EigenPod` contracts allow Stakers to restake beacon chain ETH which can then be delegated to Operators via the `DelegationManager`. - -The `EigenPodManager` is the entry point for this process, allowing Stakers to deploy an `EigenPod` and begin restaking. While actively restaking, a Staker uses their `EigenPod` to validate various beacon chain state proofs of validator balance and withdrawal status. When exiting, a Staker uses the `DelegationManager` to undelegate or queue a withdrawal from EigenLayer. -`EigenPods` serve as the withdrawal credentials for one or more beacon chain validators controlled by a Staker. Their primary role is to validate beacon chain proofs for each of the Staker's validators. Beacon chain proofs are used to verify a validator's: -* `EigenPod.verifyWithdrawalCredentials`: withdrawal credentials and effective balance -* `EigenPod.verifyBalanceUpdates`: effective balance (when it changes) -* `EigenPod.verifyAndProcessWithdrawals`: withdrawable epoch, and processed withdrawals within historical block summary +The `EigenPodManager` manages the relationship between a Staker's `EigenPod`, the delegatable shares each Staker holds in the beacon chain ETH strategy, and the withdrawal of those shares via the `DelegationManager`. These functions together support Stakers' ability to restake beacon chain ETH and delegate restaked ETH to Operators in order to earn additional yield. -See [/proofs](./proofs/) for detailed documentation on each of the state proofs used in these methods. Additionally, proofs are checked against a beacon chain block root supplied by Succinct's Telepathy protocol ([docs link](https://docs.telepathy.xyz/)). +The `EigenPodManager` is the entry point for this process, allowing Stakers to deploy an `EigenPod` and begin restaking. After a Staker deploys their `EigenPod`, the `EigenPodManager` receives various updates from the pod that add or remove shares from the Staker. #### High-level Concepts -The functions of the `EigenPodManager` and `EigenPod` contracts are tightly linked. Rather than writing two separate docs pages, documentation for both contracts is included in this file. This document organizes methods according to the following themes (click each to be taken to the relevant section): +This document organizes methods according to the following themes (click each to be taken to the relevant section): * [Depositing Into EigenLayer](#depositing-into-eigenlayer) -* [Restaking Beacon Chain ETH](#restaking-beacon-chain-eth) * [Withdrawal Processing](#withdrawal-processing) -* [System Configuration](#system-configuration) * [Other Methods](#other-methods) #### Important State Variables -* `EigenPodManager`: - * `mapping(address => IEigenPod) public ownerToPod`: Tracks the deployed `EigenPod` for each Staker - * `mapping(address => int256) public podOwnerShares`: Keeps track of the actively restaked beacon chain ETH for each Staker. - * In some cases, a beacon chain balance update may cause a Staker's balance to drop below zero. This is because when queueing for a withdrawal in the `DelegationManager`, the Staker's current shares are fully removed. If the Staker's beacon chain balance drops after this occurs, their `podOwnerShares` may go negative. This is a temporary change to account for the drop in balance, and is ultimately corrected when the withdrawal is finally processed. - * Since balances on the consensus layer are stored only in Gwei amounts, the EigenPodManager enforces the invariant that `podOwnerShares` is always a whole Gwei amount for every staker, i.e. `podOwnerShares[staker] % 1e9 == 0` always. -* `EigenPod`: - * `_validatorPubkeyHashToInfo[bytes32] -> (ValidatorInfo)`: individual validators are identified within an `EigenPod` according to their public key hash. This mapping keeps track of the following for each validator: - * `validatorStatus`: (`INACTIVE`, `ACTIVE`, `WITHDRAWN`) - * `validatorIndex`: A `uint40` that is unique for each validator making a successful deposit via the deposit contract - * `mostRecentBalanceUpdateTimestamp`: A timestamp that represents the most recent successful proof of the validator's effective balance - * `restakedBalanceGwei`: set to the validator's balance. - * `withdrawableRestakedExecutionLayerGwei`: When a Staker proves that a validator has exited from the beacon chain, the withdrawal amount is added to this variable. When completing a withdrawal of beacon chain ETH, the withdrawal amount is subtracted from this variable. See also: - * [`DelegationManager`: "Undelegating and Withdrawing"](./DelegationManager.md#undelegating-and-withdrawing) - * [`EigenPodManager`: "Withdrawal Processing"](#withdrawal-processing) - -#### Important Definitions - -* "Pod Owner": A Staker who has deployed an `EigenPod` is a Pod Owner. The terms are used interchangeably in this document. - * Pod Owners can only deploy a single `EigenPod`, but can restake any number of beacon chain validators from the same `EigenPod`. - * Pod Owners can delegate their `EigenPodManager` shares to Operators (via `DelegationManager`). - * These shares correspond to the amount of provably-restaked beacon chain ETH held by the Pod Owner via their `EigenPod`. -* `EigenPod`: - * `_podWithdrawalCredentials() -> (bytes memory)`: - * Gives `abi.encodePacked(bytes1(uint8(1)), bytes11(0), address(EigenPod))` - * These are the `0x01` withdrawal credentials of the `EigenPod`, used as a validator's withdrawal credentials on the beacon chain. +* `mapping(address => IEigenPod) public ownerToPod`: Tracks the deployed `EigenPod` for each Staker +* `mapping(address => int256) public podOwnerShares`: Keeps track of the actively restaked beacon chain ETH for each Staker. + * In some cases, a beacon chain balance update may cause a Staker's balance to drop below zero. This is because when queueing for a withdrawal in the `DelegationManager`, the Staker's current shares are fully removed. If the Staker's beacon chain balance drops after this occurs, their `podOwnerShares` may go negative. This is a temporary change to account for the drop in balance, and is ultimately corrected when the withdrawal is finally processed. + * Since balances on the consensus layer are stored only in Gwei amounts, the EigenPodManager enforces the invariant that `podOwnerShares` is always a whole Gwei amount for every staker, i.e. `podOwnerShares[staker] % 1e9 == 0` always. --- ### Depositing Into EigenLayer Before a Staker begins restaking beacon chain ETH, they need to deploy an `EigenPod`, stake, and start a beacon chain validator: -* [`EigenPodManager.createPod`](#eigenpodmanagercreatepod) -* [`EigenPodManager.stake`](#eigenpodmanagerstake) - * [`EigenPod.stake`](#eigenpodstake) +* [`createPod`](#createpod) +* [`stake`](#stake) -To complete the deposit process, the Staker needs to prove that the validator's withdrawal credentials are pointed at the `EigenPod`: -* [`EigenPod.verifyWithdrawalCredentials`](#eigenpodverifywithdrawalcredentials) - -#### `EigenPodManager.createPod` +#### `createPod` ```solidity -function createPod() external onlyWhenNotPaused(PAUSED_NEW_EIGENPODS) returns (address) +function createPod() + external + onlyWhenNotPaused(PAUSED_NEW_EIGENPODS) + returns (address) ``` Allows a Staker to deploy an `EigenPod` instance, if they have not done so already. -Each Staker can only deploy a single `EigenPod` instance, but a single `EigenPod` can serve as the withdrawal credentials for any number of beacon chain validators. Each `EigenPod` is created using Create2 and the beacon proxy pattern, using the Staker's address as the Create2 salt. +Each Staker can only deploy a single `EigenPod` instance, but a single `EigenPod` can serve as the fee recipient / withdrawal credentials for any number of beacon chain validators. Each `EigenPod` is created using Create2 and the beacon proxy pattern, using the Staker's address as the Create2 salt. As part of the `EigenPod` deployment process, the Staker is made the Pod Owner, a permissioned role within the `EigenPod`. @@ -97,10 +57,7 @@ As part of the `EigenPod` deployment process, the Staker is made the Pod Owner, * Caller MUST NOT have deployed an `EigenPod` already * Pause status MUST NOT be set: `PAUSED_NEW_EIGENPODS` -*As of M2*: -* `EigenPods` are initialized with restaking enabled by default (`hasRestaked = true`). Pods deployed before M2 may not have this enabled, and will need to call `EigenPod.activateRestaking()`. - -#### `EigenPodManager.stake` +#### `stake` ```solidity function stake( @@ -117,177 +74,24 @@ Allows a Staker to deposit 32 ETH into the beacon chain deposit contract, provid *Effects*: * Deploys and initializes an `EigenPod` on behalf of Staker, if this has not been done already -* See [`EigenPod.stake`](#eigenpodstake) +* See [`EigenPod.stake`](./EigenPod.md#stake) *Requirements*: * Pause status MUST NOT be set: `PAUSED_NEW_EIGENPODS` -* See [`EigenPod.stake`](#eigenpodstake) - -##### `EigenPod.stake` - -```solidity -function stake( - bytes calldata pubkey, - bytes calldata signature, - bytes32 depositDataRoot -) - external - payable - onlyEigenPodManager -``` - -Handles the call to the beacon chain deposit contract. Only called via `EigenPodManager.stake`. - -*Effects*: -* Deposits 32 ETH into the beacon chain deposit contract, and provides the pod's address as the deposit's withdrawal credentials - -*Requirements*: -* Caller MUST be the `EigenPodManager` -* Call value MUST be 32 ETH -* Deposit contract `deposit` method MUST succeed given the provided `pubkey`, `signature`, and `depositDataRoot` - -#### `EigenPod.verifyWithdrawalCredentials` - -```solidity -function verifyWithdrawalCredentials( - uint64 oracleTimestamp, - BeaconChainProofs.StateRootProof calldata stateRootProof, - uint40[] calldata validatorIndices, - bytes[] calldata validatorFieldsProofs, - bytes32[][] calldata validatorFields -) - external - onlyEigenPodOwner - onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_CREDENTIALS) - hasEnabledRestaking -``` - -Once a Pod Owner has deposited ETH into the beacon chain deposit contract, they can call this method to "fully restake" one or more validators by proving the validator's withdrawal credentials are pointed at the `EigenPod`. This activation will mean that the ETH in those validators: -* is awarded to the Staker/Pod Owner in `EigenPodManager.podOwnerShares` -* is delegatable to an Operator (via the `DelegationManager`) - -For each successfully proven validator, that validator's status becomes `VALIDATOR_STATUS.ACTIVE`, and the sum of restakable ether across all newly-proven validators is provided to [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](#eigenpodmanagerrecordbeaconchainethbalanceupdate), where it is added to the Pod Owner's shares. If the Pod Owner is delegated to an Operator via the `DelegationManager`, this sum is also added to the Operator's delegated shares for the beacon chain ETH strategy. - -For each validator the Pod Owner wants to verify, the Pod Owner must supply: -* `validatorIndices`: their validator's `ValidatorIndex` (see [consensus specs](https://eth2book.info/capella/part3/config/types/#validatorindex)) -* `validatorFields`: the fields of the `Validator` container associated with the validator (see [consensus specs](https://eth2book.info/capella/part3/containers/dependencies/#validator)) -* `stateRootProof`: a proof that will verify `stateRootProof.beaconStateRoot` against an oracle-provided beacon block root -* `validatorFieldsProofs`: a proof that the `Validator` container belongs to the associated validator at the given `ValidatorIndex` within `stateRootProof.beaconStateRoot` -* `oracleTimestamp`: a timestamp used to fetch a beacon block root from `EigenPodManager.beaconChainOracle` - -*Beacon chain proofs used*: -* [`verifyStateRootAgainstLatestBlockRoot`](./proofs/BeaconChainProofs.md#beaconchainproofsverifystaterootagainstlatestblockroot) -* [`verifyValidatorFields`](./proofs/BeaconChainProofs.md#beaconchainproofsverifyvalidatorfields) - -*Effects*: -* For each validator (`_validatorPubkeyHashToInfo[pubkeyHash]`) the validator's info is set for the first time: - * `VALIDATOR_STATUS` moves from `INACTIVE` to `ACTIVE` - * `validatorIndex` is recorded - * `mostRecentBalanceUpdateTimestamp` is set to the `oracleTimestamp` used to fetch the beacon block root - * `restakedBalanceGwei` is set to the validator's effective balance -* See [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](#eigenpodmanagerrecordbeaconchainethbalanceupdate) - -*Requirements*: -* Caller MUST be the Pod Owner -* Pause status MUST NOT be set: `PAUSED_EIGENPODS_VERIFY_CREDENTIALS` -* Pod MUST have enabled restaking -* All input array lengths MUST be equal -* `oracleTimestamp`: - * MUST be greater than or equal to the timestamp of the first slot in the epoch following `mostRecentWithdrawalTimestamp` - * MUST be no more than `VERIFY_BALANCE_UPDATE_WINDOW_SECONDS` (~4.5 hrs) old - * MUST be queryable via `EigenPodManager.getBlockRootAtTimestamp` (fails if `stateRoot == 0`) -* `BeaconChainProofs.verifyStateRootAgainstLatestBlockRoot` MUST verify the provided `beaconStateRoot` against the oracle-provided `latestBlockRoot` -* For each validator: - * The validator's status MUST initially be `VALIDATOR_STATUS.INACTIVE` - * `BeaconChainProofs.verifyValidatorFields` MUST verify the provided `validatorFields` against the `beaconStateRoot` - * The aforementioned proofs MUST show that the validator's withdrawal credentials are set to the `EigenPod` -* See [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](#eigenpodmanagerrecordbeaconchainethbalanceupdate) - -*As of M2*: -* Restaking is enabled by default for pods deployed after M2. See `activateRestaking` for more info. - ---- - -### Restaking Beacon Chain ETH - -At this point, a Staker/Pod Owner has deployed their `EigenPod`, started their beacon chain validator, and proven that its withdrawal credentials are pointed to their `EigenPod`. They are now free to delegate to an Operator (if they have not already), or start up + verify additional beacon chain validators that also withdraw to the same `EigenPod`. - -The primary method concerning actively restaked validators is: -* [`EigenPod.verifyBalanceUpdates`](#eigenpodverifybalanceupdates) - -#### `EigenPod.verifyBalanceUpdates` - -```solidity -function verifyBalanceUpdates( - uint64 oracleTimestamp, - uint40[] calldata validatorIndices, - BeaconChainProofs.StateRootProof calldata stateRootProof, - bytes[] calldata validatorFieldsProofs, - bytes32[][] calldata validatorFields -) - external - onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE) -``` - -Anyone (not just the Pod Owner) may call this method with one or more valid balance update proofs to record beacon chain balance updates in one or more of the `EigenPod's` validators. - -A successful balance update proof updates the `EigenPod's` view of a validator's [effective balance](https://eth2book.info/capella/part2/incentives/balances/). If the validator's effective balance has changed, the difference is sent to `EigenPodManager.recordBeaconChainETHBalanceUpdate`, which updates the Pod Owner's shares. If the Pod Owner is delegated to an Operator, this delta is also sent to the `DelegationManager` to update the Operator's delegated beacon chain ETH shares. - -Note that if a validator's effective balance has decreased, this method will result in shares being removed from the Pod Owner in `EigenPodManager.recordBeaconChainETHBalanceUpdate`. This may cause the Pod Owner's balance to go negative in some cases, representing a "deficit" that must be repaid before any withdrawals can be processed. One example flow where this might occur is: -* Pod Owner calls `DelegationManager.undelegate`, which queues a withdrawal in the `DelegationManager`. The Pod Owner's shares are set to 0 while the withdrawal is in the queue. -* Pod Owner's beacon chain ETH balance decreases (maybe due to slashing), and someone provides a proof of this to `EigenPod.verifyBalanceUpdates`. In this case, the Pod Owner will have negative shares in the `EigenPodManager`. -* After a delay, the Pod Owner calls `DelegationManager.completeQueuedWithdrawal`. The negative shares are then repaid out of the withdrawn assets. - -For the validator whose balance should be updated, the caller must supply: -* `validatorIndex`: the validator's `ValidatorIndex` (see [consensus specs](https://eth2book.info/capella/part3/config/types/#validatorindex)) -* `stateRootProof`: a proof that will verify `stateRootProof.beaconStateRoot` against an oracle-provided beacon block root -* `validatorFieldsProofs`: a proof that the `Validator` container belongs to the associated validator at the given `ValidatorIndex` within `stateRootProof.beaconStateRoot` -* `validatorFields`: the fields of the `Validator` container associated with the validator (see [consensus specs](https://eth2book.info/capella/part3/containers/dependencies/#validator)) -* `oracleTimestamp`: a timestamp used to fetch a beacon block root from `EigenPodManager.beaconChainOracle` - -*Beacon chain proofs used*: -* [`verifyStateRootAgainstLatestBlockRoot`](./proofs/BeaconChainProofs.md#beaconchainproofsverifystaterootagainstlatestblockroot) -* [`verifyValidatorFields`](./proofs/BeaconChainProofs.md#beaconchainproofsverifyvalidatorfields) - -*Effects*: -* Updates the validator's stored info: - * `restakedBalanceGwei` is updated to the newly-proven effective balance - * `mostRecentBalanceUpdateTimestamp` is set to the `oracleTimestamp` used to fetch the beacon block root -* See [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](#eigenpodmanagerrecordbeaconchainethbalanceupdate) - -*Requirements*: -* Pause status MUST NOT be set: `PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE` -* Balance updates should only be made before a validator has fully exited. If the validator has exited, any further proofs should follow the `verifyAndProcessWithdrawals` path. - * This is to prevent someone from providing a "balance update" on an exited validator that "proves" a balance of 0, when we want to process that update as a withdrawal instead. -* `oracleTimestamp`: - * MUST be no more than `VERIFY_BALANCE_UPDATE_WINDOW_SECONDS` (~4.5 hrs) old - * MUST be newer than the validator's `mostRecentBalanceUpdateTimestamp` - * MUST be queryable via `EigenPodManager.getBlockRootAtTimestamp` (fails if `stateRoot == 0`) -* `validatorFields[0]` MUST be a pubkey hash corresponding to a validator whose withdrawal credentials have been proven, and is not yet withdrawn (`VALIDATOR_STATUS.ACTIVE`) -* `BeaconChainProofs.verifyStateRootAgainstLatestBlockRoot` MUST verify the provided `beaconStateRoot` against the oracle-provided `latestBlockRoot` -* `BeaconChainProofs.verifyValidatorFields` MUST verify the provided `validatorFields` against the `beaconStateRoot` -* See [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](#eigenpodmanagerrecordbeaconchainethbalanceupdate) +* See [`EigenPod.stake`](./EigenPod.md#stake) --- ### Withdrawal Processing -The `DelegationManager` is the entry point for all undelegation and withdrawals, which must be queued for a time before being completed. When a withdrawal is initiated, the following method is used: -* [`EigenPodManager.removeShares`](#eigenpodmanagerremoveshares) +The `DelegationManager` is the entry point for all undelegation and withdrawals, which must be queued for a time before being completed. When a withdrawal is initiated, the `DelegationManager` calls the following method: +* [`removeShares`](#removeshares) When completing a queued undelegation or withdrawal, the `DelegationManager` calls one of these two methods: -* [`EigenPodManager.addShares`](#eigenpodmanageraddshares) -* [`EigenPodManager.withdrawSharesAsTokens`](#eigenpodmanagerwithdrawsharesastokens) - * [`EigenPod.withdrawRestakedBeaconChainETH`](#eigenpodwithdrawrestakedbeaconchaineth) +* [`addShares`](#addshares) +* [`withdrawSharesAsTokens`](#withdrawsharesastokens) -If a Staker wishes to fully withdraw their beacon chain ETH (via `withdrawSharesAsTokens`), they need to exit their validator and prove the withdrawal *prior to* completing the queued withdrawal. They do so using this method: -* [`EigenPod.verifyAndProcessWithdrawals`](#eigenpodverifyandprocesswithdrawals) - -Some withdrawals are sent to their destination via the `DelayedWithdrawalRouter`: -* [`DelayedWithdrawalRouter.createDelayedWithdrawal`](#delayedwithdrawalroutercreatedelayedwithdrawal) -* [`DelayedWithdrawalRouter.claimDelayedWithdrawals`](#delayedwithdrawalrouterclaimdelayedwithdrawals) - -#### `EigenPodManager.removeShares` +#### `removeShares` ```solidity function removeShares( @@ -317,7 +121,7 @@ This method is not allowed to cause the `Staker's` balance to go negative. This * `shares` MUST NOT be greater than `podOwner's` share balance * `shares` MUST be a whole Gwei amount -#### `EigenPodManager.addShares` +#### `addShares` ```solidity function addShares( @@ -347,7 +151,7 @@ If the Pod Owner has a share deficit (negative shares), the deficit is repaid ou * `shares` MUST NOT be negative when converted to an `int256` * `shares` MUST be a whole Gwei amount -#### `EigenPodManager.withdrawSharesAsTokens` +#### `withdrawSharesAsTokens` ```solidity function withdrawSharesAsTokens( @@ -361,9 +165,7 @@ function withdrawSharesAsTokens( The `DelegationManager` calls this method when a queued withdrawal is completed and the withdrawer specifies that they want to receive the withdrawal as tokens (rather than shares). This can be used to "fully exit" some amount of beacon chain ETH and send it to a recipient (via `EigenPod.withdrawRestakedBeaconChainETH`). -Note that because this method entails withdrawing and sending beacon chain ETH, two conditions must be met for this method to succeed: (i) the ETH being withdrawn should already be in the `EigenPod`, and (ii) the beacon chain withdrawals responsible for the ETH should already be proven. - -This means that before completing their queued withdrawal, a Pod Owner needs to prove their beacon chain withdrawals via `EigenPod.verifyAndProcessWithdrawals`. +Note that because this method entails withdrawing and sending beacon chain ETH, two conditions must be met for this method to succeed: (i) the ETH being withdrawn should already be in the `EigenPod`, and (ii) the amount being withdrawn should be accounted for in `EigenPod.withdrawableRestakedExecutionLayerGwei`. This latter condition can be achieved by completing an `EigenPod` checkpoint just prior to completing a queued `DelegationManager` withdrawal (see [EigenPod: Checkpointing Validators](./EigenPod.md#checkpointing-validators) for details). Also note that, like `addShares`, if the original Pod Owner has a share deficit (negative shares), the deficit is repaid out of the withdrawn `shares` before any native ETH is withdrawn. @@ -373,211 +175,20 @@ Also note that, like `addShares`, if the original Pod Owner has a share deficit *Effects*: * If `podOwner's` share balance is negative, `shares` are added until the balance hits 0 - * Any remaining shares are withdrawn and sent to `destination` (see [`EigenPod.withdrawRestakedBeaconChainETH`](#eigenpodwithdrawrestakedbeaconchaineth)) + * Any remaining shares are converted 1:1 to ETH and sent to `destination` (see [`EigenPod.withdrawRestakedBeaconChainETH`](./EigenPod.md#withdrawrestakedbeaconchaineth)) *Requirements*: * `podOwner` MUST NOT be zero * `destination` MUST NOT be zero * `shares` MUST NOT be negative when converted to an `int256` * `shares` MUST be a whole Gwei amount -* See [`EigenPod.withdrawRestakedBeaconChainETH`](#eigenpodwithdrawrestakedbeaconchaineth) - -##### `EigenPod.withdrawRestakedBeaconChainETH` - -```solidity -function withdrawRestakedBeaconChainETH( - address recipient, - uint256 amountWei -) - external - onlyEigenPodManager -``` - -The `EigenPodManager` calls this method when withdrawing a Pod Owner's shares as tokens (native ETH). The input `amountWei` is converted to Gwei and subtracted from `withdrawableRestakedExecutionLayerGwei`, which tracks Gwei that has been provably withdrawn (via `EigenPod.verifyAndProcessWithdrawals`). - -As such: -* If a withdrawal has not been proven that sufficiently raises `withdrawableRestakedExecutionLayerGwei`, this method will revert. -* If the `EigenPod` does not have `amountWei` available to transfer, this method will revert - -*Effects*: -* Decreases the pod's `withdrawableRestakedExecutionLayerGwei` by `amountWei / GWEI_TO_WEI` -* Sends `amountWei` ETH to `recipient` - -*Requirements*: -* `amountWei / GWEI_TO_WEI` MUST NOT be greater than the proven `withdrawableRestakedExecutionLayerGwei` -* Pod MUST have at least `amountWei` ETH balance -* `recipient` MUST NOT revert when transferred `amountWei` -* `amountWei` MUST be a whole Gwei amount - -#### `EigenPod.verifyAndProcessWithdrawals` - -```solidity -function verifyAndProcessWithdrawals( - uint64 oracleTimestamp, - BeaconChainProofs.StateRootProof calldata stateRootProof, - BeaconChainProofs.WithdrawalProof[] calldata withdrawalProofs, - bytes[] calldata validatorFieldsProofs, - bytes32[][] calldata validatorFields, - bytes32[][] calldata withdrawalFields -) - external - onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_WITHDRAWAL) - onlyNotFrozen -``` - -Anyone (not just the Pod Owner) can call this method to prove that one or more validators associated with an `EigenPod` have performed a full or partial withdrawal from the beacon chain. - -Whether each withdrawal is a full or partial withdrawal is determined by the validator's "withdrawable epoch" in the `Validator` container given by `validatorFields` (see [consensus specs](https://eth2book.info/capella/part3/containers/dependencies/#validator)). If the withdrawal proof timestamp is after this epoch, the withdrawal is a full withdrawal. -* Partial withdrawals are performed automatically by the beacon chain when a validator has an effective balance over 32 ETH. This method can be used to prove that these withdrawals occurred, allowing the Pod Owner to withdraw the excess ETH (via [`DelayedWithdrawalRouter.createDelayedWithdrawal`](#delayedwithdrawalroutercreatedelayedwithdrawal)). -* Full withdrawals are performed when a Pod Owner decides to fully exit a validator from the beacon chain. To do this, the Pod Owner should follow these steps: - 1. Undelegate or queue a withdrawal (via the `DelegationManager`: ["Undelegating and Withdrawing"](./DelegationManager.md#undelegating-and-withdrawing)) - 2. Exit their validator from the beacon chain and provide a proof to this method - 3. Complete their withdrawal (via [`DelegationManager.completeQueuedWithdrawal`](./DelegationManager.md#completequeuedwithdrawal)). - -If the Pod Owner only exits their validator, the ETH of the pod owner is still staked through EigenLayer and can be used to service AVSs, even though their ETH has been withdrawn from the beacon chain. The protocol allows for this edge case. - -*Beacon chain proofs used*: -* [`verifyStateRootAgainstLatestBlockRoot`](./proofs/BeaconChainProofs.md#beaconchainproofsverifystaterootagainstlatestblockroot) -* [`verifyWithdrawal`](./proofs/BeaconChainProofs.md#beaconchainproofsverifywithdrawal) -* [`verifyValidatorFields`](./proofs/BeaconChainProofs.md#beaconchainproofsverifyvalidatorfields) - -*Effects*: -* For each proven withdrawal: - * The validator in question is recorded as having a proven withdrawal at the timestamp given by `withdrawalProof.timestampRoot` - * This is to prevent the same withdrawal from being proven twice - * If this is a full withdrawal: - * Any withdrawal amount in excess of `MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR` is immediately withdrawn (see [`DelayedWithdrawalRouter.createDelayedWithdrawal`](#delayedwithdrawalroutercreatedelayedwithdrawal)) - * The remainder (`MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR`) must be withdrawn through the `DelegationManager's` withdrawal flow, but in the meantime is added to `EigenPod.withdrawableRestakedExecutionLayerGwei` - * If the amount being withdrawn is not equal to the current accounted-for validator balance, a `shareDelta` is calculated to be sent to ([`EigenPodManager.recordBeaconChainETHBalanceUpdate`](#eigenpodmanagerrecordbeaconchainethbalanceupdate)). - * The validator's info is updated to reflect its `WITHDRAWN` status, and `restakedBalanceGwei` is set to 0 - * If this is a partial withdrawal: - * The withdrawal amount is added to `sumOfPartialWithdrawalsClaimedGwei` - * The withdrawal amount is withdrawn (via [`DelayedWithdrawalRouter.createDelayedWithdrawal`](#delayedwithdrawalroutercreatedelayedwithdrawal)) - -*Requirements*: -* Pause status MUST NOT be set: `PAUSED_EIGENPODS_VERIFY_WITHDRAWAL` -* All input array lengths MUST be equal -* `oracleTimestamp` MUST be queryable via `EigenPodManager.getBlockRootAtTimestamp` (fails if `stateRoot == 0`) -* `BeaconChainProofs.verifyStateRootAgainstLatestBlockRoot` MUST verify the provided `beaconStateRoot` against the oracle-provided `latestBlockRoot` -* For each withdrawal being proven: - * The time of the withdrawal (`withdrawalProof.timestampRoot`) must be AFTER the `EigenPod's` `mostRecentWithdrawalTimestamp` - * The validator MUST be in either status: `ACTIVE` or `WITHDRAWN` - * `WITHDRAWN` is permitted because technically, it's possible to deposit additional ETH into an exited validator and have the ETH be auto-withdrawn. - * If the withdrawal is a full withdrawal, only `ACTIVE` is permitted - * The validator MUST NOT have already proven a withdrawal at the `withdrawalProof.timestampRoot` - * `BeaconChainProofs.verifyWithdrawal` MUST verify the provided `withdrawalFields` against the provided `beaconStateRoot` - * `BeaconChainProofs.verifyValidatorFields` MUST verify the provided `validatorFields` against the `beaconStateRoot` - -#### `DelayedWithdrawalRouter.createDelayedWithdrawal` - -```solidity -function createDelayedWithdrawal( - address podOwner, - address recipient -) - external - payable - onlyEigenPod(podOwner) - onlyWhenNotPaused(PAUSED_DELAYED_WITHDRAWAL_CLAIMS) -``` - -Used by `EigenPods` to queue a withdrawal of beacon chain ETH that can be claimed by a `recipient` after `withdrawalDelayBlocks` have passed. - -*Effects*: -* Creates a `DelayedWithdrawal` for the `recipient` in the amount of `msg.value`, starting at the current block - -*Requirements*: -* Pause status MUST NOT be set: `PAUSED_DELAYED_WITHDRAWAL_CLAIMS` -* Caller MUST be the `EigenPod` associated with the `podOwner` -* `recipient` MUST NOT be zero - -#### `DelayedWithdrawalRouter.claimDelayedWithdrawals` - -```solidity -function claimDelayedWithdrawals( - address recipient, - uint256 maxNumberOfDelayedWithdrawalsToClaim -) - external - nonReentrant - onlyWhenNotPaused(PAUSED_DELAYED_WITHDRAWAL_CLAIMS) - -// (Uses `msg.sender` as `recipient`) -function claimDelayedWithdrawals( - uint256 maxNumberOfDelayedWithdrawalsToClaim -) - external - nonReentrant - onlyWhenNotPaused(PAUSED_DELAYED_WITHDRAWAL_CLAIMS) -``` - -After `withdrawalDelayBlocks`, withdrawals can be claimed using these methods. Claims may be processed on behalf of someone else by passing their address in as the `recipient`. Otherwise, claims are processed on behalf of `msg.sender`. - -This method loops over up to `maxNumberOfDelayedWithdrawalsToClaim` withdrawals, tallys each withdrawal amount, and sends the total to the `recipient`. - -*Effects*: -* Updates the `recipient's` `delayedWithdrawalsCompleted` -* Sends ETH from completed withdrawals to the `recipient` - -*Requirements*: -* Pause status MUST NOT be set: `PAUSED_DELAYED_WITHDRAWAL_CLAIMS` - ---- - -### System Configuration - -* [`EigenPodManager.updateBeaconChainOracle`](#eigenpodmanagerupdatebeaconchainoracle) -* [`DelayedWithdrawalRouter.setWithdrawalDelayBlocks`](#delayedwithdrawalroutersetwithdrawaldelayblocks) - -#### `EigenPodManager.updateBeaconChainOracle` - -```solidity -function updateBeaconChainOracle(IBeaconChainOracle newBeaconChainOracle) external onlyOwner -``` - -Allows the owner to update the address of the oracle used by `EigenPods` to retrieve beacon chain state roots (used when verifying beacon chain state proofs). - -*Effects*: -* Updates `EigenPodManager.beaconChainOracle` - -*Requirements*: -* Caller MUST be the owner - -#### `DelayedWithdrawalRouter.setWithdrawalDelayBlocks` - -```solidity -function setWithdrawalDelayBlocks(uint256 newValue) external onlyOwner -``` - -Allows the `DelayedWithdrawalRouter` to update the delay between withdrawal creation and claimability. - -The new delay can't exceed `MAX_WITHDRAWAL_DELAY_BLOCKS`. - -*Effects*: -* Updates `DelayedWithdrawalRouter.withdrawalDelayBlocks` - -*Requirements*: -* Caller MUST be the owner -* `newValue` MUST NOT be greater than `MAX_WITHDRAWAL_DELAY_BLOCKS` +* See [`EigenPod.withdrawRestakedBeaconChainETH`](./EigenPod.md#withdrawrestakedbeaconchaineth) --- ### Other Methods -This section details various methods that don't fit well into other sections. - -Stakers' balance updates are accounted for when the Staker's `EigenPod` calls this method: -* [`EigenPodManager.recordBeaconChainETHBalanceUpdate`](#eigenpodmanagerrecordbeaconchainethbalanceupdate) - -*For pods deployed prior to M2*, the following methods are callable: -* [`EigenPod.activateRestaking`](#eigenpodactivaterestaking) -* [`EigenPod.withdrawBeforeRestaking`](#eigenpodwithdrawbeforerestaking) - -The `EigenPod` also includes two token recovery mechanisms: -* [`EigenPod.withdrawNonBeaconChainETHBalanceWei`](#eigenpodwithdrawnonbeaconchainethbalancewei) -* [`EigenPod.recoverTokens`](#eigenpodrecovertokens) - -#### `EigenPodManager.recordBeaconChainETHBalanceUpdate` +#### `recordBeaconChainETHBalanceUpdate` ```solidity function recordBeaconChainETHBalanceUpdate( @@ -589,130 +200,25 @@ function recordBeaconChainETHBalanceUpdate( nonReentrant ``` -This method is called by an `EigenPod` during a balance update or withdrawal. It accepts a positive or negative `sharesDelta`, which is added/subtracted against the Pod Owner's shares. +This method is called by an `EigenPod` to report a change in its Pod Owner's shares. It accepts a positive or negative `sharesDelta`, which is added/subtracted against the Pod Owner's shares. The delta is also communicated to the `DelegationManager`, which updates the number of shares the Pod Owner has delegated to an Operator. + +Note that this method _may_ result in a Pod Owner's shares going negative. This can occur when: +* The Pod Owner has queued a withdrawal for all their Beacon Chain ETH shares via `DelegationManager.queueWithdrawals` + * This will set the `EigenPodManager.podOwnerShares[podOwner]` to 0 +* The Pod Owner's pod reports a negative delta, perhaps due to the Pod Owner getting slashed on the beacon chain. -If the Pod Owner is not in undelegation limbo and is delegated to an Operator, the `sharesDelta` is also sent to the `DelegationManager` to either increase or decrease the Operator's delegated shares. +In this case, the Pod Owner's `podOwnerShares` will go negative. *Entry Points*: * `EigenPod.verifyWithdrawalCredentials` -* `EigenPod.verifyBalanceUpdates` -* `EigenPod.verifyAndProcessWithdrawals` +* `EigenPod.startCheckpoint` +* `EigenPod.verifyCheckpointProofs` *Effects*: * Adds or removes `sharesDelta` from the Pod Owner's shares -* If the Pod Owner is NOT in undelegation limbo: - * If `sharesDelta` is negative: see [`DelegationManager.decreaseDelegatedShares`](./DelegationManager.md#decreasedelegatedshares) - * If `sharesDelta` is positive: see [`DelegationManager.increaseDelegatedShares`](./DelegationManager.md#increasedelegatedshares) +* If `sharesDelta` is negative: see [`DelegationManager.decreaseDelegatedShares`](./DelegationManager.md#decreasedelegatedshares) +* If `sharesDelta` is positive: see [`DelegationManager.increaseDelegatedShares`](./DelegationManager.md#increasedelegatedshares) *Requirements*: * Caller MUST be the `EigenPod` associated with the passed-in `podOwner` -* `sharesDelta`: - * MUST NOT be 0 - * If negative, `sharesDelta` MUST NOT remove more shares than the Pod Owner has - * MUST be a whole Gwei amount - -#### `EigenPod.activateRestaking` - -```solidity -function activateRestaking() - external - onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_CREDENTIALS) - onlyEigenPodOwner - hasNeverRestaked -``` - -Note: This method is only callable on pods deployed before M2. After M2, restaking is enabled by default. - -`activateRestaking` allows a Pod Owner to designate their pod (and any future ETH sent to it) as being restaked. Calling this method first withdraws any ETH in the `EigenPod` via the `DelayedWithdrawalRouter`, and then prevents further calls to `withdrawBeforeRestaking`. - -Withdrawing any future ETH sent via beacon chain withdrawal to the `EigenPod` requires providing beacon chain state proofs. However, ETH sent to the pod's `receive` function should be withdrawable without proofs (see [`withdrawNonBeaconChainETHBalanceWei`](#eigenpodwithdrawnonbeaconchainethbalancewei)). - -*Effects*: -* Sets `hasRestaked = true` -* Sets the pod's `nonBeaconChainETHBalanceWei` to 0 (only incremented in the fallback function) -* Updates the pod's most recent withdrawal timestamp to the current time -* See [DelayedWithdrawalRouter.createDelayedWithdrawal](#delayedwithdrawalroutercreatedelayedwithdrawal) - -*Requirements*: -* Caller MUST be the Pod Owner -* Pause status MUST NOT be set: `PAUSED_NEW_EIGENPODS` -* Pod MUST NOT have already activated restaking -* See [DelayedWithdrawalRouter.createDelayedWithdrawal](#delayedwithdrawalroutercreatedelayedwithdrawal) - -*As of M2*: restaking is automatically activated for newly-deployed `EigenPods` (`hasRestaked = true`). However, for `EigenPods` deployed *before* M2, restaking may not be active (unless the Pod Owner has called this method). - -#### `EigenPod.withdrawBeforeRestaking` - -```solidity -function withdrawBeforeRestaking() - external - onlyEigenPodOwner - hasNeverRestaked -``` - -Note: This method is only callable on pods deployed before M2. After M2, restaking is enabled by default. - -Allows the Pod Owner to withdraw any ETH in the `EigenPod` via the `DelayedWithdrawalRouter`, assuming restaking has not yet been activated. See [`EigenPod.activateRestaking`](#eigenpodactivaterestaking) for more details. - -*Effects*: -* Sets the pod's `nonBeaconChainETHBalanceWei` to 0 (only incremented in the fallback function) -* Updates the pod's most recent withdrawal timestamp to the current time -* See [DelayedWithdrawalRouter.createDelayedWithdrawal](#delayedwithdrawalroutercreatedelayedwithdrawal) - -*Requirements*: -* Caller MUST be the Pod Owner -* Pod MUST NOT have already activated restaking -* See [DelayedWithdrawalRouter.createDelayedWithdrawal](#delayedwithdrawalroutercreatedelayedwithdrawal) - -*As of M2*: restaking is automatically activated for newly-deployed `EigenPods`, making this method uncallable for pods deployed after M2. However, for `EigenPods` deployed *before* M2, restaking may not be active, and this method may be callable. - -#### `EigenPod.withdrawNonBeaconChainETHBalanceWei` - -```solidity -function withdrawNonBeaconChainETHBalanceWei( - address recipient, - uint256 amountToWithdraw -) - external - onlyEigenPodOwner - onlyWhenNotPaused(PAUSED_NON_PROOF_WITHDRAWALS) -``` - -Allows the Pod Owner to withdraw ETH accidentally sent to the contract's `receive` function. - -The `receive` function updates `nonBeaconChainETHBalanceWei`, which this function uses to calculate how much can be withdrawn. - -Withdrawals from this function are sent via the `DelayedWithdrawalRouter`, and can be claimed by the passed-in `recipient`. - -*Effects:* -* Decrements `nonBeaconChainETHBalanceWei` -* Sends `amountToWithdraw` wei to [`DelayedWithdrawalRouter.createDelayedWithdrawal`](#delayedwithdrawalroutercreatedelayedwithdrawal) - -*Requirements:* -* Pause status MUST NOT be set: `PAUSED_NON_PROOF_WITHDRAWALS` -* Caller MUST be the Pod Owner -* `amountToWithdraw` MUST NOT be greater than the amount sent to the contract's `receive` function -* See [`DelayedWithdrawalRouter.createDelayedWithdrawal`](#delayedwithdrawalroutercreatedelayedwithdrawal) - -#### `EigenPod.recoverTokens` - -```solidity -function recoverTokens( - IERC20[] memory tokenList, - uint256[] memory amountsToWithdraw, - address recipient -) - external - onlyEigenPodOwner - onlyWhenNotPaused(PAUSED_NON_PROOF_WITHDRAWALS) -``` - -Allows the Pod Owner to rescue ERC20 tokens accidentally sent to the `EigenPod`. - -*Effects:* -* Calls `transfer` on each of the ERC20's in `tokenList`, sending the corresponding `amountsToWithdraw` to the `recipient` - -*Requirements:* -* Pause status MUST NOT be set: `PAUSED_NON_PROOF_WITHDRAWALS` -* `tokenList` and `amountsToWithdraw` MUST have equal lengths -* Caller MUST be the Pod Owner +* `sharesDelta` MUST be a whole Gwei amount diff --git a/docs/images/EL_completing_queued_withdrawal.png b/docs/images/EL_completing_queued_withdrawal.png deleted file mode 100644 index 9dd09ddb5..000000000 Binary files a/docs/images/EL_completing_queued_withdrawal.png and /dev/null differ diff --git a/docs/images/EL_delegating.png b/docs/images/EL_delegating.png deleted file mode 100644 index f371009f4..000000000 Binary files a/docs/images/EL_delegating.png and /dev/null differ diff --git a/docs/images/EL_depositing.png b/docs/images/EL_depositing.png deleted file mode 100644 index 9e732e15d..000000000 Binary files a/docs/images/EL_depositing.png and /dev/null differ diff --git a/docs/images/EL_depositing_BeaconChainETH.png b/docs/images/EL_depositing_BeaconChainETH.png deleted file mode 100644 index ae1fa636b..000000000 Binary files a/docs/images/EL_depositing_BeaconChainETH.png and /dev/null differ diff --git a/docs/images/EL_depositing_BeaconChainETH_2.png b/docs/images/EL_depositing_BeaconChainETH_2.png deleted file mode 100644 index 7fdb154f4..000000000 Binary files a/docs/images/EL_depositing_BeaconChainETH_2.png and /dev/null differ diff --git a/docs/images/EL_eigenpods_architecture.png b/docs/images/EL_eigenpods_architecture.png deleted file mode 100644 index 9947afa2a..000000000 Binary files a/docs/images/EL_eigenpods_architecture.png and /dev/null differ diff --git a/docs/images/EL_operator_registration.png b/docs/images/EL_operator_registration.png deleted file mode 100644 index 640b344d2..000000000 Binary files a/docs/images/EL_operator_registration.png and /dev/null differ diff --git a/docs/images/EL_queuing_a_withdrawal.png b/docs/images/EL_queuing_a_withdrawal.png deleted file mode 100644 index 2ec65148e..000000000 Binary files a/docs/images/EL_queuing_a_withdrawal.png and /dev/null differ diff --git a/docs/images/EigenPods_Architecture.png b/docs/images/EigenPods_Architecture.png deleted file mode 100644 index 12703d6a6..000000000 Binary files a/docs/images/EigenPods_Architecture.png and /dev/null differ diff --git a/docs/images/Staker Flow Diagrams/Complete Withdrawal as Shares.png b/docs/images/Staker Flow Diagrams/Complete Withdrawal as Shares.png index 04b2633db..02cc8d23e 100644 Binary files a/docs/images/Staker Flow Diagrams/Complete Withdrawal as Shares.png and b/docs/images/Staker Flow Diagrams/Complete Withdrawal as Shares.png differ diff --git a/docs/images/Staker Flow Diagrams/Complete Withdrawal as Tokens.png b/docs/images/Staker Flow Diagrams/Complete Withdrawal as Tokens.png index 9d7cadf8c..78a0b98e8 100644 Binary files a/docs/images/Staker Flow Diagrams/Complete Withdrawal as Tokens.png and b/docs/images/Staker Flow Diagrams/Complete Withdrawal as Tokens.png differ diff --git a/docs/images/Staker Flow Diagrams/Delegating.png b/docs/images/Staker Flow Diagrams/Delegating.png index e58c8e99a..12934e7eb 100644 Binary files a/docs/images/Staker Flow Diagrams/Delegating.png and b/docs/images/Staker Flow Diagrams/Delegating.png differ diff --git a/docs/images/Staker Flow Diagrams/Depositing.png b/docs/images/Staker Flow Diagrams/Depositing.png index c2c9e8ea8..0c5e51549 100644 Binary files a/docs/images/Staker Flow Diagrams/Depositing.png and b/docs/images/Staker Flow Diagrams/Depositing.png differ diff --git a/docs/images/Staker Flow Diagrams/Partial Withdrawals.png b/docs/images/Staker Flow Diagrams/Partial Withdrawals.png deleted file mode 100644 index 3a6ef385d..000000000 Binary files a/docs/images/Staker Flow Diagrams/Partial Withdrawals.png and /dev/null differ diff --git a/docs/images/Staker Flow Diagrams/Queue Withdrawal.png b/docs/images/Staker Flow Diagrams/Queue Withdrawal.png index 16cbc9dbb..2ee83562c 100644 Binary files a/docs/images/Staker Flow Diagrams/Queue Withdrawal.png and b/docs/images/Staker Flow Diagrams/Queue Withdrawal.png differ diff --git a/docs/images/Staker Flow Diagrams/Validator Exits.png b/docs/images/Staker Flow Diagrams/Validator Exits.png index 9b46fe2ed..0bc3267cd 100644 Binary files a/docs/images/Staker Flow Diagrams/Validator Exits.png and b/docs/images/Staker Flow Diagrams/Validator Exits.png differ diff --git a/docs/images/Staker Flow Diagrams/Validator Yield.png b/docs/images/Staker Flow Diagrams/Validator Yield.png new file mode 100644 index 000000000..6237ffecc Binary files /dev/null and b/docs/images/Staker Flow Diagrams/Validator Yield.png differ diff --git a/docs/images/Withdrawal_Credential_Proof.png b/docs/images/Withdrawal_Credential_Proof.png deleted file mode 100644 index 72a290e88..000000000 Binary files a/docs/images/Withdrawal_Credential_Proof.png and /dev/null differ diff --git a/docs/images/Withdrawal_Proof.png b/docs/images/Withdrawal_Proof.png deleted file mode 100644 index 16c94980d..000000000 Binary files a/docs/images/Withdrawal_Proof.png and /dev/null differ diff --git a/docs/images/Withdrawal_Proof_Diagram.png b/docs/images/Withdrawal_Proof_Diagram.png deleted file mode 100644 index 070a54e84..000000000 Binary files a/docs/images/Withdrawal_Proof_Diagram.png and /dev/null differ diff --git a/docs/images/middleware_outline_doc.png b/docs/images/middleware_outline_doc.png deleted file mode 100644 index 82590f588..000000000 Binary files a/docs/images/middleware_outline_doc.png and /dev/null differ diff --git a/docs/images/operator_deregister.png b/docs/images/operator_deregister.png deleted file mode 100644 index be3075c10..000000000 Binary files a/docs/images/operator_deregister.png and /dev/null differ diff --git a/docs/images/operator_opting.png b/docs/images/operator_opting.png deleted file mode 100644 index 267460086..000000000 Binary files a/docs/images/operator_opting.png and /dev/null differ diff --git a/docs/images/samplemerkle.png b/docs/images/samplemerkle.png deleted file mode 100644 index 572905669..000000000 Binary files a/docs/images/samplemerkle.png and /dev/null differ diff --git a/docs/images/slashing.png b/docs/images/slashing.png deleted file mode 100644 index 587843f64..000000000 Binary files a/docs/images/slashing.png and /dev/null differ diff --git a/docs/images/staker_opting.png b/docs/images/staker_opting.png deleted file mode 100644 index 2f6528b85..000000000 Binary files a/docs/images/staker_opting.png and /dev/null differ diff --git a/docs/images/staker_withdrawing.png b/docs/images/staker_withdrawing.png deleted file mode 100644 index 3a1dba6ca..000000000 Binary files a/docs/images/staker_withdrawing.png and /dev/null differ diff --git a/docs/images/staterootproof.png b/docs/images/staterootproof.png deleted file mode 100644 index ec2493cdc..000000000 Binary files a/docs/images/staterootproof.png and /dev/null differ diff --git a/docs/images/three_middlewares.png b/docs/images/three_middlewares.png deleted file mode 100644 index 349099535..000000000 Binary files a/docs/images/three_middlewares.png and /dev/null differ diff --git a/docs/images/three_middlewares_withdrawal_queued.png b/docs/images/three_middlewares_withdrawal_queued.png deleted file mode 100644 index 319553a37..000000000 Binary files a/docs/images/three_middlewares_withdrawal_queued.png and /dev/null differ diff --git a/docs/images/withdrawal.png b/docs/images/withdrawal.png deleted file mode 100644 index 133a6f24d..000000000 Binary files a/docs/images/withdrawal.png and /dev/null differ diff --git a/pkg/bindings/BeaconChainProofs/binding.go b/pkg/bindings/BeaconChainProofs/binding.go index a79a51aff..2fc7439ef 100644 --- a/pkg/bindings/BeaconChainProofs/binding.go +++ b/pkg/bindings/BeaconChainProofs/binding.go @@ -32,7 +32,7 @@ var ( // BeaconChainProofsMetaData contains all meta data concerning the BeaconChainProofs contract. var BeaconChainProofsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212201a5064280ec3fe3ffe359ddd6406db7f8de6fe7e2cedaeaa278344482083ea7464736f6c634300080c0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c00cb22743991a146de10677177d34d77104039d759b6119b391bd5a11f1770f64736f6c634300080c0033", } // BeaconChainProofsABI is the input ABI used to generate the binding from. diff --git a/pkg/bindings/DelayedWithdrawalRouter/binding.go b/pkg/bindings/DelayedWithdrawalRouter/binding.go deleted file mode 100644 index 31fb64ca0..000000000 --- a/pkg/bindings/DelayedWithdrawalRouter/binding.go +++ /dev/null @@ -1,1969 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package DelayedWithdrawalRouter - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// IDelayedWithdrawalRouterDelayedWithdrawal is an auto generated low-level Go binding around an user-defined struct. -type IDelayedWithdrawalRouterDelayedWithdrawal struct { - Amount *big.Int - BlockCreated uint32 -} - -// IDelayedWithdrawalRouterUserDelayedWithdrawals is an auto generated low-level Go binding around an user-defined struct. -type IDelayedWithdrawalRouterUserDelayedWithdrawals struct { - DelayedWithdrawalsCompleted *big.Int - DelayedWithdrawals []IDelayedWithdrawalRouterDelayedWithdrawal -} - -// DelayedWithdrawalRouterMetaData contains all meta data concerning the DelayedWithdrawalRouter contract. -var DelayedWithdrawalRouterMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_eigenPodManager\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"MAX_WITHDRAWAL_DELAY_BLOCKS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"canClaimDelayedWithdrawal\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDelayedWithdrawals\",\"inputs\":[{\"name\":\"maxNumberOfDelayedWithdrawalsToClaim\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"claimDelayedWithdrawals\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"maxNumberOfDelayedWithdrawalsToClaim\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createDelayedWithdrawal\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"eigenPodManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getClaimableUserDelayedWithdrawals\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"structIDelayedWithdrawalRouter.DelayedWithdrawal[]\",\"components\":[{\"name\":\"amount\",\"type\":\"uint224\",\"internalType\":\"uint224\"},{\"name\":\"blockCreated\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getUserDelayedWithdrawals\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"structIDelayedWithdrawalRouter.DelayedWithdrawal[]\",\"components\":[{\"name\":\"amount\",\"type\":\"uint224\",\"internalType\":\"uint224\"},{\"name\":\"blockCreated\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"initOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"initPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_withdrawalDelayBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setWithdrawalDelayBlocks\",\"inputs\":[{\"name\":\"newValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"userDelayedWithdrawalByIndex\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIDelayedWithdrawalRouter.DelayedWithdrawal\",\"components\":[{\"name\":\"amount\",\"type\":\"uint224\",\"internalType\":\"uint224\"},{\"name\":\"blockCreated\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"userWithdrawals\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIDelayedWithdrawalRouter.UserDelayedWithdrawals\",\"components\":[{\"name\":\"delayedWithdrawalsCompleted\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"delayedWithdrawals\",\"type\":\"tuple[]\",\"internalType\":\"structIDelayedWithdrawalRouter.DelayedWithdrawal[]\",\"components\":[{\"name\":\"amount\",\"type\":\"uint224\",\"internalType\":\"uint224\"},{\"name\":\"blockCreated\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"userWithdrawalsLength\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdrawalDelayBlocks\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"DelayedWithdrawalCreated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelayedWithdrawalsClaimed\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amountClaimed\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"delayedWithdrawalsCompleted\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalDelayBlocksSet\",\"inputs\":[{\"name\":\"previousValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001f0e38038062001f0e8339810160408190526200003491620001a8565b6001600160a01b038116620000cb5760405162461bcd60e51b815260206004820152604c60248201527f44656c617965645769746864726177616c526f757465722e636f6e737472756360448201527f746f723a205f656967656e506f644d616e616765722063616e6e6f742062652060648201526b7a65726f206164647265737360a01b608482015260a4015b60405180910390fd5b6001600160a01b038116608052620000e2620000e9565b50620001da565b600054610100900460ff1615620001535760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608401620000c2565b60005460ff9081161015620001a6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b600060208284031215620001bb57600080fd5b81516001600160a01b0381168114620001d357600080fd5b9392505050565b608051611d11620001fd600039600081816101fa0152610c000152611d116000f3fe60806040526004361061014b5760003560e01c806385594e58116100b6578063e4f4f8871161006f578063e4f4f887146103cc578063e5db06c014610405578063eb990c5914610425578063ecb7cb1b14610445578063f2fde38b14610472578063fabc1cbc1461049257600080fd5b806385594e5814610317578063886f1195146103445780638da5cb5b14610364578063c0db354c14610382578063ca661c0414610395578063d44e1b76146103ac57600080fd5b806350f73e7c1161010857806350f73e7c14610254578063595c6a67146102785780635ac86ab71461028d5780635c975abb146102cd578063715018a6146102e257806375608896146102f757600080fd5b806310d67a2f14610150578063136439dd146101725780631f39d87f146101925780633e1de008146101c85780634665bcda146101e85780634d50f9a414610234575b600080fd5b34801561015c57600080fd5b5061017061016b36600461196d565b6104b2565b005b34801561017e57600080fd5b5061017061018d366004611991565b61056e565b34801561019e57600080fd5b506101b26101ad36600461196d565b6106ad565b6040516101bf91906119c8565b60405180910390f35b3480156101d457600080fd5b506101b26101e336600461196d565b6108a8565b3480156101f457600080fd5b5061021c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101bf565b34801561024057600080fd5b5061017061024f366004611991565b6109ee565b34801561026057600080fd5b5061026a60c95481565b6040519081526020016101bf565b34801561028457600080fd5b506101706109ff565b34801561029957600080fd5b506102bd6102a8366004611a15565b609854600160ff9092169190911b9081161490565b60405190151581526020016101bf565b3480156102d957600080fd5b5060985461026a565b3480156102ee57600080fd5b50610170610ac6565b34801561030357600080fd5b506102bd610312366004611a38565b610ada565b34801561032357600080fd5b50610337610332366004611a38565b610b5d565b6040516101bf9190611a64565b34801561035057600080fd5b5060975461021c906001600160a01b031681565b34801561037057600080fd5b506033546001600160a01b031661021c565b610170610390366004611a72565b610bdd565b3480156103a157600080fd5b5061026a62034bc081565b3480156103b857600080fd5b506101706103c7366004611991565b610e9d565b3480156103d857600080fd5b5061026a6103e736600461196d565b6001600160a01b0316600090815260ca602052604090206001015490565b34801561041157600080fd5b50610170610420366004611a38565b610f31565b34801561043157600080fd5b50610170610440366004611aab565b610fc6565b34801561045157600080fd5b5061046561046036600461196d565b6110ee565b6040516101bf9190611af1565b34801561047e57600080fd5b5061017061048d36600461196d565b6111a8565b34801561049e57600080fd5b506101706104ad366004611991565b61121e565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105299190611b47565b6001600160a01b0316336001600160a01b0316146105625760405162461bcd60e51b815260040161055990611b64565b60405180910390fd5b61056b8161137a565b50565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156105b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105da9190611bae565b6105f65760405162461bcd60e51b815260040161055990611bd0565b6098548181161461066f5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610559565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6001600160a01b038116600090815260ca6020526040812080546001909101546060926106da8383611c2e565b90508060005b82811015610786576001600160a01b038716600090815260ca6020526040812060010161070d8388611c45565b8154811061071d5761071d611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff1691810182905260c95490925061076391611c45565b4310156107735781925050610786565b508061077e81611c73565b9150506106e0565b508060008167ffffffffffffffff8111156107a3576107a3611c8e565b6040519080825280602002602001820160405280156107e857816020015b60408051808201909152600080825260208201528152602001906001900390816107c15790505b509050811561089d5760005b8281101561089b576001600160a01b038916600090815260ca602052604090206001016108218289611c45565b8154811061083157610831611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff1691810191909152825183908390811061087d5761087d611c5d565b6020026020010181905250808061089390611c73565b9150506107f4565b505b979650505050505050565b6001600160a01b038116600090815260ca6020526040812080546001909101546060926108d58383611c2e565b905060008167ffffffffffffffff8111156108f2576108f2611c8e565b60405190808252806020026020018201604052801561093757816020015b60408051808201909152600080825260208201528152602001906001900390816109105790505b50905060005b828110156109e4576001600160a01b038716600090815260ca6020526040902060010161096a8287611c45565b8154811061097a5761097a611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff169181019190915282518390839081106109c6576109c6611c5d565b602002602001018190525080806109dc90611c73565b91505061093d565b5095945050505050565b6109f6611471565b61056b816114cb565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610a47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6b9190611bae565b610a875760405162461bcd60e51b815260040161055990611bd0565b600019609881905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b610ace611471565b610ad86000611593565b565b6001600160a01b038216600090815260ca60205260408120548210801590610b54575060c9546001600160a01b038416600090815260ca60205260409020600101805484908110610b2d57610b2d611c5d565b600091825260209091200154610b509190600160e01b900463ffffffff16611c45565b4310155b90505b92915050565b60408051808201909152600080825260208201526001600160a01b038316600090815260ca60205260409020600101805483908110610b9e57610b9e611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff16918101919091529392505050565b60405163a38406a360e01b81526001600160a01b038084166004830152839133917f0000000000000000000000000000000000000000000000000000000000000000169063a38406a390602401602060405180830381865afa158015610c47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6b9190611b47565b6001600160a01b031614610ce75760405162461bcd60e51b815260206004820152603d60248201527f44656c617965645769746864726177616c526f757465722e6f6e6c794569676560448201527f6e506f643a206e6f7420706f644f776e6572277320456967656e506f640000006064820152608401610559565b60985460009060019081161415610d105760405162461bcd60e51b815260040161055990611ca4565b6001600160a01b038316610da65760405162461bcd60e51b815260206004820152605160248201527f44656c617965645769746864726177616c526f757465722e637265617465446560448201527f6c617965645769746864726177616c3a20726563697069656e742063616e6e6f60648201527074206265207a65726f206164647265737360781b608482015260a401610559565b346001600160e01b03811615610e96576040805180820182526001600160e01b03808416825263ffffffff43811660208085019182526001600160a01b038a16600081815260ca8352968720600190810180548083018255818a5293892088519551909616600160e01b029490961693909317939091019290925593525490917fb8f1b14c7caf74150801dcc9bc18d575cbeaf5b421943497e409df92c92e0f5991889188918691610e5791611c2e565b604080516001600160a01b0395861681529490931660208501526001600160e01b039091169183019190915260608201526080015b60405180910390a1505b5050505050565b60026065541415610ef05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610559565b600260655560985460009060019081161415610f1e5760405162461bcd60e51b815260040161055990611ca4565b610f2833836115e5565b50506001606555565b60026065541415610f845760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610559565b600260655560985460009060019081161415610fb25760405162461bcd60e51b815260040161055990611ca4565b610fbc83836115e5565b5050600160655550565b600054610100900460ff1615808015610fe65750600054600160ff909116105b806110005750303b158015611000575060005460ff166001145b6110635760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610559565b6000805460ff191660011790558015611086576000805461ff0019166101001790555b61108f85611593565b6110998484611750565b6110a2826114cb565b8015610e96576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6040805180820190915260008152606060208201526001600160a01b038216600090815260ca6020908152604080832081518083018352815481526001820180548451818702810187019095528085529195929486810194939192919084015b8282101561119a57600084815260209081902060408051808201909152908401546001600160e01b0381168252600160e01b900463ffffffff168183015282526001909201910161114e565b505050915250909392505050565b6111b0611471565b6001600160a01b0381166112155760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610559565b61056b81611593565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611271573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112959190611b47565b6001600160a01b0316336001600160a01b0316146112c55760405162461bcd60e51b815260040161055990611b64565b6098541981196098541916146113435760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610559565b609881905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c906020016106a2565b6001600160a01b0381166114085760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610559565b609754604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1609780546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b03163314610ad85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610559565b62034bc08111156115525760405162461bcd60e51b815260206004820152604560248201527f44656c617965645769746864726177616c526f757465722e5f7365745769746860448201527f64726177616c44656c6179426c6f636b733a206e657756616c756520746f6f206064820152646c6172676560d81b608482015260a401610559565b60c95460408051918252602082018390527f4ffb00400574147429ee377a5633386321e66d45d8b14676014b5fa393e61e9e910160405180910390a160c955565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216600090815260ca602052604081208054600190910154825b848110801561161e57508161161c8285611c45565b105b156116cb576001600160a01b038616600090815260ca602052604081206001016116488386611c45565b8154811061165857611658611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff1691810182905260c95490925061169e91611c45565b4310156116ab57506116cb565b80516116c0906001600160e01b031686611c45565b945050600101611607565b6116d58184611c45565b6001600160a01b038716600090815260ca602052604090205583156116fe576116fe868561183a565b7f6b7151500bd0b5cc211bcc47b3029831b769004df4549e8e1c9a69da05bb0943868561172b8487611c45565b604080516001600160a01b039094168452602084019290925290820152606001610e8c565b6097546001600160a01b031615801561177157506001600160a01b03821615155b6117f35760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610559565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26118368261137a565b5050565b8047101561188a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610559565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146118d7576040519150601f19603f3d011682016040523d82523d6000602084013e6118dc565b606091505b50509050806119535760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610559565b505050565b6001600160a01b038116811461056b57600080fd5b60006020828403121561197f57600080fd5b813561198a81611958565b9392505050565b6000602082840312156119a357600080fd5b5035919050565b80516001600160e01b0316825260209081015163ffffffff16910152565b602080825282518282018190526000919060409081850190868401855b82811015611a08576119f88483516119aa565b92840192908501906001016119e5565b5091979650505050505050565b600060208284031215611a2757600080fd5b813560ff8116811461198a57600080fd5b60008060408385031215611a4b57600080fd5b8235611a5681611958565b946020939093013593505050565b60408101610b5782846119aa565b60008060408385031215611a8557600080fd5b8235611a9081611958565b91506020830135611aa081611958565b809150509250929050565b60008060008060808587031215611ac157600080fd5b8435611acc81611958565b93506020850135611adc81611958565b93969395505050506040820135916060013590565b602080825282518282015282810151604080840181905281516060850181905260009392830191849160808701905b8084101561089b57611b338286516119aa565b938501936001939093019290820190611b20565b600060208284031215611b5957600080fd5b815161198a81611958565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611bc057600080fd5b8151801515811461198a57600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082821015611c4057611c40611c18565b500390565b60008219821115611c5857611c58611c18565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611c8757611c87611c18565b5060010190565b634e487b7160e01b600052604160045260246000fd5b60208082526019908201527f5061757361626c653a20696e646578206973207061757365640000000000000060408201526060019056fea264697066735822122000d7cf28f4403941c299573f87dac2e0ac298f40aace10d232ce8c2e9d0894a564736f6c634300080c0033", -} - -// DelayedWithdrawalRouterABI is the input ABI used to generate the binding from. -// Deprecated: Use DelayedWithdrawalRouterMetaData.ABI instead. -var DelayedWithdrawalRouterABI = DelayedWithdrawalRouterMetaData.ABI - -// DelayedWithdrawalRouterBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use DelayedWithdrawalRouterMetaData.Bin instead. -var DelayedWithdrawalRouterBin = DelayedWithdrawalRouterMetaData.Bin - -// DeployDelayedWithdrawalRouter deploys a new Ethereum contract, binding an instance of DelayedWithdrawalRouter to it. -func DeployDelayedWithdrawalRouter(auth *bind.TransactOpts, backend bind.ContractBackend, _eigenPodManager common.Address) (common.Address, *types.Transaction, *DelayedWithdrawalRouter, error) { - parsed, err := DelayedWithdrawalRouterMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DelayedWithdrawalRouterBin), backend, _eigenPodManager) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &DelayedWithdrawalRouter{DelayedWithdrawalRouterCaller: DelayedWithdrawalRouterCaller{contract: contract}, DelayedWithdrawalRouterTransactor: DelayedWithdrawalRouterTransactor{contract: contract}, DelayedWithdrawalRouterFilterer: DelayedWithdrawalRouterFilterer{contract: contract}}, nil -} - -// DelayedWithdrawalRouter is an auto generated Go binding around an Ethereum contract. -type DelayedWithdrawalRouter struct { - DelayedWithdrawalRouterCaller // Read-only binding to the contract - DelayedWithdrawalRouterTransactor // Write-only binding to the contract - DelayedWithdrawalRouterFilterer // Log filterer for contract events -} - -// DelayedWithdrawalRouterCaller is an auto generated read-only Go binding around an Ethereum contract. -type DelayedWithdrawalRouterCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// DelayedWithdrawalRouterTransactor is an auto generated write-only Go binding around an Ethereum contract. -type DelayedWithdrawalRouterTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// DelayedWithdrawalRouterFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type DelayedWithdrawalRouterFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// DelayedWithdrawalRouterSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type DelayedWithdrawalRouterSession struct { - Contract *DelayedWithdrawalRouter // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// DelayedWithdrawalRouterCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type DelayedWithdrawalRouterCallerSession struct { - Contract *DelayedWithdrawalRouterCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// DelayedWithdrawalRouterTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type DelayedWithdrawalRouterTransactorSession struct { - Contract *DelayedWithdrawalRouterTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// DelayedWithdrawalRouterRaw is an auto generated low-level Go binding around an Ethereum contract. -type DelayedWithdrawalRouterRaw struct { - Contract *DelayedWithdrawalRouter // Generic contract binding to access the raw methods on -} - -// DelayedWithdrawalRouterCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type DelayedWithdrawalRouterCallerRaw struct { - Contract *DelayedWithdrawalRouterCaller // Generic read-only contract binding to access the raw methods on -} - -// DelayedWithdrawalRouterTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type DelayedWithdrawalRouterTransactorRaw struct { - Contract *DelayedWithdrawalRouterTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewDelayedWithdrawalRouter creates a new instance of DelayedWithdrawalRouter, bound to a specific deployed contract. -func NewDelayedWithdrawalRouter(address common.Address, backend bind.ContractBackend) (*DelayedWithdrawalRouter, error) { - contract, err := bindDelayedWithdrawalRouter(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouter{DelayedWithdrawalRouterCaller: DelayedWithdrawalRouterCaller{contract: contract}, DelayedWithdrawalRouterTransactor: DelayedWithdrawalRouterTransactor{contract: contract}, DelayedWithdrawalRouterFilterer: DelayedWithdrawalRouterFilterer{contract: contract}}, nil -} - -// NewDelayedWithdrawalRouterCaller creates a new read-only instance of DelayedWithdrawalRouter, bound to a specific deployed contract. -func NewDelayedWithdrawalRouterCaller(address common.Address, caller bind.ContractCaller) (*DelayedWithdrawalRouterCaller, error) { - contract, err := bindDelayedWithdrawalRouter(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterCaller{contract: contract}, nil -} - -// NewDelayedWithdrawalRouterTransactor creates a new write-only instance of DelayedWithdrawalRouter, bound to a specific deployed contract. -func NewDelayedWithdrawalRouterTransactor(address common.Address, transactor bind.ContractTransactor) (*DelayedWithdrawalRouterTransactor, error) { - contract, err := bindDelayedWithdrawalRouter(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterTransactor{contract: contract}, nil -} - -// NewDelayedWithdrawalRouterFilterer creates a new log filterer instance of DelayedWithdrawalRouter, bound to a specific deployed contract. -func NewDelayedWithdrawalRouterFilterer(address common.Address, filterer bind.ContractFilterer) (*DelayedWithdrawalRouterFilterer, error) { - contract, err := bindDelayedWithdrawalRouter(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterFilterer{contract: contract}, nil -} - -// bindDelayedWithdrawalRouter binds a generic wrapper to an already deployed contract. -func bindDelayedWithdrawalRouter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := DelayedWithdrawalRouterMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _DelayedWithdrawalRouter.Contract.DelayedWithdrawalRouterCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.DelayedWithdrawalRouterTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.DelayedWithdrawalRouterTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _DelayedWithdrawalRouter.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.contract.Transact(opts, method, params...) -} - -// MAXWITHDRAWALDELAYBLOCKS is a free data retrieval call binding the contract method 0xca661c04. -// -// Solidity: function MAX_WITHDRAWAL_DELAY_BLOCKS() view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) MAXWITHDRAWALDELAYBLOCKS(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "MAX_WITHDRAWAL_DELAY_BLOCKS") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// MAXWITHDRAWALDELAYBLOCKS is a free data retrieval call binding the contract method 0xca661c04. -// -// Solidity: function MAX_WITHDRAWAL_DELAY_BLOCKS() view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) MAXWITHDRAWALDELAYBLOCKS() (*big.Int, error) { - return _DelayedWithdrawalRouter.Contract.MAXWITHDRAWALDELAYBLOCKS(&_DelayedWithdrawalRouter.CallOpts) -} - -// MAXWITHDRAWALDELAYBLOCKS is a free data retrieval call binding the contract method 0xca661c04. -// -// Solidity: function MAX_WITHDRAWAL_DELAY_BLOCKS() view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) MAXWITHDRAWALDELAYBLOCKS() (*big.Int, error) { - return _DelayedWithdrawalRouter.Contract.MAXWITHDRAWALDELAYBLOCKS(&_DelayedWithdrawalRouter.CallOpts) -} - -// CanClaimDelayedWithdrawal is a free data retrieval call binding the contract method 0x75608896. -// -// Solidity: function canClaimDelayedWithdrawal(address user, uint256 index) view returns(bool) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) CanClaimDelayedWithdrawal(opts *bind.CallOpts, user common.Address, index *big.Int) (bool, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "canClaimDelayedWithdrawal", user, index) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// CanClaimDelayedWithdrawal is a free data retrieval call binding the contract method 0x75608896. -// -// Solidity: function canClaimDelayedWithdrawal(address user, uint256 index) view returns(bool) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) CanClaimDelayedWithdrawal(user common.Address, index *big.Int) (bool, error) { - return _DelayedWithdrawalRouter.Contract.CanClaimDelayedWithdrawal(&_DelayedWithdrawalRouter.CallOpts, user, index) -} - -// CanClaimDelayedWithdrawal is a free data retrieval call binding the contract method 0x75608896. -// -// Solidity: function canClaimDelayedWithdrawal(address user, uint256 index) view returns(bool) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) CanClaimDelayedWithdrawal(user common.Address, index *big.Int) (bool, error) { - return _DelayedWithdrawalRouter.Contract.CanClaimDelayedWithdrawal(&_DelayedWithdrawalRouter.CallOpts, user, index) -} - -// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. -// -// Solidity: function eigenPodManager() view returns(address) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) EigenPodManager(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "eigenPodManager") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. -// -// Solidity: function eigenPodManager() view returns(address) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) EigenPodManager() (common.Address, error) { - return _DelayedWithdrawalRouter.Contract.EigenPodManager(&_DelayedWithdrawalRouter.CallOpts) -} - -// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. -// -// Solidity: function eigenPodManager() view returns(address) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) EigenPodManager() (common.Address, error) { - return _DelayedWithdrawalRouter.Contract.EigenPodManager(&_DelayedWithdrawalRouter.CallOpts) -} - -// GetClaimableUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x1f39d87f. -// -// Solidity: function getClaimableUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) GetClaimableUserDelayedWithdrawals(opts *bind.CallOpts, user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "getClaimableUserDelayedWithdrawals", user) - - if err != nil { - return *new([]IDelayedWithdrawalRouterDelayedWithdrawal), err - } - - out0 := *abi.ConvertType(out[0], new([]IDelayedWithdrawalRouterDelayedWithdrawal)).(*[]IDelayedWithdrawalRouterDelayedWithdrawal) - - return out0, err - -} - -// GetClaimableUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x1f39d87f. -// -// Solidity: function getClaimableUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) GetClaimableUserDelayedWithdrawals(user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _DelayedWithdrawalRouter.Contract.GetClaimableUserDelayedWithdrawals(&_DelayedWithdrawalRouter.CallOpts, user) -} - -// GetClaimableUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x1f39d87f. -// -// Solidity: function getClaimableUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) GetClaimableUserDelayedWithdrawals(user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _DelayedWithdrawalRouter.Contract.GetClaimableUserDelayedWithdrawals(&_DelayedWithdrawalRouter.CallOpts, user) -} - -// GetUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x3e1de008. -// -// Solidity: function getUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) GetUserDelayedWithdrawals(opts *bind.CallOpts, user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "getUserDelayedWithdrawals", user) - - if err != nil { - return *new([]IDelayedWithdrawalRouterDelayedWithdrawal), err - } - - out0 := *abi.ConvertType(out[0], new([]IDelayedWithdrawalRouterDelayedWithdrawal)).(*[]IDelayedWithdrawalRouterDelayedWithdrawal) - - return out0, err - -} - -// GetUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x3e1de008. -// -// Solidity: function getUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) GetUserDelayedWithdrawals(user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _DelayedWithdrawalRouter.Contract.GetUserDelayedWithdrawals(&_DelayedWithdrawalRouter.CallOpts, user) -} - -// GetUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x3e1de008. -// -// Solidity: function getUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) GetUserDelayedWithdrawals(user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _DelayedWithdrawalRouter.Contract.GetUserDelayedWithdrawals(&_DelayedWithdrawalRouter.CallOpts, user) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) Owner() (common.Address, error) { - return _DelayedWithdrawalRouter.Contract.Owner(&_DelayedWithdrawalRouter.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) Owner() (common.Address, error) { - return _DelayedWithdrawalRouter.Contract.Owner(&_DelayedWithdrawalRouter.CallOpts) -} - -// Paused is a free data retrieval call binding the contract method 0x5ac86ab7. -// -// Solidity: function paused(uint8 index) view returns(bool) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) Paused(opts *bind.CallOpts, index uint8) (bool, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "paused", index) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// Paused is a free data retrieval call binding the contract method 0x5ac86ab7. -// -// Solidity: function paused(uint8 index) view returns(bool) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) Paused(index uint8) (bool, error) { - return _DelayedWithdrawalRouter.Contract.Paused(&_DelayedWithdrawalRouter.CallOpts, index) -} - -// Paused is a free data retrieval call binding the contract method 0x5ac86ab7. -// -// Solidity: function paused(uint8 index) view returns(bool) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) Paused(index uint8) (bool, error) { - return _DelayedWithdrawalRouter.Contract.Paused(&_DelayedWithdrawalRouter.CallOpts, index) -} - -// Paused0 is a free data retrieval call binding the contract method 0x5c975abb. -// -// Solidity: function paused() view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) Paused0(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "paused0") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Paused0 is a free data retrieval call binding the contract method 0x5c975abb. -// -// Solidity: function paused() view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) Paused0() (*big.Int, error) { - return _DelayedWithdrawalRouter.Contract.Paused0(&_DelayedWithdrawalRouter.CallOpts) -} - -// Paused0 is a free data retrieval call binding the contract method 0x5c975abb. -// -// Solidity: function paused() view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) Paused0() (*big.Int, error) { - return _DelayedWithdrawalRouter.Contract.Paused0(&_DelayedWithdrawalRouter.CallOpts) -} - -// PauserRegistry is a free data retrieval call binding the contract method 0x886f1195. -// -// Solidity: function pauserRegistry() view returns(address) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) PauserRegistry(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "pauserRegistry") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// PauserRegistry is a free data retrieval call binding the contract method 0x886f1195. -// -// Solidity: function pauserRegistry() view returns(address) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) PauserRegistry() (common.Address, error) { - return _DelayedWithdrawalRouter.Contract.PauserRegistry(&_DelayedWithdrawalRouter.CallOpts) -} - -// PauserRegistry is a free data retrieval call binding the contract method 0x886f1195. -// -// Solidity: function pauserRegistry() view returns(address) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) PauserRegistry() (common.Address, error) { - return _DelayedWithdrawalRouter.Contract.PauserRegistry(&_DelayedWithdrawalRouter.CallOpts) -} - -// UserDelayedWithdrawalByIndex is a free data retrieval call binding the contract method 0x85594e58. -// -// Solidity: function userDelayedWithdrawalByIndex(address user, uint256 index) view returns((uint224,uint32)) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) UserDelayedWithdrawalByIndex(opts *bind.CallOpts, user common.Address, index *big.Int) (IDelayedWithdrawalRouterDelayedWithdrawal, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "userDelayedWithdrawalByIndex", user, index) - - if err != nil { - return *new(IDelayedWithdrawalRouterDelayedWithdrawal), err - } - - out0 := *abi.ConvertType(out[0], new(IDelayedWithdrawalRouterDelayedWithdrawal)).(*IDelayedWithdrawalRouterDelayedWithdrawal) - - return out0, err - -} - -// UserDelayedWithdrawalByIndex is a free data retrieval call binding the contract method 0x85594e58. -// -// Solidity: function userDelayedWithdrawalByIndex(address user, uint256 index) view returns((uint224,uint32)) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) UserDelayedWithdrawalByIndex(user common.Address, index *big.Int) (IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _DelayedWithdrawalRouter.Contract.UserDelayedWithdrawalByIndex(&_DelayedWithdrawalRouter.CallOpts, user, index) -} - -// UserDelayedWithdrawalByIndex is a free data retrieval call binding the contract method 0x85594e58. -// -// Solidity: function userDelayedWithdrawalByIndex(address user, uint256 index) view returns((uint224,uint32)) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) UserDelayedWithdrawalByIndex(user common.Address, index *big.Int) (IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _DelayedWithdrawalRouter.Contract.UserDelayedWithdrawalByIndex(&_DelayedWithdrawalRouter.CallOpts, user, index) -} - -// UserWithdrawals is a free data retrieval call binding the contract method 0xecb7cb1b. -// -// Solidity: function userWithdrawals(address user) view returns((uint256,(uint224,uint32)[])) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) UserWithdrawals(opts *bind.CallOpts, user common.Address) (IDelayedWithdrawalRouterUserDelayedWithdrawals, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "userWithdrawals", user) - - if err != nil { - return *new(IDelayedWithdrawalRouterUserDelayedWithdrawals), err - } - - out0 := *abi.ConvertType(out[0], new(IDelayedWithdrawalRouterUserDelayedWithdrawals)).(*IDelayedWithdrawalRouterUserDelayedWithdrawals) - - return out0, err - -} - -// UserWithdrawals is a free data retrieval call binding the contract method 0xecb7cb1b. -// -// Solidity: function userWithdrawals(address user) view returns((uint256,(uint224,uint32)[])) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) UserWithdrawals(user common.Address) (IDelayedWithdrawalRouterUserDelayedWithdrawals, error) { - return _DelayedWithdrawalRouter.Contract.UserWithdrawals(&_DelayedWithdrawalRouter.CallOpts, user) -} - -// UserWithdrawals is a free data retrieval call binding the contract method 0xecb7cb1b. -// -// Solidity: function userWithdrawals(address user) view returns((uint256,(uint224,uint32)[])) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) UserWithdrawals(user common.Address) (IDelayedWithdrawalRouterUserDelayedWithdrawals, error) { - return _DelayedWithdrawalRouter.Contract.UserWithdrawals(&_DelayedWithdrawalRouter.CallOpts, user) -} - -// UserWithdrawalsLength is a free data retrieval call binding the contract method 0xe4f4f887. -// -// Solidity: function userWithdrawalsLength(address user) view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) UserWithdrawalsLength(opts *bind.CallOpts, user common.Address) (*big.Int, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "userWithdrawalsLength", user) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// UserWithdrawalsLength is a free data retrieval call binding the contract method 0xe4f4f887. -// -// Solidity: function userWithdrawalsLength(address user) view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) UserWithdrawalsLength(user common.Address) (*big.Int, error) { - return _DelayedWithdrawalRouter.Contract.UserWithdrawalsLength(&_DelayedWithdrawalRouter.CallOpts, user) -} - -// UserWithdrawalsLength is a free data retrieval call binding the contract method 0xe4f4f887. -// -// Solidity: function userWithdrawalsLength(address user) view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) UserWithdrawalsLength(user common.Address) (*big.Int, error) { - return _DelayedWithdrawalRouter.Contract.UserWithdrawalsLength(&_DelayedWithdrawalRouter.CallOpts, user) -} - -// WithdrawalDelayBlocks is a free data retrieval call binding the contract method 0x50f73e7c. -// -// Solidity: function withdrawalDelayBlocks() view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCaller) WithdrawalDelayBlocks(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _DelayedWithdrawalRouter.contract.Call(opts, &out, "withdrawalDelayBlocks") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// WithdrawalDelayBlocks is a free data retrieval call binding the contract method 0x50f73e7c. -// -// Solidity: function withdrawalDelayBlocks() view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) WithdrawalDelayBlocks() (*big.Int, error) { - return _DelayedWithdrawalRouter.Contract.WithdrawalDelayBlocks(&_DelayedWithdrawalRouter.CallOpts) -} - -// WithdrawalDelayBlocks is a free data retrieval call binding the contract method 0x50f73e7c. -// -// Solidity: function withdrawalDelayBlocks() view returns(uint256) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterCallerSession) WithdrawalDelayBlocks() (*big.Int, error) { - return _DelayedWithdrawalRouter.Contract.WithdrawalDelayBlocks(&_DelayedWithdrawalRouter.CallOpts) -} - -// ClaimDelayedWithdrawals is a paid mutator transaction binding the contract method 0xd44e1b76. -// -// Solidity: function claimDelayedWithdrawals(uint256 maxNumberOfDelayedWithdrawalsToClaim) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) ClaimDelayedWithdrawals(opts *bind.TransactOpts, maxNumberOfDelayedWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "claimDelayedWithdrawals", maxNumberOfDelayedWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals is a paid mutator transaction binding the contract method 0xd44e1b76. -// -// Solidity: function claimDelayedWithdrawals(uint256 maxNumberOfDelayedWithdrawalsToClaim) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) ClaimDelayedWithdrawals(maxNumberOfDelayedWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.ClaimDelayedWithdrawals(&_DelayedWithdrawalRouter.TransactOpts, maxNumberOfDelayedWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals is a paid mutator transaction binding the contract method 0xd44e1b76. -// -// Solidity: function claimDelayedWithdrawals(uint256 maxNumberOfDelayedWithdrawalsToClaim) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) ClaimDelayedWithdrawals(maxNumberOfDelayedWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.ClaimDelayedWithdrawals(&_DelayedWithdrawalRouter.TransactOpts, maxNumberOfDelayedWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals0 is a paid mutator transaction binding the contract method 0xe5db06c0. -// -// Solidity: function claimDelayedWithdrawals(address recipient, uint256 maxNumberOfDelayedWithdrawalsToClaim) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) ClaimDelayedWithdrawals0(opts *bind.TransactOpts, recipient common.Address, maxNumberOfDelayedWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "claimDelayedWithdrawals0", recipient, maxNumberOfDelayedWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals0 is a paid mutator transaction binding the contract method 0xe5db06c0. -// -// Solidity: function claimDelayedWithdrawals(address recipient, uint256 maxNumberOfDelayedWithdrawalsToClaim) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) ClaimDelayedWithdrawals0(recipient common.Address, maxNumberOfDelayedWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.ClaimDelayedWithdrawals0(&_DelayedWithdrawalRouter.TransactOpts, recipient, maxNumberOfDelayedWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals0 is a paid mutator transaction binding the contract method 0xe5db06c0. -// -// Solidity: function claimDelayedWithdrawals(address recipient, uint256 maxNumberOfDelayedWithdrawalsToClaim) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) ClaimDelayedWithdrawals0(recipient common.Address, maxNumberOfDelayedWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.ClaimDelayedWithdrawals0(&_DelayedWithdrawalRouter.TransactOpts, recipient, maxNumberOfDelayedWithdrawalsToClaim) -} - -// CreateDelayedWithdrawal is a paid mutator transaction binding the contract method 0xc0db354c. -// -// Solidity: function createDelayedWithdrawal(address podOwner, address recipient) payable returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) CreateDelayedWithdrawal(opts *bind.TransactOpts, podOwner common.Address, recipient common.Address) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "createDelayedWithdrawal", podOwner, recipient) -} - -// CreateDelayedWithdrawal is a paid mutator transaction binding the contract method 0xc0db354c. -// -// Solidity: function createDelayedWithdrawal(address podOwner, address recipient) payable returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) CreateDelayedWithdrawal(podOwner common.Address, recipient common.Address) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.CreateDelayedWithdrawal(&_DelayedWithdrawalRouter.TransactOpts, podOwner, recipient) -} - -// CreateDelayedWithdrawal is a paid mutator transaction binding the contract method 0xc0db354c. -// -// Solidity: function createDelayedWithdrawal(address podOwner, address recipient) payable returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) CreateDelayedWithdrawal(podOwner common.Address, recipient common.Address) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.CreateDelayedWithdrawal(&_DelayedWithdrawalRouter.TransactOpts, podOwner, recipient) -} - -// Initialize is a paid mutator transaction binding the contract method 0xeb990c59. -// -// Solidity: function initialize(address initOwner, address _pauserRegistry, uint256 initPausedStatus, uint256 _withdrawalDelayBlocks) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) Initialize(opts *bind.TransactOpts, initOwner common.Address, _pauserRegistry common.Address, initPausedStatus *big.Int, _withdrawalDelayBlocks *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "initialize", initOwner, _pauserRegistry, initPausedStatus, _withdrawalDelayBlocks) -} - -// Initialize is a paid mutator transaction binding the contract method 0xeb990c59. -// -// Solidity: function initialize(address initOwner, address _pauserRegistry, uint256 initPausedStatus, uint256 _withdrawalDelayBlocks) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) Initialize(initOwner common.Address, _pauserRegistry common.Address, initPausedStatus *big.Int, _withdrawalDelayBlocks *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.Initialize(&_DelayedWithdrawalRouter.TransactOpts, initOwner, _pauserRegistry, initPausedStatus, _withdrawalDelayBlocks) -} - -// Initialize is a paid mutator transaction binding the contract method 0xeb990c59. -// -// Solidity: function initialize(address initOwner, address _pauserRegistry, uint256 initPausedStatus, uint256 _withdrawalDelayBlocks) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) Initialize(initOwner common.Address, _pauserRegistry common.Address, initPausedStatus *big.Int, _withdrawalDelayBlocks *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.Initialize(&_DelayedWithdrawalRouter.TransactOpts, initOwner, _pauserRegistry, initPausedStatus, _withdrawalDelayBlocks) -} - -// Pause is a paid mutator transaction binding the contract method 0x136439dd. -// -// Solidity: function pause(uint256 newPausedStatus) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) Pause(opts *bind.TransactOpts, newPausedStatus *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "pause", newPausedStatus) -} - -// Pause is a paid mutator transaction binding the contract method 0x136439dd. -// -// Solidity: function pause(uint256 newPausedStatus) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) Pause(newPausedStatus *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.Pause(&_DelayedWithdrawalRouter.TransactOpts, newPausedStatus) -} - -// Pause is a paid mutator transaction binding the contract method 0x136439dd. -// -// Solidity: function pause(uint256 newPausedStatus) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) Pause(newPausedStatus *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.Pause(&_DelayedWithdrawalRouter.TransactOpts, newPausedStatus) -} - -// PauseAll is a paid mutator transaction binding the contract method 0x595c6a67. -// -// Solidity: function pauseAll() returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) PauseAll(opts *bind.TransactOpts) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "pauseAll") -} - -// PauseAll is a paid mutator transaction binding the contract method 0x595c6a67. -// -// Solidity: function pauseAll() returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) PauseAll() (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.PauseAll(&_DelayedWithdrawalRouter.TransactOpts) -} - -// PauseAll is a paid mutator transaction binding the contract method 0x595c6a67. -// -// Solidity: function pauseAll() returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) PauseAll() (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.PauseAll(&_DelayedWithdrawalRouter.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) RenounceOwnership() (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.RenounceOwnership(&_DelayedWithdrawalRouter.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.RenounceOwnership(&_DelayedWithdrawalRouter.TransactOpts) -} - -// SetPauserRegistry is a paid mutator transaction binding the contract method 0x10d67a2f. -// -// Solidity: function setPauserRegistry(address newPauserRegistry) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) SetPauserRegistry(opts *bind.TransactOpts, newPauserRegistry common.Address) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "setPauserRegistry", newPauserRegistry) -} - -// SetPauserRegistry is a paid mutator transaction binding the contract method 0x10d67a2f. -// -// Solidity: function setPauserRegistry(address newPauserRegistry) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) SetPauserRegistry(newPauserRegistry common.Address) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.SetPauserRegistry(&_DelayedWithdrawalRouter.TransactOpts, newPauserRegistry) -} - -// SetPauserRegistry is a paid mutator transaction binding the contract method 0x10d67a2f. -// -// Solidity: function setPauserRegistry(address newPauserRegistry) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) SetPauserRegistry(newPauserRegistry common.Address) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.SetPauserRegistry(&_DelayedWithdrawalRouter.TransactOpts, newPauserRegistry) -} - -// SetWithdrawalDelayBlocks is a paid mutator transaction binding the contract method 0x4d50f9a4. -// -// Solidity: function setWithdrawalDelayBlocks(uint256 newValue) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) SetWithdrawalDelayBlocks(opts *bind.TransactOpts, newValue *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "setWithdrawalDelayBlocks", newValue) -} - -// SetWithdrawalDelayBlocks is a paid mutator transaction binding the contract method 0x4d50f9a4. -// -// Solidity: function setWithdrawalDelayBlocks(uint256 newValue) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) SetWithdrawalDelayBlocks(newValue *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.SetWithdrawalDelayBlocks(&_DelayedWithdrawalRouter.TransactOpts, newValue) -} - -// SetWithdrawalDelayBlocks is a paid mutator transaction binding the contract method 0x4d50f9a4. -// -// Solidity: function setWithdrawalDelayBlocks(uint256 newValue) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) SetWithdrawalDelayBlocks(newValue *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.SetWithdrawalDelayBlocks(&_DelayedWithdrawalRouter.TransactOpts, newValue) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "transferOwnership", newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.TransferOwnership(&_DelayedWithdrawalRouter.TransactOpts, newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.TransferOwnership(&_DelayedWithdrawalRouter.TransactOpts, newOwner) -} - -// Unpause is a paid mutator transaction binding the contract method 0xfabc1cbc. -// -// Solidity: function unpause(uint256 newPausedStatus) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactor) Unpause(opts *bind.TransactOpts, newPausedStatus *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.contract.Transact(opts, "unpause", newPausedStatus) -} - -// Unpause is a paid mutator transaction binding the contract method 0xfabc1cbc. -// -// Solidity: function unpause(uint256 newPausedStatus) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterSession) Unpause(newPausedStatus *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.Unpause(&_DelayedWithdrawalRouter.TransactOpts, newPausedStatus) -} - -// Unpause is a paid mutator transaction binding the contract method 0xfabc1cbc. -// -// Solidity: function unpause(uint256 newPausedStatus) returns() -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterTransactorSession) Unpause(newPausedStatus *big.Int) (*types.Transaction, error) { - return _DelayedWithdrawalRouter.Contract.Unpause(&_DelayedWithdrawalRouter.TransactOpts, newPausedStatus) -} - -// DelayedWithdrawalRouterDelayedWithdrawalCreatedIterator is returned from FilterDelayedWithdrawalCreated and is used to iterate over the raw logs and unpacked data for DelayedWithdrawalCreated events raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterDelayedWithdrawalCreatedIterator struct { - Event *DelayedWithdrawalRouterDelayedWithdrawalCreated // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *DelayedWithdrawalRouterDelayedWithdrawalCreatedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterDelayedWithdrawalCreated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterDelayedWithdrawalCreated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *DelayedWithdrawalRouterDelayedWithdrawalCreatedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *DelayedWithdrawalRouterDelayedWithdrawalCreatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// DelayedWithdrawalRouterDelayedWithdrawalCreated represents a DelayedWithdrawalCreated event raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterDelayedWithdrawalCreated struct { - PodOwner common.Address - Recipient common.Address - Amount *big.Int - Index *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDelayedWithdrawalCreated is a free log retrieval operation binding the contract event 0xb8f1b14c7caf74150801dcc9bc18d575cbeaf5b421943497e409df92c92e0f59. -// -// Solidity: event DelayedWithdrawalCreated(address podOwner, address recipient, uint256 amount, uint256 index) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) FilterDelayedWithdrawalCreated(opts *bind.FilterOpts) (*DelayedWithdrawalRouterDelayedWithdrawalCreatedIterator, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.FilterLogs(opts, "DelayedWithdrawalCreated") - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterDelayedWithdrawalCreatedIterator{contract: _DelayedWithdrawalRouter.contract, event: "DelayedWithdrawalCreated", logs: logs, sub: sub}, nil -} - -// WatchDelayedWithdrawalCreated is a free log subscription operation binding the contract event 0xb8f1b14c7caf74150801dcc9bc18d575cbeaf5b421943497e409df92c92e0f59. -// -// Solidity: event DelayedWithdrawalCreated(address podOwner, address recipient, uint256 amount, uint256 index) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) WatchDelayedWithdrawalCreated(opts *bind.WatchOpts, sink chan<- *DelayedWithdrawalRouterDelayedWithdrawalCreated) (event.Subscription, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.WatchLogs(opts, "DelayedWithdrawalCreated") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(DelayedWithdrawalRouterDelayedWithdrawalCreated) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "DelayedWithdrawalCreated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseDelayedWithdrawalCreated is a log parse operation binding the contract event 0xb8f1b14c7caf74150801dcc9bc18d575cbeaf5b421943497e409df92c92e0f59. -// -// Solidity: event DelayedWithdrawalCreated(address podOwner, address recipient, uint256 amount, uint256 index) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) ParseDelayedWithdrawalCreated(log types.Log) (*DelayedWithdrawalRouterDelayedWithdrawalCreated, error) { - event := new(DelayedWithdrawalRouterDelayedWithdrawalCreated) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "DelayedWithdrawalCreated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// DelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator is returned from FilterDelayedWithdrawalsClaimed and is used to iterate over the raw logs and unpacked data for DelayedWithdrawalsClaimed events raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator struct { - Event *DelayedWithdrawalRouterDelayedWithdrawalsClaimed // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *DelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterDelayedWithdrawalsClaimed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterDelayedWithdrawalsClaimed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *DelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *DelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// DelayedWithdrawalRouterDelayedWithdrawalsClaimed represents a DelayedWithdrawalsClaimed event raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterDelayedWithdrawalsClaimed struct { - Recipient common.Address - AmountClaimed *big.Int - DelayedWithdrawalsCompleted *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDelayedWithdrawalsClaimed is a free log retrieval operation binding the contract event 0x6b7151500bd0b5cc211bcc47b3029831b769004df4549e8e1c9a69da05bb0943. -// -// Solidity: event DelayedWithdrawalsClaimed(address recipient, uint256 amountClaimed, uint256 delayedWithdrawalsCompleted) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) FilterDelayedWithdrawalsClaimed(opts *bind.FilterOpts) (*DelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.FilterLogs(opts, "DelayedWithdrawalsClaimed") - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator{contract: _DelayedWithdrawalRouter.contract, event: "DelayedWithdrawalsClaimed", logs: logs, sub: sub}, nil -} - -// WatchDelayedWithdrawalsClaimed is a free log subscription operation binding the contract event 0x6b7151500bd0b5cc211bcc47b3029831b769004df4549e8e1c9a69da05bb0943. -// -// Solidity: event DelayedWithdrawalsClaimed(address recipient, uint256 amountClaimed, uint256 delayedWithdrawalsCompleted) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) WatchDelayedWithdrawalsClaimed(opts *bind.WatchOpts, sink chan<- *DelayedWithdrawalRouterDelayedWithdrawalsClaimed) (event.Subscription, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.WatchLogs(opts, "DelayedWithdrawalsClaimed") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(DelayedWithdrawalRouterDelayedWithdrawalsClaimed) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "DelayedWithdrawalsClaimed", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseDelayedWithdrawalsClaimed is a log parse operation binding the contract event 0x6b7151500bd0b5cc211bcc47b3029831b769004df4549e8e1c9a69da05bb0943. -// -// Solidity: event DelayedWithdrawalsClaimed(address recipient, uint256 amountClaimed, uint256 delayedWithdrawalsCompleted) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) ParseDelayedWithdrawalsClaimed(log types.Log) (*DelayedWithdrawalRouterDelayedWithdrawalsClaimed, error) { - event := new(DelayedWithdrawalRouterDelayedWithdrawalsClaimed) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "DelayedWithdrawalsClaimed", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// DelayedWithdrawalRouterInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterInitializedIterator struct { - Event *DelayedWithdrawalRouterInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *DelayedWithdrawalRouterInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *DelayedWithdrawalRouterInitializedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *DelayedWithdrawalRouterInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// DelayedWithdrawalRouterInitialized represents a Initialized event raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) FilterInitialized(opts *bind.FilterOpts) (*DelayedWithdrawalRouterInitializedIterator, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.FilterLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterInitializedIterator{contract: _DelayedWithdrawalRouter.contract, event: "Initialized", logs: logs, sub: sub}, nil -} - -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *DelayedWithdrawalRouterInitialized) (event.Subscription, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.WatchLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(DelayedWithdrawalRouterInitialized) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) ParseInitialized(log types.Log) (*DelayedWithdrawalRouterInitialized, error) { - event := new(DelayedWithdrawalRouterInitialized) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "Initialized", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// DelayedWithdrawalRouterOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterOwnershipTransferredIterator struct { - Event *DelayedWithdrawalRouterOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *DelayedWithdrawalRouterOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *DelayedWithdrawalRouterOwnershipTransferredIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *DelayedWithdrawalRouterOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// DelayedWithdrawalRouterOwnershipTransferred represents a OwnershipTransferred event raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*DelayedWithdrawalRouterOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _DelayedWithdrawalRouter.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterOwnershipTransferredIterator{contract: _DelayedWithdrawalRouter.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DelayedWithdrawalRouterOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _DelayedWithdrawalRouter.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(DelayedWithdrawalRouterOwnershipTransferred) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) ParseOwnershipTransferred(log types.Log) (*DelayedWithdrawalRouterOwnershipTransferred, error) { - event := new(DelayedWithdrawalRouterOwnershipTransferred) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// DelayedWithdrawalRouterPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterPausedIterator struct { - Event *DelayedWithdrawalRouterPaused // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *DelayedWithdrawalRouterPausedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterPaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterPaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *DelayedWithdrawalRouterPausedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *DelayedWithdrawalRouterPausedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// DelayedWithdrawalRouterPaused represents a Paused event raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterPaused struct { - Account common.Address - NewPausedStatus *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterPaused is a free log retrieval operation binding the contract event 0xab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d. -// -// Solidity: event Paused(address indexed account, uint256 newPausedStatus) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) FilterPaused(opts *bind.FilterOpts, account []common.Address) (*DelayedWithdrawalRouterPausedIterator, error) { - - var accountRule []interface{} - for _, accountItem := range account { - accountRule = append(accountRule, accountItem) - } - - logs, sub, err := _DelayedWithdrawalRouter.contract.FilterLogs(opts, "Paused", accountRule) - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterPausedIterator{contract: _DelayedWithdrawalRouter.contract, event: "Paused", logs: logs, sub: sub}, nil -} - -// WatchPaused is a free log subscription operation binding the contract event 0xab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d. -// -// Solidity: event Paused(address indexed account, uint256 newPausedStatus) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *DelayedWithdrawalRouterPaused, account []common.Address) (event.Subscription, error) { - - var accountRule []interface{} - for _, accountItem := range account { - accountRule = append(accountRule, accountItem) - } - - logs, sub, err := _DelayedWithdrawalRouter.contract.WatchLogs(opts, "Paused", accountRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(DelayedWithdrawalRouterPaused) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "Paused", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParsePaused is a log parse operation binding the contract event 0xab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d. -// -// Solidity: event Paused(address indexed account, uint256 newPausedStatus) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) ParsePaused(log types.Log) (*DelayedWithdrawalRouterPaused, error) { - event := new(DelayedWithdrawalRouterPaused) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "Paused", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// DelayedWithdrawalRouterPauserRegistrySetIterator is returned from FilterPauserRegistrySet and is used to iterate over the raw logs and unpacked data for PauserRegistrySet events raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterPauserRegistrySetIterator struct { - Event *DelayedWithdrawalRouterPauserRegistrySet // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *DelayedWithdrawalRouterPauserRegistrySetIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterPauserRegistrySet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterPauserRegistrySet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *DelayedWithdrawalRouterPauserRegistrySetIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *DelayedWithdrawalRouterPauserRegistrySetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// DelayedWithdrawalRouterPauserRegistrySet represents a PauserRegistrySet event raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterPauserRegistrySet struct { - PauserRegistry common.Address - NewPauserRegistry common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterPauserRegistrySet is a free log retrieval operation binding the contract event 0x6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6. -// -// Solidity: event PauserRegistrySet(address pauserRegistry, address newPauserRegistry) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) FilterPauserRegistrySet(opts *bind.FilterOpts) (*DelayedWithdrawalRouterPauserRegistrySetIterator, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.FilterLogs(opts, "PauserRegistrySet") - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterPauserRegistrySetIterator{contract: _DelayedWithdrawalRouter.contract, event: "PauserRegistrySet", logs: logs, sub: sub}, nil -} - -// WatchPauserRegistrySet is a free log subscription operation binding the contract event 0x6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6. -// -// Solidity: event PauserRegistrySet(address pauserRegistry, address newPauserRegistry) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) WatchPauserRegistrySet(opts *bind.WatchOpts, sink chan<- *DelayedWithdrawalRouterPauserRegistrySet) (event.Subscription, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.WatchLogs(opts, "PauserRegistrySet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(DelayedWithdrawalRouterPauserRegistrySet) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "PauserRegistrySet", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParsePauserRegistrySet is a log parse operation binding the contract event 0x6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6. -// -// Solidity: event PauserRegistrySet(address pauserRegistry, address newPauserRegistry) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) ParsePauserRegistrySet(log types.Log) (*DelayedWithdrawalRouterPauserRegistrySet, error) { - event := new(DelayedWithdrawalRouterPauserRegistrySet) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "PauserRegistrySet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// DelayedWithdrawalRouterUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterUnpausedIterator struct { - Event *DelayedWithdrawalRouterUnpaused // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *DelayedWithdrawalRouterUnpausedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterUnpaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterUnpaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *DelayedWithdrawalRouterUnpausedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *DelayedWithdrawalRouterUnpausedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// DelayedWithdrawalRouterUnpaused represents a Unpaused event raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterUnpaused struct { - Account common.Address - NewPausedStatus *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUnpaused is a free log retrieval operation binding the contract event 0x3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c. -// -// Solidity: event Unpaused(address indexed account, uint256 newPausedStatus) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) FilterUnpaused(opts *bind.FilterOpts, account []common.Address) (*DelayedWithdrawalRouterUnpausedIterator, error) { - - var accountRule []interface{} - for _, accountItem := range account { - accountRule = append(accountRule, accountItem) - } - - logs, sub, err := _DelayedWithdrawalRouter.contract.FilterLogs(opts, "Unpaused", accountRule) - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterUnpausedIterator{contract: _DelayedWithdrawalRouter.contract, event: "Unpaused", logs: logs, sub: sub}, nil -} - -// WatchUnpaused is a free log subscription operation binding the contract event 0x3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c. -// -// Solidity: event Unpaused(address indexed account, uint256 newPausedStatus) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *DelayedWithdrawalRouterUnpaused, account []common.Address) (event.Subscription, error) { - - var accountRule []interface{} - for _, accountItem := range account { - accountRule = append(accountRule, accountItem) - } - - logs, sub, err := _DelayedWithdrawalRouter.contract.WatchLogs(opts, "Unpaused", accountRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(DelayedWithdrawalRouterUnpaused) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "Unpaused", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUnpaused is a log parse operation binding the contract event 0x3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c. -// -// Solidity: event Unpaused(address indexed account, uint256 newPausedStatus) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) ParseUnpaused(log types.Log) (*DelayedWithdrawalRouterUnpaused, error) { - event := new(DelayedWithdrawalRouterUnpaused) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "Unpaused", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// DelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator is returned from FilterWithdrawalDelayBlocksSet and is used to iterate over the raw logs and unpacked data for WithdrawalDelayBlocksSet events raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator struct { - Event *DelayedWithdrawalRouterWithdrawalDelayBlocksSet // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *DelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterWithdrawalDelayBlocksSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(DelayedWithdrawalRouterWithdrawalDelayBlocksSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *DelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *DelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// DelayedWithdrawalRouterWithdrawalDelayBlocksSet represents a WithdrawalDelayBlocksSet event raised by the DelayedWithdrawalRouter contract. -type DelayedWithdrawalRouterWithdrawalDelayBlocksSet struct { - PreviousValue *big.Int - NewValue *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterWithdrawalDelayBlocksSet is a free log retrieval operation binding the contract event 0x4ffb00400574147429ee377a5633386321e66d45d8b14676014b5fa393e61e9e. -// -// Solidity: event WithdrawalDelayBlocksSet(uint256 previousValue, uint256 newValue) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) FilterWithdrawalDelayBlocksSet(opts *bind.FilterOpts) (*DelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.FilterLogs(opts, "WithdrawalDelayBlocksSet") - if err != nil { - return nil, err - } - return &DelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator{contract: _DelayedWithdrawalRouter.contract, event: "WithdrawalDelayBlocksSet", logs: logs, sub: sub}, nil -} - -// WatchWithdrawalDelayBlocksSet is a free log subscription operation binding the contract event 0x4ffb00400574147429ee377a5633386321e66d45d8b14676014b5fa393e61e9e. -// -// Solidity: event WithdrawalDelayBlocksSet(uint256 previousValue, uint256 newValue) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) WatchWithdrawalDelayBlocksSet(opts *bind.WatchOpts, sink chan<- *DelayedWithdrawalRouterWithdrawalDelayBlocksSet) (event.Subscription, error) { - - logs, sub, err := _DelayedWithdrawalRouter.contract.WatchLogs(opts, "WithdrawalDelayBlocksSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(DelayedWithdrawalRouterWithdrawalDelayBlocksSet) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "WithdrawalDelayBlocksSet", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseWithdrawalDelayBlocksSet is a log parse operation binding the contract event 0x4ffb00400574147429ee377a5633386321e66d45d8b14676014b5fa393e61e9e. -// -// Solidity: event WithdrawalDelayBlocksSet(uint256 previousValue, uint256 newValue) -func (_DelayedWithdrawalRouter *DelayedWithdrawalRouterFilterer) ParseWithdrawalDelayBlocksSet(log types.Log) (*DelayedWithdrawalRouterWithdrawalDelayBlocksSet, error) { - event := new(DelayedWithdrawalRouterWithdrawalDelayBlocksSet) - if err := _DelayedWithdrawalRouter.contract.UnpackLog(event, "WithdrawalDelayBlocksSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/pkg/bindings/DelegationManager/binding.go b/pkg/bindings/DelegationManager/binding.go index 46c335b3f..cf241371c 100644 --- a/pkg/bindings/DelegationManager/binding.go +++ b/pkg/bindings/DelegationManager/binding.go @@ -63,7 +63,7 @@ type ISignatureUtilsSignatureWithExpiry struct { // DelegationManagerMetaData contains all meta data concerning the DelegationManager contract. var DelegationManagerMetaData = &bind.MetaData{ ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_strategyManager\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"},{\"name\":\"_slasher\",\"type\":\"address\",\"internalType\":\"contractISlasher\"},{\"name\":\"_eigenPodManager\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"DELEGATION_APPROVAL_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DOMAIN_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_STAKER_OPT_OUT_WINDOW_BLOCKS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_WITHDRAWAL_DELAY_BLOCKS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"STAKER_DELEGATION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateCurrentStakerDelegationDigestHash\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateDelegationApprovalDigestHash\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_delegationApprover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"approverSalt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateStakerDelegationDigestHash\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_stakerNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateWithdrawalRoot\",\"inputs\":[{\"name\":\"withdrawal\",\"type\":\"tuple\",\"internalType\":\"structIDelegationManager.Withdrawal\",\"components\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delegatedTo\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"strategies\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"shares\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"completeQueuedWithdrawal\",\"inputs\":[{\"name\":\"withdrawal\",\"type\":\"tuple\",\"internalType\":\"structIDelegationManager.Withdrawal\",\"components\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delegatedTo\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"strategies\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"shares\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}]},{\"name\":\"tokens\",\"type\":\"address[]\",\"internalType\":\"contractIERC20[]\"},{\"name\":\"middlewareTimesIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"receiveAsTokens\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeQueuedWithdrawals\",\"inputs\":[{\"name\":\"withdrawals\",\"type\":\"tuple[]\",\"internalType\":\"structIDelegationManager.Withdrawal[]\",\"components\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delegatedTo\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"strategies\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"shares\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}]},{\"name\":\"tokens\",\"type\":\"address[][]\",\"internalType\":\"contractIERC20[][]\"},{\"name\":\"middlewareTimesIndexes\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"receiveAsTokens\",\"type\":\"bool[]\",\"internalType\":\"bool[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"cumulativeWithdrawalsQueued\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"decreaseDelegatedShares\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegateTo\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"approverSignatureAndExpiry\",\"type\":\"tuple\",\"internalType\":\"structISignatureUtils.SignatureWithExpiry\",\"components\":[{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"approverSalt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegateToBySignature\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"stakerSignatureAndExpiry\",\"type\":\"tuple\",\"internalType\":\"structISignatureUtils.SignatureWithExpiry\",\"components\":[{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"approverSignatureAndExpiry\",\"type\":\"tuple\",\"internalType\":\"structISignatureUtils.SignatureWithExpiry\",\"components\":[{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"approverSalt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegatedTo\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"delegationApprover\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"delegationApproverSaltIsSpent\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getDelegatableShares\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getOperatorShares\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategies\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getWithdrawalDelay\",\"inputs\":[{\"name\":\"strategies\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"increaseDelegatedShares\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"initialPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minWithdrawalDelayBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_strategies\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"_withdrawalDelayBlocks\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isDelegated\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperator\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"minWithdrawalDelayBlocks\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"modifyOperatorDetails\",\"inputs\":[{\"name\":\"newOperatorDetails\",\"type\":\"tuple\",\"internalType\":\"structIDelegationManager.OperatorDetails\",\"components\":[{\"name\":\"__deprecated_earningsReceiver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delegationApprover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"stakerOptOutWindowBlocks\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"operatorDetails\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIDelegationManager.OperatorDetails\",\"components\":[{\"name\":\"__deprecated_earningsReceiver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delegationApprover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"stakerOptOutWindowBlocks\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"operatorShares\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingWithdrawals\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"queueWithdrawals\",\"inputs\":[{\"name\":\"queuedWithdrawalParams\",\"type\":\"tuple[]\",\"internalType\":\"structIDelegationManager.QueuedWithdrawalParams[]\",\"components\":[{\"name\":\"strategies\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"shares\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"registerAsOperator\",\"inputs\":[{\"name\":\"registeringOperatorDetails\",\"type\":\"tuple\",\"internalType\":\"structIDelegationManager.OperatorDetails\",\"components\":[{\"name\":\"__deprecated_earningsReceiver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delegationApprover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"stakerOptOutWindowBlocks\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMinWithdrawalDelayBlocks\",\"inputs\":[{\"name\":\"newMinWithdrawalDelayBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setStrategyWithdrawalDelayBlocks\",\"inputs\":[{\"name\":\"strategies\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"withdrawalDelayBlocks\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slasher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISlasher\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stakerNonce\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stakerOptOutWindowBlocks\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"strategyWithdrawalDelayBlocks\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"undelegate\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"withdrawalRoots\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateOperatorMetadataURI\",\"inputs\":[{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinWithdrawalDelayBlocksSet\",\"inputs\":[{\"name\":\"previousValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OperatorDetailsModified\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOperatorDetails\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIDelegationManager.OperatorDetails\",\"components\":[{\"name\":\"__deprecated_earningsReceiver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delegationApprover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"stakerOptOutWindowBlocks\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OperatorMetadataURIUpdated\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OperatorRegistered\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"operatorDetails\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIDelegationManager.OperatorDetails\",\"components\":[{\"name\":\"__deprecated_earningsReceiver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delegationApprover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"stakerOptOutWindowBlocks\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OperatorSharesDecreased\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"staker\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIStrategy\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OperatorSharesIncreased\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"staker\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIStrategy\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StakerDelegated\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StakerForceUndelegated\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StakerUndelegated\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StrategyWithdrawalDelayBlocksSet\",\"inputs\":[{\"name\":\"strategy\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIStrategy\"},{\"name\":\"previousValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalCompleted\",\"inputs\":[{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalQueued\",\"inputs\":[{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"withdrawal\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIDelegationManager.Withdrawal\",\"components\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delegatedTo\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"strategies\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"shares\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}]}],\"anonymous\":false}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162005c4638038062005c46833981016040819052620000359162000140565b6001600160a01b0380841660805280821660c052821660a0526200005862000065565b50504660e0525062000194565b600054610100900460ff1615620000d25760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000125576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b03811681146200013d57600080fd5b50565b6000806000606084860312156200015657600080fd5b8351620001638162000127565b6020850151909350620001768162000127565b6040850151909250620001898162000127565b809150509250925092565b60805160a05160c05160e051615a1d6200022960003960006126a00152600081816105b10152818161102e015281816113aa01528181611c23015281816129f901528181613eac0152614398015260006107620152600081816104f901528181610ffc0152818161137801528181611cb701528181612ac601528181612c4901528181613fd2015261443e0152615a1d6000f3fe608060405234801561001057600080fd5b50600436106103425760003560e01c8063635bbd10116101b8578063b7f06ebe11610104578063cf80873e116100a2578063f16172b01161007c578063f16172b014610908578063f2fde38b1461091b578063f698da251461092e578063fabc1cbc1461093657600080fd5b8063cf80873e146108c1578063da8be864146108e2578063eea9064b146108f557600080fd5b8063c488375a116100de578063c488375a146107de578063c5e480db146107fe578063c94b5111146108a4578063ca661c04146108b757600080fd5b8063b7f06ebe14610784578063bb45fef2146107a7578063c448feb8146107d557600080fd5b8063886f1195116101715780639104c3191161014b5780639104c3191461070f57806399be81c81461072a578063a17884841461073d578063b13442711461075d57600080fd5b8063886f1195146106cb5780638da5cb5b146106de57806390041347146106ef57600080fd5b8063635bbd101461063657806365da1264146106495780636d70f7ae14610672578063715018a614610685578063778e55f31461068d5780637f548071146106b857600080fd5b806328a573ae116102925780634665bcda11610230578063597b36da1161020a578063597b36da146105e55780635ac86ab7146105f85780635c975abb1461061b57806360d7faed1461062357600080fd5b80634665bcda146105ac5780634fc40b61146105d3578063595c6a67146105dd57600080fd5b806339b70e381161026c57806339b70e38146104f45780633cdeb5e0146105335780633e28391d14610562578063433773821461058557600080fd5b806328a573ae146104ae57806329c77d4f146104c157806333404396146104e157600080fd5b8063132d4967116102ff57806316928365116102d957806316928365146104285780631bbce0911461046157806320606b701461047457806322bf40e41461049b57600080fd5b8063132d4967146103ef578063136439dd146104025780631522bf021461041557600080fd5b80630449ca391461034757806304a4f9791461036d5780630b9f487a146103945780630dd8dd02146103a75780630f589e59146103c757806310d67a2f146103dc575b600080fd5b61035a61035536600461484e565b610949565b6040519081526020015b60405180910390f35b61035a7f14bde674c9f64b2ad00eaaee4a8bed1fabef35c7507e3c5b9cfc9436909a2dad81565b61035a6103a23660046148b4565b6109ce565b6103ba6103b536600461484e565b610a90565b604051610364919061490f565b6103da6103d53660046149ac565b610df9565b005b6103da6103ea3660046149ff565b610f3e565b6103da6103fd366004614a23565b610ff1565b6103da610410366004614a64565b6110a8565b6103da610423366004614a7d565b6111e7565b61035a6104363660046149ff565b6001600160a01b0316600090815260996020526040902060010154600160a01b900463ffffffff1690565b61035a61046f366004614a23565b6111fb565b61035a7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6103da6104a9366004614ae8565b611229565b6103da6104bc366004614a23565b61136d565b61035a6104cf3660046149ff565b609b6020526000908152604090205481565b6103da6104ef366004614b8f565b61141d565b61051b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610364565b61051b6105413660046149ff565b6001600160a01b039081166000908152609960205260409020600101541690565b6105756105703660046149ff565b61155a565b6040519015158152602001610364565b61035a7f39111bc4a4d688e1f685123d7497d4615370152a8ee4a0593e647bd06ad8bb0b81565b61051b7f000000000000000000000000000000000000000000000000000000000000000081565b61035a6213c68081565b6103da61157a565b61035a6105f3366004614e8c565b611641565b610575610606366004614ec8565b606654600160ff9092169190911b9081161490565b60665461035a565b6103da610631366004614ef9565b611671565b6103da610644366004614a64565b61170c565b61051b6106573660046149ff565b609a602052600090815260409020546001600160a01b031681565b6105756106803660046149ff565b61171d565b6103da611757565b61035a61069b366004614f88565b609860209081526000928352604080842090915290825290205481565b6103da6106c6366004615069565b61176b565b60655461051b906001600160a01b031681565b6033546001600160a01b031661051b565b6107026106fd3660046150f9565b611997565b6040516103649190615183565b61051b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b6103da610738366004615196565b611a71565b61035a61074b3660046149ff565b609f6020526000908152604090205481565b61051b7f000000000000000000000000000000000000000000000000000000000000000081565b610575610792366004614a64565b609e6020526000908152604090205460ff1681565b6105756107b53660046151cb565b609c60209081526000928352604080842090915290825290205460ff1681565b61035a609d5481565b61035a6107ec3660046149ff565b60a16020526000908152604090205481565b61086e61080c3660046149ff565b6040805160608082018352600080835260208084018290529284018190526001600160a01b03948516815260998352839020835191820184528054851682526001015493841691810191909152600160a01b90920463ffffffff169082015290565b6040805182516001600160a01b039081168252602080850151909116908201529181015163ffffffff1690820152606001610364565b61035a6108b23660046151f7565b611b43565b61035a62034bc081565b6108d46108cf3660046149ff565b611bfc565b604051610364929190615278565b6103ba6108f03660046149ff565b611fb4565b6103da61090336600461529d565b612478565b6103da6109163660046152f5565b612595565b6103da6109293660046149ff565b612626565b61035a61269c565b6103da610944366004614a64565b6126da565b609d54600090815b838110156109c657600060a1600087878581811061097157610971615311565b905060200201602081019061098691906149ff565b6001600160a01b03166001600160a01b03168152602001908152602001600020549050828111156109b5578092505b506109bf8161533d565b9050610951565b509392505050565b604080517f14bde674c9f64b2ad00eaaee4a8bed1fabef35c7507e3c5b9cfc9436909a2dad6020808301919091526001600160a01b038681168385015288811660608401528716608083015260a0820185905260c08083018590528351808403909101815260e0909201909252805191012060009081610a4c61269c565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f19018152919052805160209091012098975050505050505050565b60665460609060019060029081161415610ac55760405162461bcd60e51b8152600401610abc90615358565b60405180910390fd5b6000836001600160401b03811115610adf57610adf614c31565b604051908082528060200260200182016040528015610b08578160200160208202803683370190505b50336000908152609a60205260408120549192506001600160a01b03909116905b85811015610dee57868682818110610b4357610b43615311565b9050602002810190610b55919061538f565b610b639060208101906153af565b9050878783818110610b7757610b77615311565b9050602002810190610b89919061538f565b610b9390806153af565b905014610c085760405162461bcd60e51b815260206004820152603860248201527f44656c65676174696f6e4d616e616765722e717565756557697468647261776160448201527f6c3a20696e707574206c656e677468206d69736d6174636800000000000000006064820152608401610abc565b33878783818110610c1b57610c1b615311565b9050602002810190610c2d919061538f565b610c3e9060608101906040016149ff565b6001600160a01b031614610cba5760405162461bcd60e51b815260206004820152603c60248201527f44656c65676174696f6e4d616e616765722e717565756557697468647261776160448201527f6c3a2077697468647261776572206d757374206265207374616b6572000000006064820152608401610abc565b610dbf3383898985818110610cd157610cd1615311565b9050602002810190610ce3919061538f565b610cf49060608101906040016149ff565b8a8a86818110610d0657610d06615311565b9050602002810190610d18919061538f565b610d2290806153af565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508e92508d9150889050818110610d6857610d68615311565b9050602002810190610d7a919061538f565b610d889060208101906153af565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061283692505050565b838281518110610dd157610dd1615311565b602090810291909101015280610de68161533d565b915050610b29565b509095945050505050565b610e023361155a565b15610e885760405162461bcd60e51b815260206004820152604a60248201527f44656c65676174696f6e4d616e616765722e726567697374657241734f70657260448201527f61746f723a2063616c6c657220697320616c7265616479206163746976656c796064820152690819195b1959d85d195960b21b608482015260a401610abc565b610e923384612df6565b604080518082019091526060815260006020820152610eb43380836000612fe9565b336001600160a01b03167f8e8485583a2310d41f7c82b9427d0bd49bad74bb9cff9d3402a29d8f9b28a0e285604051610eed91906153f8565b60405180910390a2336001600160a01b03167f02a919ed0e2acad1dd90f17ef2fa4ae5462ee1339170034a8531cca4b67080908484604051610f3092919061544a565b60405180910390a250505050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb59190615479565b6001600160a01b0316336001600160a01b031614610fe55760405162461bcd60e51b8152600401610abc90615496565b610fee8161327f565b50565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806110505750336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016145b61106c5760405162461bcd60e51b8152600401610abc906154e0565b6110758361155a565b156110a3576001600160a01b038084166000908152609a6020526040902054166110a181858585613376565b505b505050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156110f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611114919061553d565b6111305760405162461bcd60e51b8152600401610abc9061555a565b606654818116146111a95760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610abc565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6111ef6133f1565b6110a18484848461344b565b6001600160a01b0383166000908152609b602052604081205461122085828686611b43565b95945050505050565b600054610100900460ff16158080156112495750600054600160ff909116105b806112635750303b158015611263575060005460ff166001145b6112c65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610abc565b6000805460ff1916600117905580156112e9576000805461ff0019166101001790555b6112f38888613671565b6112fb61375b565b609755611307896137f2565b61131086613844565b61131c8585858561344b565b8015611362576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806113cc5750336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016145b6113e85760405162461bcd60e51b8152600401610abc906154e0565b6113f18361155a565b156110a3576001600160a01b038084166000908152609a6020526040902054166110a18185858561393e565b606654600290600490811614156114465760405162461bcd60e51b8152600401610abc90615358565b600260c95414156114995760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610abc565b600260c95560005b88811015611549576115398a8a838181106114be576114be615311565b90506020028101906114d091906155a2565b8989848181106114e2576114e2615311565b90506020028101906114f491906153af565b89898681811061150657611506615311565b9050602002013588888781811061151f5761151f615311565b905060200201602081019061153491906155b8565b6139b9565b6115428161533d565b90506114a1565b5050600160c9555050505050505050565b6001600160a01b039081166000908152609a602052604090205416151590565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156115c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e6919061553d565b6116025760405162461bcd60e51b8152600401610abc9061555a565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000816040516020016116549190615649565b604051602081830303815290604052805190602001209050919050565b6066546002906004908116141561169a5760405162461bcd60e51b8152600401610abc90615358565b600260c95414156116ed5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610abc565b600260c9556116ff86868686866139b9565b5050600160c95550505050565b6117146133f1565b610fee81613844565b60006001600160a01b0382161580159061175157506001600160a01b038083166000818152609a6020526040902054909116145b92915050565b61175f6133f1565b61176960006137f2565b565b42836020015110156117ef5760405162461bcd60e51b815260206004820152604160248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f4279536960448201527f676e61747572653a207374616b6572207369676e6174757265206578706972656064820152601960fa1b608482015260a401610abc565b6117f88561155a565b156118815760405162461bcd60e51b815260206004820152604d60248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f4279536960448201527f676e61747572653a207374616b657220697320616c726561647920616374697660648201526c195b1e4819195b1959d85d1959609a1b608482015260a401610abc565b61188a8461171d565b6119165760405162461bcd60e51b815260206004820152605160248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f4279536960448201527f676e61747572653a206f70657261746f72206973206e6f7420726567697374656064820152703932b21034b71022b4b3b2b72630bcb2b960791b608482015260a401610abc565b6000609b6000876001600160a01b03166001600160a01b0316815260200190815260200160002054905060006119528783888860200151611b43565b6001600160a01b0388166000908152609b60205260409020600184019055855190915061198290889083906141a3565b61198e87878686612fe9565b50505050505050565b6060600082516001600160401b038111156119b4576119b4614c31565b6040519080825280602002602001820160405280156119dd578160200160208202803683370190505b50905060005b83518110156109c6576001600160a01b03851660009081526098602052604081208551909190869084908110611a1b57611a1b615311565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054828281518110611a5657611a56615311565b6020908102919091010152611a6a8161533d565b90506119e3565b611a7a3361171d565b611afc5760405162461bcd60e51b815260206004820152604760248201527f44656c65676174696f6e4d616e616765722e7570646174654f70657261746f7260448201527f4d657461646174615552493a2063616c6c6572206d75737420626520616e206f6064820152663832b930ba37b960c91b608482015260a401610abc565b336001600160a01b03167f02a919ed0e2acad1dd90f17ef2fa4ae5462ee1339170034a8531cca4b67080908383604051611b3792919061544a565b60405180910390a25050565b604080517f39111bc4a4d688e1f685123d7497d4615370152a8ee4a0593e647bd06ad8bb0b6020808301919091526001600160a01b0387811683850152851660608301526080820186905260a08083018590528351808403909101815260c0909201909252805191012060009081611bb961269c565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f190181529190528051602090910120979650505050505050565b6040516360f4062b60e01b81526001600160a01b03828116600483015260609182916000917f0000000000000000000000000000000000000000000000000000000000000000909116906360f4062b90602401602060405180830381865afa158015611c6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c90919061565c565b6040516394f649dd60e01b81526001600160a01b03868116600483015291925060009182917f0000000000000000000000000000000000000000000000000000000000000000909116906394f649dd90602401600060405180830381865afa158015611d00573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d2891908101906156d0565b9150915060008313611d3f57909590945092505050565b606080835160001415611df9576040805160018082528183019092529060208083019080368337505060408051600180825281830190925292945090506020808301908036833701905050905073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac082600081518110611db457611db4615311565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600081518110611de857611de8615311565b602002602001018181525050611fa7565b8351611e0690600161578a565b6001600160401b03811115611e1d57611e1d614c31565b604051908082528060200260200182016040528015611e46578160200160208202803683370190505b50915081516001600160401b03811115611e6257611e62614c31565b604051908082528060200260200182016040528015611e8b578160200160208202803683370190505b50905060005b8451811015611f2557848181518110611eac57611eac615311565b6020026020010151838281518110611ec657611ec6615311565b60200260200101906001600160a01b031690816001600160a01b031681525050838181518110611ef857611ef8615311565b6020026020010151828281518110611f1257611f12615311565b6020908102919091010152600101611e91565b5073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac08260018451611f4a91906157a2565b81518110611f5a57611f5a615311565b60200260200101906001600160a01b031690816001600160a01b031681525050848160018451611f8a91906157a2565b81518110611f9a57611f9a615311565b6020026020010181815250505b9097909650945050505050565b60665460609060019060029081161415611fe05760405162461bcd60e51b8152600401610abc90615358565b611fe98361155a565b6120695760405162461bcd60e51b8152602060048201526044602482018190527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a207374908201527f616b6572206d7573742062652064656c65676174656420746f20756e64656c656064820152636761746560e01b608482015260a401610abc565b6120728361171d565b156120e55760405162461bcd60e51b815260206004820152603d60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a206f7060448201527f657261746f72732063616e6e6f7420626520756e64656c6567617465640000006064820152608401610abc565b6001600160a01b0383166121615760405162461bcd60e51b815260206004820152603c60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a20636160448201527f6e6e6f7420756e64656c6567617465207a65726f2061646472657373000000006064820152608401610abc565b6001600160a01b038084166000818152609a6020526040902054909116903314806121945750336001600160a01b038216145b806121bb57506001600160a01b038181166000908152609960205260409020600101541633145b61222d5760405162461bcd60e51b815260206004820152603d60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a20636160448201527f6c6c65722063616e6e6f7420756e64656c6567617465207374616b65720000006064820152608401610abc565b60008061223986611bfc565b9092509050336001600160a01b0387161461228f57826001600160a01b0316866001600160a01b03167ff0eddf07e6ea14f388b47e1e94a0f464ecbd9eed4171130e0fc0e99fb4030a8a60405160405180910390a35b826001600160a01b0316866001600160a01b03167ffee30966a256b71e14bc0ebfc94315e28ef4a97a7131a9e2b7a310a73af4467660405160405180910390a36001600160a01b0386166000908152609a6020526040902080546001600160a01b0319169055815161231157604080516000815260208101909152945061246f565b81516001600160401b0381111561232a5761232a614c31565b604051908082528060200260200182016040528015612353578160200160208202803683370190505b50945060005b825181101561246d576040805160018082528183019092526000916020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508483815181106123b9576123b9615311565b6020026020010151826000815181106123d4576123d4615311565b60200260200101906001600160a01b031690816001600160a01b03168152505083838151811061240657612406615311565b60200260200101518160008151811061242157612421615311565b60200260200101818152505061243a89878b8585612836565b88848151811061244c5761244c615311565b602002602001018181525050505080806124659061533d565b915050612359565b505b50505050919050565b6124813361155a565b156124ff5760405162461bcd60e51b815260206004820152604260248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f3a20737460448201527f616b657220697320616c7265616479206163746976656c792064656c65676174606482015261195960f21b608482015260a401610abc565b6125088361171d565b6125895760405162461bcd60e51b815260206004820152604660248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f3a206f7060448201527f657261746f72206973206e6f74207265676973746572656420696e2045696765606482015265372630bcb2b960d11b608482015260a401610abc565b6110a333848484612fe9565b61259e3361171d565b61261c5760405162461bcd60e51b815260206004820152604360248201527f44656c65676174696f6e4d616e616765722e6d6f646966794f70657261746f7260448201527f44657461696c733a2063616c6c6572206d75737420626520616e206f706572616064820152623a37b960e91b608482015260a401610abc565b610fee3382612df6565b61262e6133f1565b6001600160a01b0381166126935760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610abc565b610fee816137f2565b60007f00000000000000000000000000000000000000000000000000000000000000004614156126cd575060975490565b6126d561375b565b905090565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561272d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127519190615479565b6001600160a01b0316336001600160a01b0316146127815760405162461bcd60e51b8152600401610abc90615496565b6066541981196066541916146127ff5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610abc565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c906020016111dc565b60006001600160a01b0386166128cd5760405162461bcd60e51b815260206004820152605060248201527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448201527f6e6451756575655769746864726177616c3a207374616b65722063616e6e6f7460648201526f206265207a65726f206164647265737360801b608482015260a401610abc565b82516129575760405162461bcd60e51b815260206004820152604d60248201527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448201527f6e6451756575655769746864726177616c3a207374726174656769657320636160648201526c6e6e6f7420626520656d70747960981b608482015260a401610abc565b60005b8351811015612d04576001600160a01b038616156129b0576129b0868886848151811061298957612989615311565b60200260200101518685815181106129a3576129a3615311565b6020026020010151613376565b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06001600160a01b03168482815181106129e0576129e0615311565b60200260200101516001600160a01b03161415612aa9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663beffbb8988858481518110612a3957612a39615311565b60200260200101516040518363ffffffff1660e01b8152600401612a729291906001600160a01b03929092168252602082015260400190565b600060405180830381600087803b158015612a8c57600080fd5b505af1158015612aa0573d6000803e3d6000fd5b50505050612cfc565b846001600160a01b0316876001600160a01b03161480612b7b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639b4da03d858381518110612b0557612b05615311565b60200260200101516040518263ffffffff1660e01b8152600401612b3891906001600160a01b0391909116815260200190565b602060405180830381865afa158015612b55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b79919061553d565b155b612c475760405162461bcd60e51b8152602060048201526084602482018190527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448301527f6e6451756575655769746864726177616c3a2077697468647261776572206d7560648301527f73742062652073616d652061646472657373206173207374616b657220696620908201527f746869726450617274795472616e7366657273466f7262696464656e2061726560a482015263081cd95d60e21b60c482015260e401610abc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638c80d4e588868481518110612c8957612c89615311565b6020026020010151868581518110612ca357612ca3615311565b60200260200101516040518463ffffffff1660e01b8152600401612cc9939291906157b9565b600060405180830381600087803b158015612ce357600080fd5b505af1158015612cf7573d6000803e3d6000fd5b505050505b60010161295a565b506001600160a01b0386166000908152609f60205260408120805491829190612d2c8361533d565b919050555060006040518060e00160405280896001600160a01b03168152602001886001600160a01b03168152602001876001600160a01b031681526020018381526020014363ffffffff1681526020018681526020018581525090506000612d9482611641565b6000818152609e602052604090819020805460ff19166001179055519091507f9009ab153e8014fbfb02f2217f5cde7aa7f9ad734ae85ca3ee3f4ca2fdd499f990612de290839085906157dd565b60405180910390a198975050505050505050565b6213c680612e0a60608301604084016157f6565b63ffffffff161115612ebf5760405162461bcd60e51b815260206004820152606c60248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a207374616b65724f70744f757457696e646f77426c6f636b732060648201527f63616e6e6f74206265203e204d41585f5354414b45525f4f50545f4f55545f5760848201526b494e444f575f424c4f434b5360a01b60a482015260c401610abc565b6001600160a01b0382166000908152609960205260409081902060010154600160a01b900463ffffffff1690612efb90606084019084016157f6565b63ffffffff161015612f915760405162461bcd60e51b815260206004820152605360248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a207374616b65724f70744f757457696e646f77426c6f636b732060648201527218d85b9b9bdd08189948191958dc99585cd959606a1b608482015260a401610abc565b6001600160a01b03821660009081526099602052604090208190612fb58282615833565b505060405133907ffebe5cd24b2cbc7b065b9d0fdeb904461e4afcff57dd57acda1e7832031ba7ac90611b379084906153f8565b606654600090600190811614156130125760405162461bcd60e51b8152600401610abc90615358565b6001600160a01b038085166000908152609960205260409020600101541680158015906130485750336001600160a01b03821614155b801561305d5750336001600160a01b03861614155b156131ca5742846020015110156130dc5760405162461bcd60e51b815260206004820152603760248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2061707060448201527f726f766572207369676e617475726520657870697265640000000000000000006064820152608401610abc565b6001600160a01b0381166000908152609c6020908152604080832086845290915290205460ff16156131765760405162461bcd60e51b815260206004820152603760248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2061707060448201527f726f76657253616c7420616c7265616479207370656e740000000000000000006064820152608401610abc565b6001600160a01b0381166000908152609c6020908152604080832086845282528220805460ff191660011790558501516131b79088908890859088906109ce565b90506131c8828287600001516141a3565b505b6001600160a01b038681166000818152609a602052604080822080546001600160a01b031916948a169485179055517fc3ee9f2e5fda98e8066a1f745b2df9285f416fe98cf2559cd21484b3d87433049190a360008061322988611bfc565b9150915060005b825181101561136257613277888a85848151811061325057613250615311565b602002602001015185858151811061326a5761326a615311565b602002602001015161393e565b600101613230565b6001600160a01b03811661330d5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610abc565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038085166000908152609860209081526040808320938616835292905290812080548392906133ad9084906157a2565b92505081905550836001600160a01b03167f6909600037b75d7b4733aedd815442b5ec018a827751c832aaff64eba5d6d2dd848484604051610f30939291906157b9565b6033546001600160a01b031633146117695760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610abc565b8281146134d35760405162461bcd60e51b815260206004820152604a60248201527f44656c65676174696f6e4d616e616765722e5f7365745374726174656779576960448201527f746864726177616c44656c6179426c6f636b733a20696e707574206c656e67746064820152690d040dad2e6dac2e8c6d60b31b608482015260a401610abc565b8260005b818110156136695760008686838181106134f3576134f3615311565b905060200201602081019061350891906149ff565b6001600160a01b038116600090815260a1602052604081205491925086868581811061353657613536615311565b90506020020135905062034bc08111156135fa5760405162461bcd60e51b815260206004820152607360248201527f44656c65676174696f6e4d616e616765722e5f7365745374726174656779576960448201527f746864726177616c44656c6179426c6f636b733a205f7769746864726177616c60648201527f44656c6179426c6f636b732063616e6e6f74206265203e204d41585f5749544860848201527244524157414c5f44454c41595f424c4f434b5360681b60a482015260c401610abc565b6001600160a01b038316600081815260a160209081526040918290208490558151928352820184905281018290527f0e7efa738e8b0ce6376a0c1af471655540d2e9a81647d7b09ed823018426576d9060600160405180910390a1505050806136629061533d565b90506134d7565b505050505050565b6065546001600160a01b031615801561369257506001600160a01b03821615155b6137145760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610abc565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26137578261327f565b5050565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b62034bc08111156138fd5760405162461bcd60e51b815260206004820152607160248201527f44656c65676174696f6e4d616e616765722e5f7365744d696e5769746864726160448201527f77616c44656c6179426c6f636b733a205f6d696e5769746864726177616c446560648201527f6c6179426c6f636b732063616e6e6f74206265203e204d41585f5749544844526084820152704157414c5f44454c41595f424c4f434b5360781b60a482015260c401610abc565b609d5460408051918252602082018390527fafa003cd76f87ff9d62b35beea889920f33c0c42b8d45b74954d61d50f4b6b69910160405180910390a1609d55565b6001600160a01b0380851660009081526098602090815260408083209386168352929052908120805483929061397590849061578a565b92505081905550836001600160a01b03167f1ec042c965e2edd7107b51188ee0f383e22e76179041ab3a9d18ff151405166c848484604051610f30939291906157b9565b60006139c76105f387615896565b6000818152609e602052604090205490915060ff16613a485760405162461bcd60e51b815260206004820152604360248201526000805160206159c883398151915260448201527f645769746864726177616c3a20616374696f6e206973206e6f7420696e20717560648201526265756560e81b608482015260a401610abc565b609d544390613a5d60a0890160808a016157f6565b63ffffffff16613a6d919061578a565b1115613af55760405162461bcd60e51b815260206004820152605f60248201526000805160206159c883398151915260448201527f645769746864726177616c3a206d696e5769746864726177616c44656c61794260648201527f6c6f636b7320706572696f6420686173206e6f74207965742070617373656400608482015260a401610abc565b613b0560608701604088016149ff565b6001600160a01b0316336001600160a01b031614613b925760405162461bcd60e51b815260206004820152605060248201526000805160206159c883398151915260448201527f645769746864726177616c3a206f6e6c7920776974686472617765722063616e60648201526f1031b7b6b83632ba329030b1ba34b7b760811b608482015260a401610abc565b8115613c1457613ba560a08701876153af565b85149050613c145760405162461bcd60e51b815260206004820152604260248201526000805160206159c883398151915260448201527f645769746864726177616c3a20696e707574206c656e677468206d69736d61746064820152610c6d60f31b608482015260a401610abc565b6000818152609e60205260409020805460ff191690558115613d795760005b613c4060a08801886153af565b9050811015613d73574360a16000613c5b60a08b018b6153af565b85818110613c6b57613c6b615311565b9050602002016020810190613c8091906149ff565b6001600160a01b03168152602081019190915260400160002054613caa60a08a0160808b016157f6565b63ffffffff16613cba919061578a565b1115613cd85760405162461bcd60e51b8152600401610abc906158a2565b613d6b613ce860208901896149ff565b33613cf660a08b018b6153af565b85818110613d0657613d06615311565b9050602002016020810190613d1b91906149ff565b613d2860c08c018c6153af565b86818110613d3857613d38615311565b905060200201358a8a87818110613d5157613d51615311565b9050602002016020810190613d6691906149ff565b61435d565b600101613c33565b50614168565b336000908152609a60205260408120546001600160a01b0316905b613da160a08901896153af565b9050811015614165574360a16000613dbc60a08c018c6153af565b85818110613dcc57613dcc615311565b9050602002016020810190613de191906149ff565b6001600160a01b03168152602081019190915260400160002054613e0b60a08b0160808c016157f6565b63ffffffff16613e1b919061578a565b1115613e395760405162461bcd60e51b8152600401610abc906158a2565b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac0613e5b60a08a018a6153af565b83818110613e6b57613e6b615311565b9050602002016020810190613e8091906149ff565b6001600160a01b03161415613fd0576000613e9e60208a018a6149ff565b905060006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016630e81073c83613edf60c08e018e6153af565b87818110613eef57613eef615311565b6040516001600160e01b031960e087901b1681526001600160a01b03909416600485015260200291909101356024830152506044016020604051808303816000875af1158015613f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f67919061565c565b6001600160a01b038084166000908152609a6020526040902054919250168015613fc857613fc88184613f9d60a08f018f6153af565b88818110613fad57613fad615311565b9050602002016020810190613fc291906149ff565b8561393e565b50505061415d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c4623ea13389898581811061401257614012615311565b905060200201602081019061402791906149ff565b61403460a08d018d6153af565b8681811061404457614044615311565b905060200201602081019061405991906149ff565b61406660c08e018e6153af565b8781811061407657614076615311565b60405160e088901b6001600160e01b03191681526001600160a01b03968716600482015294861660248601529290941660448401526020909102013560648201526084019050600060405180830381600087803b1580156140d657600080fd5b505af11580156140ea573d6000803e3d6000fd5b505050506001600160a01b0382161561415d5761415d823361410f60a08c018c6153af565b8581811061411f5761411f615311565b905060200201602081019061413491906149ff565b61414160c08d018d6153af565b8681811061415157614151615311565b9050602002013561393e565b600101613d94565b50505b6040518181527fc97098c2f658800b4df29001527f7324bcdffcf6e8751a699ab920a1eced5b1d9060200160405180910390a1505050505050565b6001600160a01b0383163b156142bd57604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e906141e3908690869060040161592a565b602060405180830381865afa158015614200573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142249190615987565b6001600160e01b031916146110a35760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a401610abc565b826001600160a01b03166142d1838361449d565b6001600160a01b0316146110a35760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a401610abc565b6001600160a01b03831673beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac014156144085760405162387b1360e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063387b1300906143d1908890889087906004016157b9565b600060405180830381600087803b1580156143eb57600080fd5b505af11580156143ff573d6000803e3d6000fd5b50505050614496565b60405163c608c7f360e01b81526001600160a01b03858116600483015284811660248301526044820184905282811660648301527f0000000000000000000000000000000000000000000000000000000000000000169063c608c7f390608401600060405180830381600087803b15801561448257600080fd5b505af1158015611362573d6000803e3d6000fd5b5050505050565b60008060006144ac85856144b9565b915091506109c681614529565b6000808251604114156144f05760208301516040840151606085015160001a6144e4878285856146e4565b94509450505050614522565b82516040141561451a576020830151604084015161450f8683836147d1565b935093505050614522565b506000905060025b9250929050565b600081600481111561453d5761453d6159b1565b14156145465750565b600181600481111561455a5761455a6159b1565b14156145a85760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610abc565b60028160048111156145bc576145bc6159b1565b141561460a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610abc565b600381600481111561461e5761461e6159b1565b14156146775760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610abc565b600481600481111561468b5761468b6159b1565b1415610fee5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610abc565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561471b57506000905060036147c8565b8460ff16601b1415801561473357508460ff16601c14155b1561474457506000905060046147c8565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614798573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166147c1576000600192509250506147c8565b9150600090505b94509492505050565b6000806001600160ff1b038316816147ee60ff86901c601b61578a565b90506147fc878288856146e4565b935093505050935093915050565b60008083601f84011261481c57600080fd5b5081356001600160401b0381111561483357600080fd5b6020830191508360208260051b850101111561452257600080fd5b6000806020838503121561486157600080fd5b82356001600160401b0381111561487757600080fd5b6148838582860161480a565b90969095509350505050565b6001600160a01b0381168114610fee57600080fd5b80356148af8161488f565b919050565b600080600080600060a086880312156148cc57600080fd5b85356148d78161488f565b945060208601356148e78161488f565b935060408601356148f78161488f565b94979396509394606081013594506080013592915050565b6020808252825182820181905260009190848201906040850190845b818110156149475783518352928401929184019160010161492b565b50909695505050505050565b60006060828403121561496557600080fd5b50919050565b60008083601f84011261497d57600080fd5b5081356001600160401b0381111561499457600080fd5b60208301915083602082850101111561452257600080fd5b6000806000608084860312156149c157600080fd5b6149cb8585614953565b925060608401356001600160401b038111156149e657600080fd5b6149f28682870161496b565b9497909650939450505050565b600060208284031215614a1157600080fd5b8135614a1c8161488f565b9392505050565b600080600060608486031215614a3857600080fd5b8335614a438161488f565b92506020840135614a538161488f565b929592945050506040919091013590565b600060208284031215614a7657600080fd5b5035919050565b60008060008060408587031215614a9357600080fd5b84356001600160401b0380821115614aaa57600080fd5b614ab68883890161480a565b90965094506020870135915080821115614acf57600080fd5b50614adc8782880161480a565b95989497509550505050565b60008060008060008060008060c0898b031215614b0457600080fd5b8835614b0f8161488f565b97506020890135614b1f8161488f565b9650604089013595506060890135945060808901356001600160401b0380821115614b4957600080fd5b614b558c838d0161480a565b909650945060a08b0135915080821115614b6e57600080fd5b50614b7b8b828c0161480a565b999c989b5096995094979396929594505050565b6000806000806000806000806080898b031215614bab57600080fd5b88356001600160401b0380821115614bc257600080fd5b614bce8c838d0161480a565b909a50985060208b0135915080821115614be757600080fd5b614bf38c838d0161480a565b909850965060408b0135915080821115614c0c57600080fd5b614c188c838d0161480a565b909650945060608b0135915080821115614b6e57600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715614c6957614c69614c31565b60405290565b604080519081016001600160401b0381118282101715614c6957614c69614c31565b604051601f8201601f191681016001600160401b0381118282101715614cb957614cb9614c31565b604052919050565b63ffffffff81168114610fee57600080fd5b80356148af81614cc1565b60006001600160401b03821115614cf757614cf7614c31565b5060051b60200190565b600082601f830112614d1257600080fd5b81356020614d27614d2283614cde565b614c91565b82815260059290921b84018101918181019086841115614d4657600080fd5b8286015b84811015614d6a578035614d5d8161488f565b8352918301918301614d4a565b509695505050505050565b600082601f830112614d8657600080fd5b81356020614d96614d2283614cde565b82815260059290921b84018101918181019086841115614db557600080fd5b8286015b84811015614d6a5780358352918301918301614db9565b600060e08284031215614de257600080fd5b614dea614c47565b9050614df5826148a4565b8152614e03602083016148a4565b6020820152614e14604083016148a4565b604082015260608201356060820152614e2f60808301614cd3565b608082015260a08201356001600160401b0380821115614e4e57600080fd5b614e5a85838601614d01565b60a084015260c0840135915080821115614e7357600080fd5b50614e8084828501614d75565b60c08301525092915050565b600060208284031215614e9e57600080fd5b81356001600160401b03811115614eb457600080fd5b614ec084828501614dd0565b949350505050565b600060208284031215614eda57600080fd5b813560ff81168114614a1c57600080fd5b8015158114610fee57600080fd5b600080600080600060808688031215614f1157600080fd5b85356001600160401b0380821115614f2857600080fd5b9087019060e0828a031215614f3c57600080fd5b90955060208701359080821115614f5257600080fd5b50614f5f8882890161480a565b909550935050604086013591506060860135614f7a81614eeb565b809150509295509295909350565b60008060408385031215614f9b57600080fd5b8235614fa68161488f565b91506020830135614fb68161488f565b809150509250929050565b600060408284031215614fd357600080fd5b614fdb614c6f565b905081356001600160401b0380821115614ff457600080fd5b818401915084601f83011261500857600080fd5b813560208282111561501c5761501c614c31565b61502e601f8301601f19168201614c91565b9250818352868183860101111561504457600080fd5b8181850182850137600081838501015282855280860135818601525050505092915050565b600080600080600060a0868803121561508157600080fd5b853561508c8161488f565b9450602086013561509c8161488f565b935060408601356001600160401b03808211156150b857600080fd5b6150c489838a01614fc1565b945060608801359150808211156150da57600080fd5b506150e788828901614fc1565b95989497509295608001359392505050565b6000806040838503121561510c57600080fd5b82356151178161488f565b915060208301356001600160401b0381111561513257600080fd5b61513e85828601614d01565b9150509250929050565b600081518084526020808501945080840160005b838110156151785781518752958201959082019060010161515c565b509495945050505050565b602081526000614a1c6020830184615148565b600080602083850312156151a957600080fd5b82356001600160401b038111156151bf57600080fd5b6148838582860161496b565b600080604083850312156151de57600080fd5b82356151e98161488f565b946020939093013593505050565b6000806000806080858703121561520d57600080fd5b84356152188161488f565b935060208501359250604085013561522f8161488f565b9396929550929360600135925050565b600081518084526020808501945080840160005b838110156151785781516001600160a01b031687529582019590820190600101615253565b60408152600061528b604083018561523f565b82810360208401526112208185615148565b6000806000606084860312156152b257600080fd5b83356152bd8161488f565b925060208401356001600160401b038111156152d857600080fd5b6152e486828701614fc1565b925050604084013590509250925092565b60006060828403121561530757600080fd5b614a1c8383614953565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561535157615351615327565b5060010190565b60208082526019908201527f5061757361626c653a20696e6465782069732070617573656400000000000000604082015260600190565b60008235605e198336030181126153a557600080fd5b9190910192915050565b6000808335601e198436030181126153c657600080fd5b8301803591506001600160401b038211156153e057600080fd5b6020019150600581901b360382131561452257600080fd5b6060810182356154078161488f565b6001600160a01b0390811683526020840135906154238261488f565b166020830152604083013561543781614cc1565b63ffffffff811660408401525092915050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60006020828403121561548b57600080fd5b8151614a1c8161488f565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60208082526037908201527f44656c65676174696f6e4d616e616765723a206f6e6c7953747261746567794d60408201527f616e616765724f72456967656e506f644d616e61676572000000000000000000606082015260800190565b60006020828403121561554f57600080fd5b8151614a1c81614eeb565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b6000823560de198336030181126153a557600080fd5b6000602082840312156155ca57600080fd5b8135614a1c81614eeb565b600060018060a01b03808351168452806020840151166020850152806040840151166040850152506060820151606084015263ffffffff608083015116608084015260a082015160e060a085015261563060e085018261523f565b905060c083015184820360c08601526112208282615148565b602081526000614a1c60208301846155d5565b60006020828403121561566e57600080fd5b5051919050565b600082601f83011261568657600080fd5b81516020615696614d2283614cde565b82815260059290921b840181019181810190868411156156b557600080fd5b8286015b84811015614d6a57805183529183019183016156b9565b600080604083850312156156e357600080fd5b82516001600160401b03808211156156fa57600080fd5b818501915085601f83011261570e57600080fd5b8151602061571e614d2283614cde565b82815260059290921b8401810191818101908984111561573d57600080fd5b948201945b838610156157645785516157558161488f565b82529482019490820190615742565b9188015191965090935050508082111561577d57600080fd5b5061513e85828601615675565b6000821982111561579d5761579d615327565b500190565b6000828210156157b4576157b4615327565b500390565b6001600160a01b039384168152919092166020820152604081019190915260600190565b828152604060208201526000614ec060408301846155d5565b60006020828403121561580857600080fd5b8135614a1c81614cc1565b80546001600160a01b0319166001600160a01b0392909216919091179055565b813561583e8161488f565b6158488183615813565b5060018101602083013561585b8161488f565b6158658183615813565b50604083013561587481614cc1565b815463ffffffff60a01b191660a09190911b63ffffffff60a01b161790555050565b60006117513683614dd0565b6020808252606e908201526000805160206159c883398151915260408201527f645769746864726177616c3a207769746864726177616c44656c6179426c6f6360608201527f6b7320706572696f6420686173206e6f74207965742070617373656420666f7260808201526d207468697320737472617465677960901b60a082015260c00190565b82815260006020604081840152835180604085015260005b8181101561595e57858101830151858201606001528201615942565b81811115615970576000606083870101525b50601f01601f191692909201606001949350505050565b60006020828403121561599957600080fd5b81516001600160e01b031981168114614a1c57600080fd5b634e487b7160e01b600052602160045260246000fdfe44656c65676174696f6e4d616e616765722e5f636f6d706c6574655175657565a2646970667358221220bf8d86bcdd28ced1de84f8b1df4241e41ec500e2d5f60b98850fd1866eb2cace64736f6c634300080c0033", + Bin: "0x6101006040523480156200001257600080fd5b5060405162005c4638038062005c46833981016040819052620000359162000140565b6001600160a01b0380841660805280821660c052821660a0526200005862000065565b50504660e0525062000194565b600054610100900460ff1615620000d25760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000125576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b03811681146200013d57600080fd5b50565b6000806000606084860312156200015657600080fd5b8351620001638162000127565b6020850151909350620001768162000127565b6040850151909250620001898162000127565b809150509250925092565b60805160a05160c05160e051615a1d6200022960003960006126a00152600081816105b10152818161102e015281816113aa01528181611c23015281816129f901528181613eac0152614398015260006107620152600081816104f901528181610ffc0152818161137801528181611cb701528181612ac601528181612c4901528181613fd2015261443e0152615a1d6000f3fe608060405234801561001057600080fd5b50600436106103425760003560e01c8063635bbd10116101b8578063b7f06ebe11610104578063cf80873e116100a2578063f16172b01161007c578063f16172b014610908578063f2fde38b1461091b578063f698da251461092e578063fabc1cbc1461093657600080fd5b8063cf80873e146108c1578063da8be864146108e2578063eea9064b146108f557600080fd5b8063c488375a116100de578063c488375a146107de578063c5e480db146107fe578063c94b5111146108a4578063ca661c04146108b757600080fd5b8063b7f06ebe14610784578063bb45fef2146107a7578063c448feb8146107d557600080fd5b8063886f1195116101715780639104c3191161014b5780639104c3191461070f57806399be81c81461072a578063a17884841461073d578063b13442711461075d57600080fd5b8063886f1195146106cb5780638da5cb5b146106de57806390041347146106ef57600080fd5b8063635bbd101461063657806365da1264146106495780636d70f7ae14610672578063715018a614610685578063778e55f31461068d5780637f548071146106b857600080fd5b806328a573ae116102925780634665bcda11610230578063597b36da1161020a578063597b36da146105e55780635ac86ab7146105f85780635c975abb1461061b57806360d7faed1461062357600080fd5b80634665bcda146105ac5780634fc40b61146105d3578063595c6a67146105dd57600080fd5b806339b70e381161026c57806339b70e38146104f45780633cdeb5e0146105335780633e28391d14610562578063433773821461058557600080fd5b806328a573ae146104ae57806329c77d4f146104c157806333404396146104e157600080fd5b8063132d4967116102ff57806316928365116102d957806316928365146104285780631bbce0911461046157806320606b701461047457806322bf40e41461049b57600080fd5b8063132d4967146103ef578063136439dd146104025780631522bf021461041557600080fd5b80630449ca391461034757806304a4f9791461036d5780630b9f487a146103945780630dd8dd02146103a75780630f589e59146103c757806310d67a2f146103dc575b600080fd5b61035a61035536600461484e565b610949565b6040519081526020015b60405180910390f35b61035a7f14bde674c9f64b2ad00eaaee4a8bed1fabef35c7507e3c5b9cfc9436909a2dad81565b61035a6103a23660046148b4565b6109ce565b6103ba6103b536600461484e565b610a90565b604051610364919061490f565b6103da6103d53660046149ac565b610df9565b005b6103da6103ea3660046149ff565b610f3e565b6103da6103fd366004614a23565b610ff1565b6103da610410366004614a64565b6110a8565b6103da610423366004614a7d565b6111e7565b61035a6104363660046149ff565b6001600160a01b0316600090815260996020526040902060010154600160a01b900463ffffffff1690565b61035a61046f366004614a23565b6111fb565b61035a7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6103da6104a9366004614ae8565b611229565b6103da6104bc366004614a23565b61136d565b61035a6104cf3660046149ff565b609b6020526000908152604090205481565b6103da6104ef366004614b8f565b61141d565b61051b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610364565b61051b6105413660046149ff565b6001600160a01b039081166000908152609960205260409020600101541690565b6105756105703660046149ff565b61155a565b6040519015158152602001610364565b61035a7f39111bc4a4d688e1f685123d7497d4615370152a8ee4a0593e647bd06ad8bb0b81565b61051b7f000000000000000000000000000000000000000000000000000000000000000081565b61035a6213c68081565b6103da61157a565b61035a6105f3366004614e8c565b611641565b610575610606366004614ec8565b606654600160ff9092169190911b9081161490565b60665461035a565b6103da610631366004614ef9565b611671565b6103da610644366004614a64565b61170c565b61051b6106573660046149ff565b609a602052600090815260409020546001600160a01b031681565b6105756106803660046149ff565b61171d565b6103da611757565b61035a61069b366004614f88565b609860209081526000928352604080842090915290825290205481565b6103da6106c6366004615069565b61176b565b60655461051b906001600160a01b031681565b6033546001600160a01b031661051b565b6107026106fd3660046150f9565b611997565b6040516103649190615183565b61051b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b6103da610738366004615196565b611a71565b61035a61074b3660046149ff565b609f6020526000908152604090205481565b61051b7f000000000000000000000000000000000000000000000000000000000000000081565b610575610792366004614a64565b609e6020526000908152604090205460ff1681565b6105756107b53660046151cb565b609c60209081526000928352604080842090915290825290205460ff1681565b61035a609d5481565b61035a6107ec3660046149ff565b60a16020526000908152604090205481565b61086e61080c3660046149ff565b6040805160608082018352600080835260208084018290529284018190526001600160a01b03948516815260998352839020835191820184528054851682526001015493841691810191909152600160a01b90920463ffffffff169082015290565b6040805182516001600160a01b039081168252602080850151909116908201529181015163ffffffff1690820152606001610364565b61035a6108b23660046151f7565b611b43565b61035a62034bc081565b6108d46108cf3660046149ff565b611bfc565b604051610364929190615278565b6103ba6108f03660046149ff565b611fb4565b6103da61090336600461529d565b612478565b6103da6109163660046152f5565b612595565b6103da6109293660046149ff565b612626565b61035a61269c565b6103da610944366004614a64565b6126da565b609d54600090815b838110156109c657600060a1600087878581811061097157610971615311565b905060200201602081019061098691906149ff565b6001600160a01b03166001600160a01b03168152602001908152602001600020549050828111156109b5578092505b506109bf8161533d565b9050610951565b509392505050565b604080517f14bde674c9f64b2ad00eaaee4a8bed1fabef35c7507e3c5b9cfc9436909a2dad6020808301919091526001600160a01b038681168385015288811660608401528716608083015260a0820185905260c08083018590528351808403909101815260e0909201909252805191012060009081610a4c61269c565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f19018152919052805160209091012098975050505050505050565b60665460609060019060029081161415610ac55760405162461bcd60e51b8152600401610abc90615358565b60405180910390fd5b6000836001600160401b03811115610adf57610adf614c31565b604051908082528060200260200182016040528015610b08578160200160208202803683370190505b50336000908152609a60205260408120549192506001600160a01b03909116905b85811015610dee57868682818110610b4357610b43615311565b9050602002810190610b55919061538f565b610b639060208101906153af565b9050878783818110610b7757610b77615311565b9050602002810190610b89919061538f565b610b9390806153af565b905014610c085760405162461bcd60e51b815260206004820152603860248201527f44656c65676174696f6e4d616e616765722e717565756557697468647261776160448201527f6c3a20696e707574206c656e677468206d69736d6174636800000000000000006064820152608401610abc565b33878783818110610c1b57610c1b615311565b9050602002810190610c2d919061538f565b610c3e9060608101906040016149ff565b6001600160a01b031614610cba5760405162461bcd60e51b815260206004820152603c60248201527f44656c65676174696f6e4d616e616765722e717565756557697468647261776160448201527f6c3a2077697468647261776572206d757374206265207374616b6572000000006064820152608401610abc565b610dbf3383898985818110610cd157610cd1615311565b9050602002810190610ce3919061538f565b610cf49060608101906040016149ff565b8a8a86818110610d0657610d06615311565b9050602002810190610d18919061538f565b610d2290806153af565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508e92508d9150889050818110610d6857610d68615311565b9050602002810190610d7a919061538f565b610d889060208101906153af565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061283692505050565b838281518110610dd157610dd1615311565b602090810291909101015280610de68161533d565b915050610b29565b509095945050505050565b610e023361155a565b15610e885760405162461bcd60e51b815260206004820152604a60248201527f44656c65676174696f6e4d616e616765722e726567697374657241734f70657260448201527f61746f723a2063616c6c657220697320616c7265616479206163746976656c796064820152690819195b1959d85d195960b21b608482015260a401610abc565b610e923384612df6565b604080518082019091526060815260006020820152610eb43380836000612fe9565b336001600160a01b03167f8e8485583a2310d41f7c82b9427d0bd49bad74bb9cff9d3402a29d8f9b28a0e285604051610eed91906153f8565b60405180910390a2336001600160a01b03167f02a919ed0e2acad1dd90f17ef2fa4ae5462ee1339170034a8531cca4b67080908484604051610f3092919061544a565b60405180910390a250505050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb59190615479565b6001600160a01b0316336001600160a01b031614610fe55760405162461bcd60e51b8152600401610abc90615496565b610fee8161327f565b50565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806110505750336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016145b61106c5760405162461bcd60e51b8152600401610abc906154e0565b6110758361155a565b156110a3576001600160a01b038084166000908152609a6020526040902054166110a181858585613376565b505b505050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156110f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611114919061553d565b6111305760405162461bcd60e51b8152600401610abc9061555a565b606654818116146111a95760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610abc565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6111ef6133f1565b6110a18484848461344b565b6001600160a01b0383166000908152609b602052604081205461122085828686611b43565b95945050505050565b600054610100900460ff16158080156112495750600054600160ff909116105b806112635750303b158015611263575060005460ff166001145b6112c65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610abc565b6000805460ff1916600117905580156112e9576000805461ff0019166101001790555b6112f38888613671565b6112fb61375b565b609755611307896137f2565b61131086613844565b61131c8585858561344b565b8015611362576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806113cc5750336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016145b6113e85760405162461bcd60e51b8152600401610abc906154e0565b6113f18361155a565b156110a3576001600160a01b038084166000908152609a6020526040902054166110a18185858561393e565b606654600290600490811614156114465760405162461bcd60e51b8152600401610abc90615358565b600260c95414156114995760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610abc565b600260c95560005b88811015611549576115398a8a838181106114be576114be615311565b90506020028101906114d091906155a2565b8989848181106114e2576114e2615311565b90506020028101906114f491906153af565b89898681811061150657611506615311565b9050602002013588888781811061151f5761151f615311565b905060200201602081019061153491906155b8565b6139b9565b6115428161533d565b90506114a1565b5050600160c9555050505050505050565b6001600160a01b039081166000908152609a602052604090205416151590565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156115c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e6919061553d565b6116025760405162461bcd60e51b8152600401610abc9061555a565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000816040516020016116549190615649565b604051602081830303815290604052805190602001209050919050565b6066546002906004908116141561169a5760405162461bcd60e51b8152600401610abc90615358565b600260c95414156116ed5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610abc565b600260c9556116ff86868686866139b9565b5050600160c95550505050565b6117146133f1565b610fee81613844565b60006001600160a01b0382161580159061175157506001600160a01b038083166000818152609a6020526040902054909116145b92915050565b61175f6133f1565b61176960006137f2565b565b42836020015110156117ef5760405162461bcd60e51b815260206004820152604160248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f4279536960448201527f676e61747572653a207374616b6572207369676e6174757265206578706972656064820152601960fa1b608482015260a401610abc565b6117f88561155a565b156118815760405162461bcd60e51b815260206004820152604d60248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f4279536960448201527f676e61747572653a207374616b657220697320616c726561647920616374697660648201526c195b1e4819195b1959d85d1959609a1b608482015260a401610abc565b61188a8461171d565b6119165760405162461bcd60e51b815260206004820152605160248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f4279536960448201527f676e61747572653a206f70657261746f72206973206e6f7420726567697374656064820152703932b21034b71022b4b3b2b72630bcb2b960791b608482015260a401610abc565b6000609b6000876001600160a01b03166001600160a01b0316815260200190815260200160002054905060006119528783888860200151611b43565b6001600160a01b0388166000908152609b60205260409020600184019055855190915061198290889083906141a3565b61198e87878686612fe9565b50505050505050565b6060600082516001600160401b038111156119b4576119b4614c31565b6040519080825280602002602001820160405280156119dd578160200160208202803683370190505b50905060005b83518110156109c6576001600160a01b03851660009081526098602052604081208551909190869084908110611a1b57611a1b615311565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054828281518110611a5657611a56615311565b6020908102919091010152611a6a8161533d565b90506119e3565b611a7a3361171d565b611afc5760405162461bcd60e51b815260206004820152604760248201527f44656c65676174696f6e4d616e616765722e7570646174654f70657261746f7260448201527f4d657461646174615552493a2063616c6c6572206d75737420626520616e206f6064820152663832b930ba37b960c91b608482015260a401610abc565b336001600160a01b03167f02a919ed0e2acad1dd90f17ef2fa4ae5462ee1339170034a8531cca4b67080908383604051611b3792919061544a565b60405180910390a25050565b604080517f39111bc4a4d688e1f685123d7497d4615370152a8ee4a0593e647bd06ad8bb0b6020808301919091526001600160a01b0387811683850152851660608301526080820186905260a08083018590528351808403909101815260c0909201909252805191012060009081611bb961269c565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f190181529190528051602090910120979650505050505050565b6040516360f4062b60e01b81526001600160a01b03828116600483015260609182916000917f0000000000000000000000000000000000000000000000000000000000000000909116906360f4062b90602401602060405180830381865afa158015611c6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c90919061565c565b6040516394f649dd60e01b81526001600160a01b03868116600483015291925060009182917f0000000000000000000000000000000000000000000000000000000000000000909116906394f649dd90602401600060405180830381865afa158015611d00573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d2891908101906156d0565b9150915060008313611d3f57909590945092505050565b606080835160001415611df9576040805160018082528183019092529060208083019080368337505060408051600180825281830190925292945090506020808301908036833701905050905073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac082600081518110611db457611db4615311565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600081518110611de857611de8615311565b602002602001018181525050611fa7565b8351611e0690600161578a565b6001600160401b03811115611e1d57611e1d614c31565b604051908082528060200260200182016040528015611e46578160200160208202803683370190505b50915081516001600160401b03811115611e6257611e62614c31565b604051908082528060200260200182016040528015611e8b578160200160208202803683370190505b50905060005b8451811015611f2557848181518110611eac57611eac615311565b6020026020010151838281518110611ec657611ec6615311565b60200260200101906001600160a01b031690816001600160a01b031681525050838181518110611ef857611ef8615311565b6020026020010151828281518110611f1257611f12615311565b6020908102919091010152600101611e91565b5073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac08260018451611f4a91906157a2565b81518110611f5a57611f5a615311565b60200260200101906001600160a01b031690816001600160a01b031681525050848160018451611f8a91906157a2565b81518110611f9a57611f9a615311565b6020026020010181815250505b9097909650945050505050565b60665460609060019060029081161415611fe05760405162461bcd60e51b8152600401610abc90615358565b611fe98361155a565b6120695760405162461bcd60e51b8152602060048201526044602482018190527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a207374908201527f616b6572206d7573742062652064656c65676174656420746f20756e64656c656064820152636761746560e01b608482015260a401610abc565b6120728361171d565b156120e55760405162461bcd60e51b815260206004820152603d60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a206f7060448201527f657261746f72732063616e6e6f7420626520756e64656c6567617465640000006064820152608401610abc565b6001600160a01b0383166121615760405162461bcd60e51b815260206004820152603c60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a20636160448201527f6e6e6f7420756e64656c6567617465207a65726f2061646472657373000000006064820152608401610abc565b6001600160a01b038084166000818152609a6020526040902054909116903314806121945750336001600160a01b038216145b806121bb57506001600160a01b038181166000908152609960205260409020600101541633145b61222d5760405162461bcd60e51b815260206004820152603d60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a20636160448201527f6c6c65722063616e6e6f7420756e64656c6567617465207374616b65720000006064820152608401610abc565b60008061223986611bfc565b9092509050336001600160a01b0387161461228f57826001600160a01b0316866001600160a01b03167ff0eddf07e6ea14f388b47e1e94a0f464ecbd9eed4171130e0fc0e99fb4030a8a60405160405180910390a35b826001600160a01b0316866001600160a01b03167ffee30966a256b71e14bc0ebfc94315e28ef4a97a7131a9e2b7a310a73af4467660405160405180910390a36001600160a01b0386166000908152609a6020526040902080546001600160a01b0319169055815161231157604080516000815260208101909152945061246f565b81516001600160401b0381111561232a5761232a614c31565b604051908082528060200260200182016040528015612353578160200160208202803683370190505b50945060005b825181101561246d576040805160018082528183019092526000916020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508483815181106123b9576123b9615311565b6020026020010151826000815181106123d4576123d4615311565b60200260200101906001600160a01b031690816001600160a01b03168152505083838151811061240657612406615311565b60200260200101518160008151811061242157612421615311565b60200260200101818152505061243a89878b8585612836565b88848151811061244c5761244c615311565b602002602001018181525050505080806124659061533d565b915050612359565b505b50505050919050565b6124813361155a565b156124ff5760405162461bcd60e51b815260206004820152604260248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f3a20737460448201527f616b657220697320616c7265616479206163746976656c792064656c65676174606482015261195960f21b608482015260a401610abc565b6125088361171d565b6125895760405162461bcd60e51b815260206004820152604660248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f3a206f7060448201527f657261746f72206973206e6f74207265676973746572656420696e2045696765606482015265372630bcb2b960d11b608482015260a401610abc565b6110a333848484612fe9565b61259e3361171d565b61261c5760405162461bcd60e51b815260206004820152604360248201527f44656c65676174696f6e4d616e616765722e6d6f646966794f70657261746f7260448201527f44657461696c733a2063616c6c6572206d75737420626520616e206f706572616064820152623a37b960e91b608482015260a401610abc565b610fee3382612df6565b61262e6133f1565b6001600160a01b0381166126935760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610abc565b610fee816137f2565b60007f00000000000000000000000000000000000000000000000000000000000000004614156126cd575060975490565b6126d561375b565b905090565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561272d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127519190615479565b6001600160a01b0316336001600160a01b0316146127815760405162461bcd60e51b8152600401610abc90615496565b6066541981196066541916146127ff5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610abc565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c906020016111dc565b60006001600160a01b0386166128cd5760405162461bcd60e51b815260206004820152605060248201527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448201527f6e6451756575655769746864726177616c3a207374616b65722063616e6e6f7460648201526f206265207a65726f206164647265737360801b608482015260a401610abc565b82516129575760405162461bcd60e51b815260206004820152604d60248201527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448201527f6e6451756575655769746864726177616c3a207374726174656769657320636160648201526c6e6e6f7420626520656d70747960981b608482015260a401610abc565b60005b8351811015612d04576001600160a01b038616156129b0576129b0868886848151811061298957612989615311565b60200260200101518685815181106129a3576129a3615311565b6020026020010151613376565b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06001600160a01b03168482815181106129e0576129e0615311565b60200260200101516001600160a01b03161415612aa9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663beffbb8988858481518110612a3957612a39615311565b60200260200101516040518363ffffffff1660e01b8152600401612a729291906001600160a01b03929092168252602082015260400190565b600060405180830381600087803b158015612a8c57600080fd5b505af1158015612aa0573d6000803e3d6000fd5b50505050612cfc565b846001600160a01b0316876001600160a01b03161480612b7b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639b4da03d858381518110612b0557612b05615311565b60200260200101516040518263ffffffff1660e01b8152600401612b3891906001600160a01b0391909116815260200190565b602060405180830381865afa158015612b55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b79919061553d565b155b612c475760405162461bcd60e51b8152602060048201526084602482018190527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448301527f6e6451756575655769746864726177616c3a2077697468647261776572206d7560648301527f73742062652073616d652061646472657373206173207374616b657220696620908201527f746869726450617274795472616e7366657273466f7262696464656e2061726560a482015263081cd95d60e21b60c482015260e401610abc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638c80d4e588868481518110612c8957612c89615311565b6020026020010151868581518110612ca357612ca3615311565b60200260200101516040518463ffffffff1660e01b8152600401612cc9939291906157b9565b600060405180830381600087803b158015612ce357600080fd5b505af1158015612cf7573d6000803e3d6000fd5b505050505b60010161295a565b506001600160a01b0386166000908152609f60205260408120805491829190612d2c8361533d565b919050555060006040518060e00160405280896001600160a01b03168152602001886001600160a01b03168152602001876001600160a01b031681526020018381526020014363ffffffff1681526020018681526020018581525090506000612d9482611641565b6000818152609e602052604090819020805460ff19166001179055519091507f9009ab153e8014fbfb02f2217f5cde7aa7f9ad734ae85ca3ee3f4ca2fdd499f990612de290839085906157dd565b60405180910390a198975050505050505050565b6213c680612e0a60608301604084016157f6565b63ffffffff161115612ebf5760405162461bcd60e51b815260206004820152606c60248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a207374616b65724f70744f757457696e646f77426c6f636b732060648201527f63616e6e6f74206265203e204d41585f5354414b45525f4f50545f4f55545f5760848201526b494e444f575f424c4f434b5360a01b60a482015260c401610abc565b6001600160a01b0382166000908152609960205260409081902060010154600160a01b900463ffffffff1690612efb90606084019084016157f6565b63ffffffff161015612f915760405162461bcd60e51b815260206004820152605360248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a207374616b65724f70744f757457696e646f77426c6f636b732060648201527218d85b9b9bdd08189948191958dc99585cd959606a1b608482015260a401610abc565b6001600160a01b03821660009081526099602052604090208190612fb58282615833565b505060405133907ffebe5cd24b2cbc7b065b9d0fdeb904461e4afcff57dd57acda1e7832031ba7ac90611b379084906153f8565b606654600090600190811614156130125760405162461bcd60e51b8152600401610abc90615358565b6001600160a01b038085166000908152609960205260409020600101541680158015906130485750336001600160a01b03821614155b801561305d5750336001600160a01b03861614155b156131ca5742846020015110156130dc5760405162461bcd60e51b815260206004820152603760248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2061707060448201527f726f766572207369676e617475726520657870697265640000000000000000006064820152608401610abc565b6001600160a01b0381166000908152609c6020908152604080832086845290915290205460ff16156131765760405162461bcd60e51b815260206004820152603760248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2061707060448201527f726f76657253616c7420616c7265616479207370656e740000000000000000006064820152608401610abc565b6001600160a01b0381166000908152609c6020908152604080832086845282528220805460ff191660011790558501516131b79088908890859088906109ce565b90506131c8828287600001516141a3565b505b6001600160a01b038681166000818152609a602052604080822080546001600160a01b031916948a169485179055517fc3ee9f2e5fda98e8066a1f745b2df9285f416fe98cf2559cd21484b3d87433049190a360008061322988611bfc565b9150915060005b825181101561136257613277888a85848151811061325057613250615311565b602002602001015185858151811061326a5761326a615311565b602002602001015161393e565b600101613230565b6001600160a01b03811661330d5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610abc565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038085166000908152609860209081526040808320938616835292905290812080548392906133ad9084906157a2565b92505081905550836001600160a01b03167f6909600037b75d7b4733aedd815442b5ec018a827751c832aaff64eba5d6d2dd848484604051610f30939291906157b9565b6033546001600160a01b031633146117695760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610abc565b8281146134d35760405162461bcd60e51b815260206004820152604a60248201527f44656c65676174696f6e4d616e616765722e5f7365745374726174656779576960448201527f746864726177616c44656c6179426c6f636b733a20696e707574206c656e67746064820152690d040dad2e6dac2e8c6d60b31b608482015260a401610abc565b8260005b818110156136695760008686838181106134f3576134f3615311565b905060200201602081019061350891906149ff565b6001600160a01b038116600090815260a1602052604081205491925086868581811061353657613536615311565b90506020020135905062034bc08111156135fa5760405162461bcd60e51b815260206004820152607360248201527f44656c65676174696f6e4d616e616765722e5f7365745374726174656779576960448201527f746864726177616c44656c6179426c6f636b733a205f7769746864726177616c60648201527f44656c6179426c6f636b732063616e6e6f74206265203e204d41585f5749544860848201527244524157414c5f44454c41595f424c4f434b5360681b60a482015260c401610abc565b6001600160a01b038316600081815260a160209081526040918290208490558151928352820184905281018290527f0e7efa738e8b0ce6376a0c1af471655540d2e9a81647d7b09ed823018426576d9060600160405180910390a1505050806136629061533d565b90506134d7565b505050505050565b6065546001600160a01b031615801561369257506001600160a01b03821615155b6137145760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610abc565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26137578261327f565b5050565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b62034bc08111156138fd5760405162461bcd60e51b815260206004820152607160248201527f44656c65676174696f6e4d616e616765722e5f7365744d696e5769746864726160448201527f77616c44656c6179426c6f636b733a205f6d696e5769746864726177616c446560648201527f6c6179426c6f636b732063616e6e6f74206265203e204d41585f5749544844526084820152704157414c5f44454c41595f424c4f434b5360781b60a482015260c401610abc565b609d5460408051918252602082018390527fafa003cd76f87ff9d62b35beea889920f33c0c42b8d45b74954d61d50f4b6b69910160405180910390a1609d55565b6001600160a01b0380851660009081526098602090815260408083209386168352929052908120805483929061397590849061578a565b92505081905550836001600160a01b03167f1ec042c965e2edd7107b51188ee0f383e22e76179041ab3a9d18ff151405166c848484604051610f30939291906157b9565b60006139c76105f387615896565b6000818152609e602052604090205490915060ff16613a485760405162461bcd60e51b815260206004820152604360248201526000805160206159c883398151915260448201527f645769746864726177616c3a20616374696f6e206973206e6f7420696e20717560648201526265756560e81b608482015260a401610abc565b609d544390613a5d60a0890160808a016157f6565b63ffffffff16613a6d919061578a565b1115613af55760405162461bcd60e51b815260206004820152605f60248201526000805160206159c883398151915260448201527f645769746864726177616c3a206d696e5769746864726177616c44656c61794260648201527f6c6f636b7320706572696f6420686173206e6f74207965742070617373656400608482015260a401610abc565b613b0560608701604088016149ff565b6001600160a01b0316336001600160a01b031614613b925760405162461bcd60e51b815260206004820152605060248201526000805160206159c883398151915260448201527f645769746864726177616c3a206f6e6c7920776974686472617765722063616e60648201526f1031b7b6b83632ba329030b1ba34b7b760811b608482015260a401610abc565b8115613c1457613ba560a08701876153af565b85149050613c145760405162461bcd60e51b815260206004820152604260248201526000805160206159c883398151915260448201527f645769746864726177616c3a20696e707574206c656e677468206d69736d61746064820152610c6d60f31b608482015260a401610abc565b6000818152609e60205260409020805460ff191690558115613d795760005b613c4060a08801886153af565b9050811015613d73574360a16000613c5b60a08b018b6153af565b85818110613c6b57613c6b615311565b9050602002016020810190613c8091906149ff565b6001600160a01b03168152602081019190915260400160002054613caa60a08a0160808b016157f6565b63ffffffff16613cba919061578a565b1115613cd85760405162461bcd60e51b8152600401610abc906158a2565b613d6b613ce860208901896149ff565b33613cf660a08b018b6153af565b85818110613d0657613d06615311565b9050602002016020810190613d1b91906149ff565b613d2860c08c018c6153af565b86818110613d3857613d38615311565b905060200201358a8a87818110613d5157613d51615311565b9050602002016020810190613d6691906149ff565b61435d565b600101613c33565b50614168565b336000908152609a60205260408120546001600160a01b0316905b613da160a08901896153af565b9050811015614165574360a16000613dbc60a08c018c6153af565b85818110613dcc57613dcc615311565b9050602002016020810190613de191906149ff565b6001600160a01b03168152602081019190915260400160002054613e0b60a08b0160808c016157f6565b63ffffffff16613e1b919061578a565b1115613e395760405162461bcd60e51b8152600401610abc906158a2565b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac0613e5b60a08a018a6153af565b83818110613e6b57613e6b615311565b9050602002016020810190613e8091906149ff565b6001600160a01b03161415613fd0576000613e9e60208a018a6149ff565b905060006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016630e81073c83613edf60c08e018e6153af565b87818110613eef57613eef615311565b6040516001600160e01b031960e087901b1681526001600160a01b03909416600485015260200291909101356024830152506044016020604051808303816000875af1158015613f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f67919061565c565b6001600160a01b038084166000908152609a6020526040902054919250168015613fc857613fc88184613f9d60a08f018f6153af565b88818110613fad57613fad615311565b9050602002016020810190613fc291906149ff565b8561393e565b50505061415d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c4623ea13389898581811061401257614012615311565b905060200201602081019061402791906149ff565b61403460a08d018d6153af565b8681811061404457614044615311565b905060200201602081019061405991906149ff565b61406660c08e018e6153af565b8781811061407657614076615311565b60405160e088901b6001600160e01b03191681526001600160a01b03968716600482015294861660248601529290941660448401526020909102013560648201526084019050600060405180830381600087803b1580156140d657600080fd5b505af11580156140ea573d6000803e3d6000fd5b505050506001600160a01b0382161561415d5761415d823361410f60a08c018c6153af565b8581811061411f5761411f615311565b905060200201602081019061413491906149ff565b61414160c08d018d6153af565b8681811061415157614151615311565b9050602002013561393e565b600101613d94565b50505b6040518181527fc97098c2f658800b4df29001527f7324bcdffcf6e8751a699ab920a1eced5b1d9060200160405180910390a1505050505050565b6001600160a01b0383163b156142bd57604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e906141e3908690869060040161592a565b602060405180830381865afa158015614200573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142249190615987565b6001600160e01b031916146110a35760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a401610abc565b826001600160a01b03166142d1838361449d565b6001600160a01b0316146110a35760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a401610abc565b6001600160a01b03831673beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac014156144085760405162387b1360e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063387b1300906143d1908890889087906004016157b9565b600060405180830381600087803b1580156143eb57600080fd5b505af11580156143ff573d6000803e3d6000fd5b50505050614496565b60405163c608c7f360e01b81526001600160a01b03858116600483015284811660248301526044820184905282811660648301527f0000000000000000000000000000000000000000000000000000000000000000169063c608c7f390608401600060405180830381600087803b15801561448257600080fd5b505af1158015611362573d6000803e3d6000fd5b5050505050565b60008060006144ac85856144b9565b915091506109c681614529565b6000808251604114156144f05760208301516040840151606085015160001a6144e4878285856146e4565b94509450505050614522565b82516040141561451a576020830151604084015161450f8683836147d1565b935093505050614522565b506000905060025b9250929050565b600081600481111561453d5761453d6159b1565b14156145465750565b600181600481111561455a5761455a6159b1565b14156145a85760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610abc565b60028160048111156145bc576145bc6159b1565b141561460a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610abc565b600381600481111561461e5761461e6159b1565b14156146775760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610abc565b600481600481111561468b5761468b6159b1565b1415610fee5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610abc565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561471b57506000905060036147c8565b8460ff16601b1415801561473357508460ff16601c14155b1561474457506000905060046147c8565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614798573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166147c1576000600192509250506147c8565b9150600090505b94509492505050565b6000806001600160ff1b038316816147ee60ff86901c601b61578a565b90506147fc878288856146e4565b935093505050935093915050565b60008083601f84011261481c57600080fd5b5081356001600160401b0381111561483357600080fd5b6020830191508360208260051b850101111561452257600080fd5b6000806020838503121561486157600080fd5b82356001600160401b0381111561487757600080fd5b6148838582860161480a565b90969095509350505050565b6001600160a01b0381168114610fee57600080fd5b80356148af8161488f565b919050565b600080600080600060a086880312156148cc57600080fd5b85356148d78161488f565b945060208601356148e78161488f565b935060408601356148f78161488f565b94979396509394606081013594506080013592915050565b6020808252825182820181905260009190848201906040850190845b818110156149475783518352928401929184019160010161492b565b50909695505050505050565b60006060828403121561496557600080fd5b50919050565b60008083601f84011261497d57600080fd5b5081356001600160401b0381111561499457600080fd5b60208301915083602082850101111561452257600080fd5b6000806000608084860312156149c157600080fd5b6149cb8585614953565b925060608401356001600160401b038111156149e657600080fd5b6149f28682870161496b565b9497909650939450505050565b600060208284031215614a1157600080fd5b8135614a1c8161488f565b9392505050565b600080600060608486031215614a3857600080fd5b8335614a438161488f565b92506020840135614a538161488f565b929592945050506040919091013590565b600060208284031215614a7657600080fd5b5035919050565b60008060008060408587031215614a9357600080fd5b84356001600160401b0380821115614aaa57600080fd5b614ab68883890161480a565b90965094506020870135915080821115614acf57600080fd5b50614adc8782880161480a565b95989497509550505050565b60008060008060008060008060c0898b031215614b0457600080fd5b8835614b0f8161488f565b97506020890135614b1f8161488f565b9650604089013595506060890135945060808901356001600160401b0380821115614b4957600080fd5b614b558c838d0161480a565b909650945060a08b0135915080821115614b6e57600080fd5b50614b7b8b828c0161480a565b999c989b5096995094979396929594505050565b6000806000806000806000806080898b031215614bab57600080fd5b88356001600160401b0380821115614bc257600080fd5b614bce8c838d0161480a565b909a50985060208b0135915080821115614be757600080fd5b614bf38c838d0161480a565b909850965060408b0135915080821115614c0c57600080fd5b614c188c838d0161480a565b909650945060608b0135915080821115614b6e57600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715614c6957614c69614c31565b60405290565b604080519081016001600160401b0381118282101715614c6957614c69614c31565b604051601f8201601f191681016001600160401b0381118282101715614cb957614cb9614c31565b604052919050565b63ffffffff81168114610fee57600080fd5b80356148af81614cc1565b60006001600160401b03821115614cf757614cf7614c31565b5060051b60200190565b600082601f830112614d1257600080fd5b81356020614d27614d2283614cde565b614c91565b82815260059290921b84018101918181019086841115614d4657600080fd5b8286015b84811015614d6a578035614d5d8161488f565b8352918301918301614d4a565b509695505050505050565b600082601f830112614d8657600080fd5b81356020614d96614d2283614cde565b82815260059290921b84018101918181019086841115614db557600080fd5b8286015b84811015614d6a5780358352918301918301614db9565b600060e08284031215614de257600080fd5b614dea614c47565b9050614df5826148a4565b8152614e03602083016148a4565b6020820152614e14604083016148a4565b604082015260608201356060820152614e2f60808301614cd3565b608082015260a08201356001600160401b0380821115614e4e57600080fd5b614e5a85838601614d01565b60a084015260c0840135915080821115614e7357600080fd5b50614e8084828501614d75565b60c08301525092915050565b600060208284031215614e9e57600080fd5b81356001600160401b03811115614eb457600080fd5b614ec084828501614dd0565b949350505050565b600060208284031215614eda57600080fd5b813560ff81168114614a1c57600080fd5b8015158114610fee57600080fd5b600080600080600060808688031215614f1157600080fd5b85356001600160401b0380821115614f2857600080fd5b9087019060e0828a031215614f3c57600080fd5b90955060208701359080821115614f5257600080fd5b50614f5f8882890161480a565b909550935050604086013591506060860135614f7a81614eeb565b809150509295509295909350565b60008060408385031215614f9b57600080fd5b8235614fa68161488f565b91506020830135614fb68161488f565b809150509250929050565b600060408284031215614fd357600080fd5b614fdb614c6f565b905081356001600160401b0380821115614ff457600080fd5b818401915084601f83011261500857600080fd5b813560208282111561501c5761501c614c31565b61502e601f8301601f19168201614c91565b9250818352868183860101111561504457600080fd5b8181850182850137600081838501015282855280860135818601525050505092915050565b600080600080600060a0868803121561508157600080fd5b853561508c8161488f565b9450602086013561509c8161488f565b935060408601356001600160401b03808211156150b857600080fd5b6150c489838a01614fc1565b945060608801359150808211156150da57600080fd5b506150e788828901614fc1565b95989497509295608001359392505050565b6000806040838503121561510c57600080fd5b82356151178161488f565b915060208301356001600160401b0381111561513257600080fd5b61513e85828601614d01565b9150509250929050565b600081518084526020808501945080840160005b838110156151785781518752958201959082019060010161515c565b509495945050505050565b602081526000614a1c6020830184615148565b600080602083850312156151a957600080fd5b82356001600160401b038111156151bf57600080fd5b6148838582860161496b565b600080604083850312156151de57600080fd5b82356151e98161488f565b946020939093013593505050565b6000806000806080858703121561520d57600080fd5b84356152188161488f565b935060208501359250604085013561522f8161488f565b9396929550929360600135925050565b600081518084526020808501945080840160005b838110156151785781516001600160a01b031687529582019590820190600101615253565b60408152600061528b604083018561523f565b82810360208401526112208185615148565b6000806000606084860312156152b257600080fd5b83356152bd8161488f565b925060208401356001600160401b038111156152d857600080fd5b6152e486828701614fc1565b925050604084013590509250925092565b60006060828403121561530757600080fd5b614a1c8383614953565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561535157615351615327565b5060010190565b60208082526019908201527f5061757361626c653a20696e6465782069732070617573656400000000000000604082015260600190565b60008235605e198336030181126153a557600080fd5b9190910192915050565b6000808335601e198436030181126153c657600080fd5b8301803591506001600160401b038211156153e057600080fd5b6020019150600581901b360382131561452257600080fd5b6060810182356154078161488f565b6001600160a01b0390811683526020840135906154238261488f565b166020830152604083013561543781614cc1565b63ffffffff811660408401525092915050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60006020828403121561548b57600080fd5b8151614a1c8161488f565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60208082526037908201527f44656c65676174696f6e4d616e616765723a206f6e6c7953747261746567794d60408201527f616e616765724f72456967656e506f644d616e61676572000000000000000000606082015260800190565b60006020828403121561554f57600080fd5b8151614a1c81614eeb565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b6000823560de198336030181126153a557600080fd5b6000602082840312156155ca57600080fd5b8135614a1c81614eeb565b600060018060a01b03808351168452806020840151166020850152806040840151166040850152506060820151606084015263ffffffff608083015116608084015260a082015160e060a085015261563060e085018261523f565b905060c083015184820360c08601526112208282615148565b602081526000614a1c60208301846155d5565b60006020828403121561566e57600080fd5b5051919050565b600082601f83011261568657600080fd5b81516020615696614d2283614cde565b82815260059290921b840181019181810190868411156156b557600080fd5b8286015b84811015614d6a57805183529183019183016156b9565b600080604083850312156156e357600080fd5b82516001600160401b03808211156156fa57600080fd5b818501915085601f83011261570e57600080fd5b8151602061571e614d2283614cde565b82815260059290921b8401810191818101908984111561573d57600080fd5b948201945b838610156157645785516157558161488f565b82529482019490820190615742565b9188015191965090935050508082111561577d57600080fd5b5061513e85828601615675565b6000821982111561579d5761579d615327565b500190565b6000828210156157b4576157b4615327565b500390565b6001600160a01b039384168152919092166020820152604081019190915260600190565b828152604060208201526000614ec060408301846155d5565b60006020828403121561580857600080fd5b8135614a1c81614cc1565b80546001600160a01b0319166001600160a01b0392909216919091179055565b813561583e8161488f565b6158488183615813565b5060018101602083013561585b8161488f565b6158658183615813565b50604083013561587481614cc1565b815463ffffffff60a01b191660a09190911b63ffffffff60a01b161790555050565b60006117513683614dd0565b6020808252606e908201526000805160206159c883398151915260408201527f645769746864726177616c3a207769746864726177616c44656c6179426c6f6360608201527f6b7320706572696f6420686173206e6f74207965742070617373656420666f7260808201526d207468697320737472617465677960901b60a082015260c00190565b82815260006020604081840152835180604085015260005b8181101561595e57858101830151858201606001528201615942565b81811115615970576000606083870101525b50601f01601f191692909201606001949350505050565b60006020828403121561599957600080fd5b81516001600160e01b031981168114614a1c57600080fd5b634e487b7160e01b600052602160045260246000fdfe44656c65676174696f6e4d616e616765722e5f636f6d706c6574655175657565a264697066735822122046f59d0774fea296e76e107662bfe5a0f076e0013aabe21beb6ded4a9b0f61a864736f6c634300080c0033", } // DelegationManagerABI is the input ABI used to generate the binding from. diff --git a/pkg/bindings/EigenPod/binding.go b/pkg/bindings/EigenPod/binding.go index f421d0a34..7016ff63f 100644 --- a/pkg/bindings/EigenPod/binding.go +++ b/pkg/bindings/EigenPod/binding.go @@ -29,40 +29,51 @@ var ( _ = abi.ConvertType ) +// BeaconChainProofsBalanceContainerProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsBalanceContainerProof struct { + BalanceContainerRoot [32]byte + Proof []byte +} + +// BeaconChainProofsBalanceProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsBalanceProof struct { + PubkeyHash [32]byte + BalanceRoot [32]byte + Proof []byte +} + // BeaconChainProofsStateRootProof is an auto generated low-level Go binding around an user-defined struct. type BeaconChainProofsStateRootProof struct { BeaconStateRoot [32]byte Proof []byte } -// BeaconChainProofsWithdrawalProof is an auto generated low-level Go binding around an user-defined struct. -type BeaconChainProofsWithdrawalProof struct { - WithdrawalProof []byte - SlotProof []byte - ExecutionPayloadProof []byte - TimestampProof []byte - HistoricalSummaryBlockRootProof []byte - BlockRootIndex uint64 - HistoricalSummaryIndex uint64 - WithdrawalIndex uint64 - BlockRoot [32]byte - SlotRoot [32]byte - TimestampRoot [32]byte - ExecutionPayloadRoot [32]byte +// BeaconChainProofsValidatorProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsValidatorProof struct { + ValidatorFields [][32]byte + Proof []byte +} + +// IEigenPodCheckpoint is an auto generated low-level Go binding around an user-defined struct. +type IEigenPodCheckpoint struct { + BeaconBlockRoot [32]byte + ProofsRemaining *big.Int + PodBalanceGwei uint64 + BalanceDeltasGwei *big.Int } // IEigenPodValidatorInfo is an auto generated low-level Go binding around an user-defined struct. type IEigenPodValidatorInfo struct { - ValidatorIndex uint64 - RestakedBalanceGwei uint64 - MostRecentBalanceUpdateTimestamp uint64 - Status uint8 + ValidatorIndex uint64 + RestakedBalanceGwei uint64 + LastCheckpointedAt uint64 + Status uint8 } // EigenPodMetaData contains all meta data concerning the EigenPod contract. var EigenPodMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_ethPOS\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"},{\"name\":\"_delayedWithdrawalRouter\",\"type\":\"address\",\"internalType\":\"contractIDelayedWithdrawalRouter\"},{\"name\":\"_eigenPodManager\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"},{\"name\":\"_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_GENESIS_TIME\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"GENESIS_TIME\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"activateRestaking\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delayedWithdrawalRouter\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDelayedWithdrawalRouter\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasRestaked\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"mostRecentWithdrawalTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nonBeaconChainETHBalanceWei\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"provenWithdrawal\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recoverTokens\",\"inputs\":[{\"name\":\"tokenList\",\"type\":\"address[]\",\"internalType\":\"contractIERC20[]\"},{\"name\":\"amountsToWithdraw\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"sumOfPartialWithdrawalsClaimedGwei\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorPubkeyHashToInfo\",\"inputs\":[{\"name\":\"validatorPubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"mostRecentBalanceUpdateTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorPubkeyToInfo\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"mostRecentBalanceUpdateTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"pubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifyAndProcessWithdrawals\",\"inputs\":[{\"name\":\"oracleTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"withdrawalProofs\",\"type\":\"tuple[]\",\"internalType\":\"structBeaconChainProofs.WithdrawalProof[]\",\"components\":[{\"name\":\"withdrawalProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"slotProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"executionPayloadProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"timestampProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"historicalSummaryBlockRootProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"blockRootIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"historicalSummaryIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"withdrawalIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blockRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"slotRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"timestampRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"executionPayloadRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"validatorFieldsProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"validatorFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"},{\"name\":\"withdrawalFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyBalanceUpdates\",\"inputs\":[{\"name\":\"oracleTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"validatorIndices\",\"type\":\"uint40[]\",\"internalType\":\"uint40[]\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"validatorFieldsProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"validatorFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyWithdrawalCredentials\",\"inputs\":[{\"name\":\"oracleTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"validatorIndices\",\"type\":\"uint40[]\",\"internalType\":\"uint40[]\"},{\"name\":\"validatorFieldsProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"validatorFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawBeforeRestaking\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawNonBeaconChainETHBalanceWei\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amountToWithdraw\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawRestakedBeaconChainETH\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amountWei\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawableRestakedExecutionLayerGwei\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"EigenPodStaked\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FullWithdrawalRedeemed\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"},{\"name\":\"withdrawalTimestamp\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"withdrawalAmountGwei\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NonBeaconChainETHReceived\",\"inputs\":[{\"name\":\"amountReceived\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NonBeaconChainETHWithdrawn\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amountWithdrawn\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PartialWithdrawalRedeemed\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"},{\"name\":\"withdrawalTimestamp\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"partialWithdrawalAmountGwei\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RestakedBeaconChainETHWithdrawn\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RestakingActivated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorBalanceUpdated\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"},{\"name\":\"balanceTimestamp\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"newValidatorBalanceGwei\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRestaked\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"}],\"anonymous\":false}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162005fc038038062005fc083398101604081905262000035916200016f565b6001600160a01b0380861660805284811660a052831660c0526001600160401b0380831660e0528116610100526200006c62000077565b5050505050620001e7565b600054610100900460ff1615620000e45760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000137576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b03811681146200014f57600080fd5b50565b80516001600160401b03811681146200016a57600080fd5b919050565b600080600080600060a086880312156200018857600080fd5b8551620001958162000139565b6020870151909550620001a88162000139565b6040870151909450620001bb8162000139565b9250620001cb6060870162000152565b9150620001db6080870162000152565b90509295509295909350565b60805160a05160c05160e05161010051615cde620002e2600039600081816105b501528181612030015281816120e7015261213f015260008181610275015281816125d00152818161260401528181612c3001528181612c5d015281816143a401526143df01526000818161036d01528181610614015281816107a701528181610aef01528181610c4401528181610dcc01528181610f87015281816111680152818161129c0152818161146d015281816118ba01528181611a6201528181611ba101528181611d6e01528181611e58015261315401526000818161024101526133c60152600081816104520152610e970152615cde6000f3fe6080604052600436106101855760003560e01c806374cdd798116100d1578063c49074421161008a578063e251ef5211610064578063e251ef5214610563578063e2c8344514610583578063f2882461146105a3578063fe80b087146105d757600080fd5b8063c490744214610503578063c4d66de814610523578063dda3346c1461054357600080fd5b806374cdd7981461044057806387e0d289146104745780639b4e46341461049b578063a50600f4146104ae578063b522538a146104ce578063baa7145a146104ee57600080fd5b806334bea20a1161013e57806358eaee791161011857806358eaee791461038f5780635d3f65b6146103bc5780636fcd0e53146103dc5780637439841f1461040957600080fd5b806334bea20a146103005780633f65cf191461033b5780634665bcda1461035b57600080fd5b80630b18ff66146101db5780630cd4649e146102185780631a5057be1461022f5780631d905d5c146102635780633106ab53146102af5780633474aa16146102e057600080fd5b366101d657346037600082825461019c9190614c9f565b90915550506040513481527f6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf499060200160405180910390a1005b600080fd5b3480156101e757600080fd5b506033546101fb906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561022457600080fd5b5061022d6105fb565b005b34801561023b57600080fd5b506101fb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561026f57600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160401b03909116815260200161020f565b3480156102bb57600080fd5b506034546102d090600160401b900460ff1681565b604051901515815260200161020f565b3480156102ec57600080fd5b50603454610297906001600160401b031681565b34801561030c57600080fd5b506102d061031b366004614cdc565b603560209081526000928352604080842090915290825290205460ff1681565b34801561034757600080fd5b5061022d610356366004614d6f565b610764565b34801561036757600080fd5b506101fb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561039b57600080fd5b506103af6103aa366004614e80565b610caf565b60405161020f9190614ef9565b3480156103c857600080fd5b50603854610297906001600160401b031681565b3480156103e857600080fd5b506103fc6103f7366004614f07565b610d14565b60405161020f9190614f20565b34801561041557600080fd5b506103af610424366004614f07565b600090815260366020526040902054600160c01b900460ff1690565b34801561044c57600080fd5b506101fb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561048057600080fd5b5060335461029790600160a01b90046001600160401b031681565b61022d6104a9366004614f68565b610dc1565b3480156104ba57600080fd5b5061022d6104c9366004614fdb565b610f6e565b3480156104da57600080fd5b506103fc6104e9366004614e80565b611304565b3480156104fa57600080fd5b5061022d6113f7565b34801561050f57600080fd5b5061022d61051e366004615085565b611462565b34801561052f57600080fd5b5061022d61053e3660046150b1565b61169f565b34801561054f57600080fd5b5061022d61055e3660046151cb565b611877565b34801561056f57600080fd5b5061022d61057e36600461529c565b611a4a565b34801561058f57600080fd5b5061022d61059e366004615085565b611e15565b3480156105af57600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b3480156105e357600080fd5b506105ed60375481565b60405190815260200161020f565b604051635ac86ab760e01b8152600260048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa158015610663573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106879190615397565b156106ad5760405162461bcd60e51b81526004016106a4906153b9565b60405180910390fd5b6033546001600160a01b031633146106d75760405162461bcd60e51b81526004016106a490615416565b603454600160401b900460ff16156107015760405162461bcd60e51b81526004016106a49061545e565b6034805460ff60401b1916600160401b179055603354610729906001600160a01b0316611ff8565b6033546040516001600160a01b03909116907fca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd90600090a250565b6033546001600160a01b0316331461078e5760405162461bcd60e51b81526004016106a490615416565b604051635ac86ab760e01b8152600260048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa1580156107f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081a9190615397565b156108375760405162461bcd60e51b81526004016106a4906153b9565b603454600160401b900460ff166108af5760405162461bcd60e51b815260206004820152603660248201527f456967656e506f642e686173456e61626c656452657374616b696e673a2072656044820152751cdd185ada5b99c81a5cc81b9bdd08195b98589b195960521b60648201526084016106a4565b85841480156108bd57508382145b61094d5760405162461bcd60e51b815260206004820152605560248201527f456967656e506f642e7665726966795769746864726177616c43726564656e7460448201527f69616c733a2076616c696461746f72496e646963657320616e642070726f6f666064820152740e640daeae6e840c4ca40e6c2daca40d8cadccee8d605b1b608482015260a4016106a4565b603354600160a01b90046001600160401b031615806109a2575060335461098c9061098790600160a01b90046001600160401b031661202c565b612116565b6001600160401b0316896001600160401b031610155b610a2e5760405162461bcd60e51b815260206004820152605160248201527f456967656e506f642e7665726966795769746864726177616c43726564656e7460448201527f69616c733a2070726f6f66206d75737420626520696e207468652065706f63686064820152701030b33a32b91030b1ba34bb30ba34b7b760791b608482015260a4016106a4565b42610a44613f486001600160401b038c16614c9f565b1015610acd5760405162461bcd60e51b815260206004820152604c60248201527f456967656e506f642e7665726966795769746864726177616c43726564656e7460448201527f69616c733a207370656369666965642074696d657374616d7020697320746f6f60648201526b0819985c881a5b881c185cdd60a21b608482015260a4016106a4565b60405163d1c64cc960e01b81526001600160401b038a166004820152610b76907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d1c64cc990602401602060405180830381865afa158015610b3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6291906154ad565b8935610b7160208c018c6154c6565b612163565b6000805b87811015610c1a57610bfc8b8b358b8b85818110610b9a57610b9a61550c565b9050602002016020810190610baf9190615522565b8a8a86818110610bc157610bc161550c565b9050602002810190610bd391906154c6565b8a8a88818110610be557610be561550c565b9050602002810190610bf79190615549565b6122f1565b610c069083614c9f565b915080610c1281615592565b915050610b7a565b5060335460405163030b147160e61b81526001600160a01b039182166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000009091169063c2c51c40906044015b600060405180830381600087803b158015610c8b57600080fd5b505af1158015610c9f573d6000803e3d6000fd5b5050505050505050505050505050565b600080610cf184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506127ab92505050565b600090815260366020526040902054600160c01b900460ff169150505b92915050565b610d3c6040805160808101825260008082526020820181905291810182905290606082015290565b600082815260366020908152604091829020825160808101845281546001600160401b038082168352600160401b8204811694830194909452600160801b810490931693810193909352906060830190600160c01b900460ff166002811115610da757610da7614ec1565b6002811115610db857610db8614ec1565b90525092915050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610e095760405162461bcd60e51b81526004016106a4906155ad565b346801bc16d674ec80000014610e955760405162461bcd60e51b8152602060048201526044602482018190527f456967656e506f642e7374616b653a206d75737420696e697469616c6c792073908201527f74616b6520666f7220616e792076616c696461746f72207769746820333220656064820152633a3432b960e11b608482015260a4016106a4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663228951186801bc16d674ec8000008787610ed86128a5565b8888886040518863ffffffff1660e01b8152600401610efc9695949392919061567f565b6000604051808303818588803b158015610f1557600080fd5b505af1158015610f29573d6000803e3d6000fd5b50505050507f606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e238585604051610f5f9291906156ce565b60405180910390a15050505050565b604051635ac86ab760e01b8152600360048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa158015610fd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ffa9190615397565b156110175760405162461bcd60e51b81526004016106a4906153b9565b868414801561102557508382145b6110ae5760405162461bcd60e51b815260206004820152604e60248201527f456967656e506f642e76657269667942616c616e6365557064617465733a207660448201527f616c696461746f72496e646963657320616e642070726f6f6673206d7573742060648201526d0c4ca40e6c2daca40d8cadccee8d60931b608482015260a4016106a4565b426110c4613f486001600160401b038c16614c9f565b10156111465760405162461bcd60e51b815260206004820152604560248201527f456967656e506f642e76657269667942616c616e6365557064617465733a207360448201527f70656369666965642074696d657374616d7020697320746f6f2066617220696e606482015264081c185cdd60da1b608482015260a4016106a4565b60405163d1c64cc960e01b81526001600160401b038a1660048201526111ea907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d1c64cc990602401602060405180830381865afa1580156111b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111db91906154ad565b8735610b7160208a018a6154c6565b6000805b8881101561128e576112708b8b8b8481811061120c5761120c61550c565b90506020020160208101906112219190615522565b8a358a8a868181106112355761123561550c565b905060200281019061124791906154c6565b8a8a888181106112595761125961550c565b905060200281019061126b9190615549565b6128ea565b61127a90836156e2565b91508061128681615592565b9150506111ee565b506033546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169163c2c51c4091166112d3633b9aca0085615723565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401610c71565b61132c6040805160808101825260008082526020820181905291810182905290606082015290565b6036600061136f85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506127ab92505050565b81526020808201929092526040908101600020815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b81049094169281019290925290916060830190600160c01b900460ff1660028111156113dc576113dc614ec1565b60028111156113ed576113ed614ec1565b9052509392505050565b6033546001600160a01b031633146114215760405162461bcd60e51b81526004016106a490615416565b603454600160401b900460ff161561144b5760405162461bcd60e51b81526004016106a49061545e565b603354611460906001600160a01b0316611ff8565b565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114aa5760405162461bcd60e51b81526004016106a4906155ad565b6114b8633b9aca00826157be565b156115425760405162461bcd60e51b815260206004820152604e60248201527f456967656e506f642e776974686472617752657374616b6564426561636f6e4360448201527f6861696e4554483a20616d6f756e74576569206d75737420626520612077686f60648201526d1b194811ddd95a48185b5bdd5b9d60921b608482015260a4016106a4565b6000611552633b9aca00836157d2565b6034549091506001600160401b03908116908216111561160b5760405162461bcd60e51b815260206004820152606260248201527f456967656e506f642e776974686472617752657374616b6564426561636f6e4360448201527f6861696e4554483a20616d6f756e74477765692065786365656473207769746860648201527f6472617761626c6552657374616b6564457865637574696f6e4c617965724777608482015261656960f01b60a482015260c4016106a4565b603480548291906000906116299084906001600160401b03166157e6565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550826001600160a01b03167f8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e8360405161168891815260200190565b60405180910390a261169a8383612dc8565b505050565b600054610100900460ff16158080156116bf5750600054600160ff909116105b806116d95750303b1580156116d9575060005460ff166001145b61173c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a4565b6000805460ff19166001179055801561175f576000805461ff0019166101001790555b6001600160a01b0382166117d25760405162461bcd60e51b815260206004820152603460248201527f456967656e506f642e696e697469616c697a653a20706f644f776e65722063616044820152736e6e6f74206265207a65726f206164647265737360601b60648201526084016106a4565b603380546001600160a01b0384166001600160a01b031990911681179091556034805460ff60401b1916600160401b1790556040517fca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd90600090a28015611873576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6033546001600160a01b031633146118a15760405162461bcd60e51b81526004016106a490615416565b604051635ac86ab760e01b8152600560048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa158015611909573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192d9190615397565b1561194a5760405162461bcd60e51b81526004016106a4906153b9565b82518451146119d55760405162461bcd60e51b815260206004820152604b60248201527f456967656e506f642e7265636f766572546f6b656e733a20746f6b656e4c697360448201527f7420616e6420616d6f756e7473546f5769746864726177206d7573742062652060648201526a0e6c2daca40d8cadccee8d60ab1b608482015260a4016106a4565b60005b8451811015611a4357611a31838583815181106119f7576119f761550c565b6020026020010151878481518110611a1157611a1161550c565b60200260200101516001600160a01b0316612dd29092919063ffffffff16565b80611a3b81615592565b9150506119d8565b5050505050565b604051635ac86ab760e01b81526004808201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa158015611ab1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ad59190615397565b15611af25760405162461bcd60e51b81526004016106a4906153b9565b8386148015611b0057508588145b8015611b0b57508782145b611b7f576040805162461bcd60e51b81526020600482015260248101919091527f456967656e506f642e766572696679416e6450726f636573735769746864726160448201527f77616c733a20696e70757473206d7573742062652073616d65206c656e67746860648201526084016106a4565b60405163d1c64cc960e01b81526001600160401b038c166004820152611c23907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d1c64cc990602401602060405180830381865afa158015611bf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1491906154ad565b8b35610b7160208e018e6154c6565b604080518082019091526000808252602082015260005b83811015611d23576000611cde8d358d8d85818110611c5b57611c5b61550c565b9050602002810190611c6d919061580e565b8c8c86818110611c7f57611c7f61550c565b9050602002810190611c9191906154c6565b8c8c88818110611ca357611ca361550c565b9050602002810190611cb59190615549565b8c8c8a818110611cc757611cc761550c565b9050602002810190611cd99190615549565b612e24565b80518451919250908490611cf3908390614c9f565b9052506020808201519084018051611d0c9083906156e2565b905250819050611d1b81615592565b915050611c3a565b50805115611d52576033548151611d52916001600160a01b031690611d4d90633b9aca009061582f565b61339c565b602081015115611e075760335460208201516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263c2c51c4092911690611da890633b9aca0090615723565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611dee57600080fd5b505af1158015611e02573d6000803e3d6000fd5b505050505b505050505050505050505050565b6033546001600160a01b03163314611e3f5760405162461bcd60e51b81526004016106a490615416565b604051635ac86ab760e01b8152600560048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb9190615397565b15611ee85760405162461bcd60e51b81526004016106a4906153b9565b603754821115611f995760405162461bcd60e51b815260206004820152606a60248201527f456967656e506f642e77697468647261776e6f6e426561636f6e436861696e4560448201527f544842616c616e63655765693a20616d6f756e74546f5769746864726177206960648201527f732067726561746572207468616e206e6f6e426561636f6e436861696e45544860848201526942616c616e636557656960b01b60a482015260c4016106a4565b8160376000828254611fab919061584e565b90915550506040518281526001600160a01b038416907f30420aacd028abb3c1fd03aba253ae725d6ddd52d16c9ac4cb5742cd43f530969060200160405180910390a261169a838361339c565b6033805467ffffffffffffffff60a01b19164263ffffffff16600160a01b021790556000603755612029814761339c565b50565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316826001600160401b031610156120d65760405162461bcd60e51b815260206004820152603760248201527f456967656e506f642e5f74696d657374616d70546f45706f63683a2074696d6560448201527f7374616d70206973206265666f72652067656e6573697300000000000000000060648201526084016106a4565b6120e2600c6020615865565b61210c7f0000000000000000000000000000000000000000000000000000000000000000846157e6565b610d0e9190615894565b6000612124600c6020615865565b61212f8360016158ba565b6121399190615865565b610d0e907f00000000000000000000000000000000000000000000000000000000000000006158ba565b61216f6003602061582f565b81146121ff5760405162461bcd60e51b815260206004820152605360248201527f426561636f6e436861696e50726f6f66732e7665726966795374617465526f6f60448201527f74416761696e73744c6174657374426c6f636b526f6f743a2050726f6f6620686064820152720c2e640d2dcc6dee4e4cac6e840d8cadccee8d606b1b608482015260a4016106a4565b61224482828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508892508791506003905061342a565b6122eb5760405162461bcd60e51b815260206004820152606660248201527f426561636f6e436861696e50726f6f66732e7665726966795374617465526f6f60448201527f74416761696e73744c6174657374426c6f636b526f6f743a20496e76616c696460648201527f206c617465737420626c6f636b2068656164657220726f6f74206d65726b6c6560848201526510383937b7b360d11b60a482015260c4016106a4565b50505050565b60008061233084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061344292505050565b6000818152603660209081526040808320815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b8104909416928101929092529394509192906060830190600160c01b900460ff16600281111561239f5761239f614ec1565b60028111156123b0576123b0614ec1565b90525090506000816060015160028111156123cd576123cd614ec1565b146124765760405162461bcd60e51b815260206004820152606760248201527f456967656e506f642e766572696679436f72726563745769746864726177616c60448201527f43726564656e7469616c733a2056616c696461746f72206d757374206265206960648201527f6e61637469766520746f2070726f7665207769746864726177616c2063726564608482015266656e7469616c7360c81b60a482015260c4016106a4565b61247e6128a5565b612487906158e5565b6124c386868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061346692505050565b1461254a5760405162461bcd60e51b815260206004820152604b60248201527f456967656e506f642e766572696679436f72726563745769746864726177616c60448201527f43726564656e7469616c733a2050726f6f66206973206e6f7420666f7220746860648201526a1a5cc8115a59d95b941bd960aa1b608482015260a4016106a4565b600061258886868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061347b92505050565b90506125988a87878b8b8e6134a0565b603980549060006125a883615592565b90915550506001606083015264ffffffffff891682526001600160401b038b811660408401527f00000000000000000000000000000000000000000000000000000000000000008116908216111561262e576001600160401b037f000000000000000000000000000000000000000000000000000000000000000016602083015261263e565b6001600160401b03811660208301525b6000838152603660209081526040918290208451815492860151938601516001600160401b03908116600160801b0267ffffffffffffffff60801b19958216600160401b026001600160801b0319909516919092161792909217928316821781556060850151859391929091839160ff60c01b191668ffffffffffffffffff60801b1990911617600160c01b8360028111156126dc576126dc614ec1565b02179055505060405164ffffffffff8b1681527f2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449915060200160405180910390a17f0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df898c84602001516040516127779392919064ffffffffff9390931683526001600160401b03918216602084015216604082015260600190565b60405180910390a1633b9aca0082602001516001600160401b031661279c919061582f565b9b9a5050505050505050505050565b600081516030146128345760405162461bcd60e51b815260206004820152604760248201527f456967656e506f642e5f63616c63756c61746556616c696461746f725075626b60448201527f657948617368206d75737420626520612034382d6279746520424c53207075626064820152666c6963206b657960c81b608482015260a4016106a4565b60405160029061284b908490600090602001615909565b60408051601f198184030181529082905261286591615938565b602060405180830381855afa158015612882573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d0e91906154ad565b60408051600160f81b60208201526000602182015230606090811b6bffffffffffffffffffffffff1916602c8301529101604051602081830303815290604052905090565b60008061292984848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061347b92505050565b9050600061296985858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061344292505050565b6000818152603660209081526040808320815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b8104909416928101929092529394509192906060830190600160c01b900460ff1660028111156129d8576129d8614ec1565b60028111156129e9576129e9614ec1565b8152505090508a6001600160401b031681604001516001600160401b031610612aa05760405162461bcd60e51b815260206004820152605c60248201527f456967656e506f642e76657269667942616c616e63655570646174653a20566160448201527f6c696461746f72732062616c616e63652068617320616c72656164792062656560648201527f6e207570646174656420666f7220746869732074696d657374616d7000000000608482015260a4016106a4565b600181606001516002811115612ab857612ab8614ec1565b14612b205760405162461bcd60e51b815260206004820152603260248201527f456967656e506f642e76657269667942616c616e63655570646174653a2056616044820152716c696461746f72206e6f742061637469766560701b60648201526084016106a4565b612b298b61202c565b6001600160401b0316612b6e8787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506136f792505050565b6001600160401b031611612c11576000836001600160401b031611612c115760405162461bcd60e51b815260206004820152604d60248201527f456967656e506f642e76657269667942616c616e63655570646174653a20766160448201527f6c696461746f7220697320776974686472617761626c6520627574206861732060648201526c3737ba103bb4ba34323930bbb760991b608482015260a4016106a4565b612c1f8987878b8b8f6134a0565b602081015160006001600160401b037f000000000000000000000000000000000000000000000000000000000000000081169086161115612c8157507f0000000000000000000000000000000000000000000000000000000000000000612c84565b50835b6001600160401b0380821660208086019182528f831660408088019182526000898152603690935290912086518154935192518516600160801b0267ffffffffffffffff60801b19938616600160401b026001600160801b031990951691909516179290921790811683178255606086015186939091839160ff60c01b191668ffffffffffffffffff60801b1990911617600160c01b836002811115612d2c57612d2c614ec1565b0217905550905050816001600160401b0316816001600160401b031614612db8577f0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df8c8e83604051612da39392919064ffffffffff9390931683526001600160401b03918216602084015216604082015260600190565b60405180910390a1612db5818361370f565b95505b5050505050979650505050505050565b611873828261372e565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261169a908490613847565b6040805180820190915260008082526020820152612e49612e44896159b9565b613919565b6033546001600160401b03600160a01b90910481169082161015612f0b5760405162461bcd60e51b815260206004820152606760248201527f456967656e506f642e70726f6f664973466f7256616c696454696d657374616d60448201527f703a20626561636f6e20636861696e2070726f6f66206d75737420626520617460648201527f206f72206166746572206d6f7374526563656e745769746864726177616c546960848201526606d657374616d760cc1b60a482015260c4016106a4565b6000612f19612e448b6159b9565b90506000612f5988888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061344292505050565b905060008082815260366020526040902054600160c01b900460ff166002811115612f8657612f86614ec1565b141561303d5760405162461bcd60e51b815260206004820152607460248201527f456967656e506f642e5f766572696679416e6450726f6365737357697468647260448201527f6177616c3a2056616c696461746f72206e657665722070726f76656e20746f2060648201527f68617665207769746864726177616c2063726564656e7469616c7320706f696e6084820152731d1959081d1bc81d1a1a5cc818dbdb9d1c9858dd60621b60a482015260c4016106a4565b60008181526035602090815260408083206001600160401b038616845290915290205460ff16156130fc5760405162461bcd60e51b815260206004820152605b60248201527f456967656e506f642e5f766572696679416e6450726f6365737357697468647260448201527f6177616c3a207769746864726177616c2068617320616c72656164792062656560648201527f6e2070726f76656e20666f7220746869732074696d657374616d700000000000608482015260a4016106a4565b6001603560008381526020019081526020016000206000846001600160401b03166001600160401b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055506131d98c87878e7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166344e71c806040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131d49190615af5565b613929565b600061321787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061434a92505050565b90506132278d8a8a8e8e866134a0565b600061326588888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061436292505050565b90506132a38a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506136f792505050565b6001600160401b03166132bd6132b88f6159b9565b61437a565b6001600160401b03161061337557603354600084815260366020908152604091829020825160808101845281546001600160401b038082168352600160401b8204811694830194909452600160801b81049093169381019390935261336a93869388938a936001600160a01b03909316928892916060830190600160c01b900460ff16600281111561335157613351614ec1565b600281111561336257613362614ec1565b90525061438c565b95505050505061338f565b60335461336a90839086906001600160a01b0316846145ca565b5098975050505050505050565b603354604051633036cd5360e21b81526001600160a01b03918216600482015283821660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063c0db354c9083906044016000604051808303818588803b15801561340d57600080fd5b505af1158015613421573d6000803e3d6000fd5b50505050505050565b6000836134388685856146a8565b1495945050505050565b6000816000815181106134575761345761550c565b60200260200101519050919050565b6000816001815181106134575761345761550c565b6000610d0e826002815181106134935761349361550c565b60200260200101516147f4565b6134ac60036002615bf6565b84146135375760405162461bcd60e51b815260206004820152604e60248201527f426561636f6e436861696e50726f6f66732e76657269667956616c696461746f60448201527f724669656c64733a2056616c696461746f72206669656c64732068617320696e60648201526d0c6dee4e4cac6e840d8cadccee8d60931b608482015260a4016106a4565b600561354560286001614c9f565b61354f9190614c9f565b61355a90602061582f565b82146135da5760405162461bcd60e51b815260206004820152604360248201527f426561636f6e436861696e50726f6f66732e76657269667956616c696461746f60448201527f724669656c64733a2050726f6f662068617320696e636f7272656374206c656e6064820152620cee8d60eb1b608482015260a4016106a4565b600064ffffffffff82166135f060286001614c9f565b600b901b179050600061363587878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061485b92505050565b905061367b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c925085915086905061342a565b6136ed5760405162461bcd60e51b815260206004820152603d60248201527f426561636f6e436861696e50726f6f66732e76657269667956616c696461746f60448201527f724669656c64733a20496e76616c6964206d65726b6c652070726f6f6600000060648201526084016106a4565b5050505050505050565b6000610d0e826007815181106134935761349361550c565b60006137276001600160401b03808416908516615c02565b9392505050565b8047101561377e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016106a4565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146137cb576040519150601f19603f3d011682016040523d82523d6000602084013e6137d0565b606091505b505090508061169a5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016106a4565b600061389c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614b089092919063ffffffff16565b80519091501561169a57808060200190518101906138ba9190615397565b61169a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106a4565b6000610d0e8261014001516147f4565b613934600280615bf6565b83146139a85760405162461bcd60e51b81526020600482015260496024820152600080516020615c8983398151915260448201527f616c3a207769746864726177616c4669656c64732068617320696e636f7272656064820152680c6e840d8cadccee8d60bb1b608482015260a4016106a4565b6139b4600d6002615bf6565b6139c460c0840160a08501615c41565b6001600160401b031610613a2e5760405162461bcd60e51b815260206004820152603f6024820152600080516020615c8983398151915260448201527f616c3a20626c6f636b526f6f74496e64657820697320746f6f206c617267650060648201526084016106a4565b613a3a60046002615bf6565b613a4b610100840160e08501615c41565b6001600160401b031610613ab7576040805162461bcd60e51b8152602060048201526024810191909152600080516020615c8983398151915260448201527f616c3a207769746864726177616c496e64657820697320746f6f206c6172676560648201526084016106a4565b613ac360186002615bf6565b613ad360e0840160c08501615c41565b6001600160401b031610613b4d5760405162461bcd60e51b81526020600482015260476024820152600080516020615c8983398151915260448201527f616c3a20686973746f726963616c53756d6d617279496e64657820697320746f6064820152666f206c6172676560c81b608482015260a4016106a4565b60006001600160401b038216613b65612e44856159b9565b6001600160401b031610613b7a576005613b7d565b60045b9050613b8a600482614c9f565b613b95906001614c9f565b613ba090602061582f565b613baa84806154c6565b905014613c1e5760405162461bcd60e51b81526020600482015260486024820152600080516020615c8983398151915260448201527f616c3a207769746864726177616c50726f6f662068617320696e636f727265636064820152670e840d8cadccee8d60c31b608482015260a4016106a4565b613c2a60046003614c9f565b613c3590602061582f565b613c4260408501856154c6565b905014613cbc5760405162461bcd60e51b815260206004820152604e6024820152600080516020615c8983398151915260448201527f616c3a20657865637574696f6e5061796c6f616450726f6f662068617320696e60648201526d0c6dee4e4cac6e840d8cadccee8d60931b608482015260a4016106a4565b613cc86003602061582f565b613cd560208501856154c6565b905014613d435760405162461bcd60e51b81526020600482015260426024820152600080516020615c8983398151915260448201527f616c3a20736c6f7450726f6f662068617320696e636f7272656374206c656e676064820152610e8d60f31b608482015260a4016106a4565b613d4e81602061582f565b613d5b60608501856154c6565b905014613dce5760405162461bcd60e51b81526020600482015260476024820152600080516020615c8983398151915260448201527f616c3a2074696d657374616d7050726f6f662068617320696e636f7272656374606482015266040d8cadccee8d60cb1b608482015260a4016106a4565b600d613ddc60186001614c9f565b613de7906005614c9f565b613df2906001614c9f565b613dfc9190614c9f565b613e0790602061582f565b613e1460808501856154c6565b905014613e9d5760405162461bcd60e51b81526020600482015260586024820152600080516020615c8983398151915260448201527f616c3a20686973746f726963616c53756d6d617279426c6f636b526f6f74507260648201527f6f6f662068617320696e636f7272656374206c656e6774680000000000000000608482015260a4016106a4565b6000613eaf60c0850160a08601615c41565b6001600160401b03166000613ec6600d6001614c9f565b613ed660e0880160c08901615c41565b6001600160401b0316901b600d613eef60186001614c9f565b613efa906001614c9f565b613f049190614c9f565b601b901b1717179050613f5f613f1d60808601866154c6565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925050506101008701358461342a565b613fd25760405162461bcd60e51b815260206004820152604a6024820152600080516020615c8983398151915260448201527f616c3a20496e76616c696420686973746f726963616c73756d6d617279206d656064820152693935b63290383937b7b360b11b608482015260a4016106a4565b614029613fe260208601866154c6565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506101008a013593506101208a01359250905061342a565b6140895760405162461bcd60e51b815260206004820152603d6024820152600080516020615c8983398151915260448201527f616c3a20496e76616c696420736c6f74206d65726b6c652070726f6f6600000060648201526084016106a4565b60496140e161409b60408701876154c6565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050506101008701356101608801358461342a565b6141535760405162461bcd60e51b81526020600482015260496024820152600080516020615c8983398151915260448201527f616c3a20496e76616c696420657865637574696f6e5061796c6f6164206d657260648201526835b63290383937b7b360b91b608482015260a4016106a4565b506141ab61416460608601866154c6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505050610160860135610140870135600961342a565b6142165760405162461bcd60e51b81526020600482015260426024820152600080516020615c8983398151915260448201527f616c3a20496e76616c69642074696d657374616d70206d65726b6c652070726f60648201526137b360f11b608482015260a4016106a4565b6000614229610100860160e08701615c41565b6001600160401b031661423e60046001614c9f565b600e901b179050600061428388888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061485b92505050565b90506142d361429287806154c6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505050610160880135838561342a565b61433f5760405162461bcd60e51b81526020600482015260436024820152600080516020615c8983398151915260448201527f616c3a20496e76616c6964207769746864726177616c206d65726b6c6520707260648201526237b7b360e91b608482015260a4016106a4565b505050505050505050565b6000610d0e826001815181106134935761349361550c565b6000610d0e826003815181106134935761349361550c565b6000602061210c8361012001516147f4565b604080518082019091526000808252602082015260007f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316846001600160401b0316111561440357507f0000000000000000000000000000000000000000000000000000000000000000614406565b50825b604080518082019091526000808252602082015261442482866157e6565b6001600160401b039081168252603480548492600091614446918591166158ba565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555061447882856020015161370f565b602082015260028460600151600281111561449557614495614ec1565b146144b757603980549060006144aa83615c5e565b9091555050600260608501525b600060208086018281528a83526036909152604091829020865181549251938801516001600160401b03908116600160801b0267ffffffffffffffff60801b19958216600160401b026001600160801b0319909516929091169190911792909217928316821781556060870151879391929091839160ff60c01b191668ffffffffffffffffff60801b1990911617600160c01b83600281111561455c5761455c614ec1565b0217905550506040805164ffffffffff8c1681526001600160401b038a8116602083015288168183015290516001600160a01b03891692507fb76a93bb649ece524688f1a01d184e0bbebcda58eae80c28a898bec3fb5a09639181900360600190a298975050505050505050565b60408051808201909152600080825260208201526040805164ffffffffff871681526001600160401b0380871660208301528416918101919091526001600160a01b038416907f8a7335714231dbd551aaba6314f4a97a14c201e53a3e25e1140325cdf67d7a4e9060600160405180910390a26038805483919060009061465b9084906001600160401b03166158ba565b92506101000a8154816001600160401b0302191690836001600160401b031602179055506040518060400160405280836001600160401b0316815260200160008152509050949350505050565b600083516000141580156146c75750602084516146c591906157be565b155b6147565760405162461bcd60e51b815260206004820152605460248201527f4d65726b6c652e70726f63657373496e636c7573696f6e50726f6f665368613260448201527f35363a2070726f6f66206c656e6774682073686f756c642062652061206e6f6e60648201527316bd32b9379036bab63a34b836329037b310199960611b608482015260a4016106a4565b604080516020808201909252848152905b855181116147ea5761477a6002856157be565b6147ad578151600052808601516020526020826040600060026107d05a03fa6147a257600080fd5b6002840493506147d8565b8086015160005281516020526020826040600060026107d05a03fa6147d157600080fd5b6002840493505b6147e3602082614c9f565b9050614767565b5051949350505050565b60f881901c60e882901c61ff00161760d882901c62ff0000161760c882901c63ff000000161764ff0000000060b883901c161765ff000000000060a883901c161766ff000000000000609883901c161767ff0000000000000060889290921c919091161790565b6000806002835161486c91906157d2565b90506000816001600160401b03811115614888576148886150ce565b6040519080825280602002602001820160405280156148b1578160200160208202803683370190505b50905060005b828110156149b8576002856148cc838361582f565b815181106148dc576148dc61550c565b6020026020010151868360026148f2919061582f565b6148fd906001614c9f565b8151811061490d5761490d61550c565b602002602001015160405160200161492f929190918252602082015260400190565b60408051601f198184030181529082905261494991615938565b602060405180830381855afa158015614966573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061498991906154ad565b82828151811061499b5761499b61550c565b6020908102919091010152806149b081615592565b9150506148b7565b506149c46002836157d2565b91505b8115614ae45760005b82811015614ad1576002826149e5838361582f565b815181106149f5576149f561550c565b602002602001015183836002614a0b919061582f565b614a16906001614c9f565b81518110614a2657614a2661550c565b6020026020010151604051602001614a48929190918252602082015260400190565b60408051601f1981840301815290829052614a6291615938565b602060405180830381855afa158015614a7f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190614aa291906154ad565b828281518110614ab457614ab461550c565b602090810291909101015280614ac981615592565b9150506149d0565b50614add6002836157d2565b91506149c7565b80600081518110614af757614af761550c565b602002602001015192505050919050565b6060614b178484600085614b1f565b949350505050565b606082471015614b805760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106a4565b6001600160a01b0385163b614bd75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106a4565b600080866001600160a01b03168587604051614bf39190615938565b60006040518083038185875af1925050503d8060008114614c30576040519150601f19603f3d011682016040523d82523d6000602084013e614c35565b606091505b5091509150614c45828286614c50565b979650505050505050565b60608315614c5f575081613727565b825115614c6f5782518084602001fd5b8160405162461bcd60e51b81526004016106a49190615c75565b634e487b7160e01b600052601160045260246000fd5b60008219821115614cb257614cb2614c89565b500190565b6001600160401b038116811461202957600080fd5b8035614cd781614cb7565b919050565b60008060408385031215614cef57600080fd5b823591506020830135614d0181614cb7565b809150509250929050565b600060408284031215614d1e57600080fd5b50919050565b60008083601f840112614d3657600080fd5b5081356001600160401b03811115614d4d57600080fd5b6020830191508360208260051b8501011115614d6857600080fd5b9250929050565b60008060008060008060008060a0898b031215614d8b57600080fd5b8835614d9681614cb7565b975060208901356001600160401b0380821115614db257600080fd5b614dbe8c838d01614d0c565b985060408b0135915080821115614dd457600080fd5b614de08c838d01614d24565b909850965060608b0135915080821115614df957600080fd5b614e058c838d01614d24565b909650945060808b0135915080821115614e1e57600080fd5b50614e2b8b828c01614d24565b999c989b5096995094979396929594505050565b60008083601f840112614e5157600080fd5b5081356001600160401b03811115614e6857600080fd5b602083019150836020828501011115614d6857600080fd5b60008060208385031215614e9357600080fd5b82356001600160401b03811115614ea957600080fd5b614eb585828601614e3f565b90969095509350505050565b634e487b7160e01b600052602160045260246000fd5b60038110614ef557634e487b7160e01b600052602160045260246000fd5b9052565b60208101610d0e8284614ed7565b600060208284031215614f1957600080fd5b5035919050565b60006080820190506001600160401b03808451168352806020850151166020840152806040850151166040840152506060830151614f616060840182614ed7565b5092915050565b600080600080600060608688031215614f8057600080fd5b85356001600160401b0380821115614f9757600080fd5b614fa389838a01614e3f565b90975095506020880135915080821115614fbc57600080fd5b50614fc988828901614e3f565b96999598509660400135949350505050565b60008060008060008060008060a0898b031215614ff757600080fd5b883561500281614cb7565b975060208901356001600160401b038082111561501e57600080fd5b61502a8c838d01614d24565b909950975060408b013591508082111561504357600080fd5b61504f8c838d01614d0c565b965060608b0135915080821115614df957600080fd5b6001600160a01b038116811461202957600080fd5b8035614cd781615065565b6000806040838503121561509857600080fd5b82356150a381615065565b946020939093013593505050565b6000602082840312156150c357600080fd5b813561372781615065565b634e487b7160e01b600052604160045260246000fd5b60405161018081016001600160401b0381118282101715615107576151076150ce565b60405290565b604051601f8201601f191681016001600160401b0381118282101715615135576151356150ce565b604052919050565b60006001600160401b03821115615156576151566150ce565b5060051b60200190565b600082601f83011261517157600080fd5b813560206151866151818361513d565b61510d565b82815260059290921b840181019181810190868411156151a557600080fd5b8286015b848110156151c057803583529183019183016151a9565b509695505050505050565b6000806000606084860312156151e057600080fd5b83356001600160401b03808211156151f757600080fd5b818601915086601f83011261520b57600080fd5b8135602061521b6151818361513d565b82815260059290921b8401810191818101908a84111561523a57600080fd5b948201945b8386101561526157853561525281615065565b8252948201949082019061523f565b9750508701359250508082111561527757600080fd5b5061528486828701615160565b9250506152936040850161507a565b90509250925092565b60008060008060008060008060008060c08b8d0312156152bb57600080fd5b6152c48b614ccc565b995060208b01356001600160401b03808211156152e057600080fd5b6152ec8e838f01614d0c565b9a5060408d013591508082111561530257600080fd5b61530e8e838f01614d24565b909a50985060608d013591508082111561532757600080fd5b6153338e838f01614d24565b909850965060808d013591508082111561534c57600080fd5b6153588e838f01614d24565b909650945060a08d013591508082111561537157600080fd5b5061537e8d828e01614d24565b915080935050809150509295989b9194979a5092959850565b6000602082840312156153a957600080fd5b8151801515811461372757600080fd5b6020808252603e908201527f456967656e506f642e6f6e6c795768656e4e6f745061757365643a20696e646560408201527f782069732070617573656420696e20456967656e506f644d616e616765720000606082015260800190565b60208082526028908201527f456967656e506f642e6f6e6c79456967656e506f644f776e65723a206e6f74206040820152673837b227bbb732b960c11b606082015260800190565b6020808252602f908201527f456967656e506f642e6861734e6576657252657374616b65643a20726573746160408201526e1ada5b99c81a5cc8195b98589b1959608a1b606082015260800190565b6000602082840312156154bf57600080fd5b5051919050565b6000808335601e198436030181126154dd57600080fd5b8301803591506001600160401b038211156154f757600080fd5b602001915036819003821315614d6857600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561553457600080fd5b813564ffffffffff8116811461372757600080fd5b6000808335601e1984360301811261556057600080fd5b8301803591506001600160401b0382111561557a57600080fd5b6020019150600581901b3603821315614d6857600080fd5b60006000198214156155a6576155a6614c89565b5060010190565b60208082526031908201527f456967656e506f642e6f6e6c79456967656e506f644d616e616765723a206e6f6040820152703a1032b4b3b2b72837b226b0b730b3b2b960791b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60005b8381101561564257818101518382015260200161562a565b838111156122eb5750506000910152565b6000815180845261566b816020860160208601615627565b601f01601f19169290920160200192915050565b60808152600061569360808301888a6155fe565b82810360208401526156a58188615653565b905082810360408401526156ba8186886155fe565b915050826060830152979650505050505050565b602081526000614b176020830184866155fe565b600080821280156001600160ff1b038490038513161561570457615704614c89565b600160ff1b839003841281161561571d5761571d614c89565b50500190565b60006001600160ff1b038184138284138082168684048611161561574957615749614c89565b600160ff1b600087128281168783058912161561576857615768614c89565b6000871292508782058712848416161561578457615784614c89565b8785058712818416161561579a5761579a614c89565b505050929093029392505050565b634e487b7160e01b600052601260045260246000fd5b6000826157cd576157cd6157a8565b500690565b6000826157e1576157e16157a8565b500490565b60006001600160401b038381169083168181101561580657615806614c89565b039392505050565b6000823561017e1983360301811261582557600080fd5b9190910192915050565b600081600019048311821515161561584957615849614c89565b500290565b60008282101561586057615860614c89565b500390565b60006001600160401b038083168185168183048111821515161561588b5761588b614c89565b02949350505050565b60006001600160401b03808416806158ae576158ae6157a8565b92169190910492915050565b60006001600160401b038083168185168083038211156158dc576158dc614c89565b01949350505050565b80516020808301519190811015614d1e5760001960209190910360031b1b16919050565b6000835161591b818460208801615627565b6001600160801b0319939093169190920190815260100192915050565b60008251615825818460208701615627565b600082601f83011261595b57600080fd5b81356001600160401b03811115615974576159746150ce565b615987601f8201601f191660200161510d565b81815284602083860101111561599c57600080fd5b816020850160208301376000918101602001919091529392505050565b600061018082360312156159cc57600080fd5b6159d46150e4565b82356001600160401b03808211156159eb57600080fd5b6159f73683870161594a565b83526020850135915080821115615a0d57600080fd5b615a193683870161594a565b60208401526040850135915080821115615a3257600080fd5b615a3e3683870161594a565b60408401526060850135915080821115615a5757600080fd5b615a633683870161594a565b60608401526080850135915080821115615a7c57600080fd5b50615a893682860161594a565b608083015250615a9b60a08401614ccc565b60a0820152615aac60c08401614ccc565b60c0820152615abd60e08401614ccc565b60e082015261010083810135908201526101208084013590820152610140808401359082015261016092830135928101929092525090565b600060208284031215615b0757600080fd5b815161372781614cb7565b600181815b80851115615b4d578160001904821115615b3357615b33614c89565b80851615615b4057918102915b93841c9390800290615b17565b509250929050565b600082615b6457506001610d0e565b81615b7157506000610d0e565b8160018114615b875760028114615b9157615bad565b6001915050610d0e565b60ff841115615ba257615ba2614c89565b50506001821b610d0e565b5060208310610133831016604e8410600b8410161715615bd0575081810a610d0e565b615bda8383615b12565b8060001904821115615bee57615bee614c89565b029392505050565b60006137278383615b55565b60008083128015600160ff1b850184121615615c2057615c20614c89565b6001600160ff1b0384018313811615615c3b57615c3b614c89565b50500390565b600060208284031215615c5357600080fd5b813561372781614cb7565b600081615c6d57615c6d614c89565b506000190190565b602081526000613727602083018461565356fe426561636f6e436861696e50726f6f66732e7665726966795769746864726177a2646970667358221220e5f0580eaf920c7bb34bd03d57402971f7a2c3f15a9ab7d5abe6370698a66e8964736f6c634300080c0033", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_ethPOS\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"},{\"name\":\"_eigenPodManager\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"},{\"name\":\"_GENESIS_TIME\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"GENESIS_TIME\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"activeValidatorCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkpointBalanceExitedGwei\",\"inputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"currentCheckpoint\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.Checkpoint\",\"components\":[{\"name\":\"beaconBlockRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proofsRemaining\",\"type\":\"uint24\",\"internalType\":\"uint24\"},{\"name\":\"podBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"balanceDeltasGwei\",\"type\":\"int128\",\"internalType\":\"int128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"currentCheckpointTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getParentBlockRoot\",\"inputs\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"lastCheckpointTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proofSubmitter\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recoverTokens\",\"inputs\":[{\"name\":\"tokenList\",\"type\":\"address[]\",\"internalType\":\"contractIERC20[]\"},{\"name\":\"amountsToWithdraw\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setProofSubmitter\",\"inputs\":[{\"name\":\"newProofSubmitter\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"startCheckpoint\",\"inputs\":[{\"name\":\"revertIfNoBalance\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"validatorPubkeyHashToInfo\",\"inputs\":[{\"name\":\"validatorPubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastCheckpointedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorPubkeyToInfo\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastCheckpointedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"pubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifyCheckpointProofs\",\"inputs\":[{\"name\":\"balanceContainerProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.BalanceContainerProof\",\"components\":[{\"name\":\"balanceContainerRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"proofs\",\"type\":\"tuple[]\",\"internalType\":\"structBeaconChainProofs.BalanceProof[]\",\"components\":[{\"name\":\"pubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"balanceRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyStaleBalance\",\"inputs\":[{\"name\":\"beaconTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"proof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.ValidatorProof\",\"components\":[{\"name\":\"validatorFields\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyWithdrawalCredentials\",\"inputs\":[{\"name\":\"beaconTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"validatorIndices\",\"type\":\"uint40[]\",\"internalType\":\"uint40[]\"},{\"name\":\"validatorFieldsProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"validatorFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawRestakedBeaconChainETH\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amountWei\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawableRestakedExecutionLayerGwei\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"CheckpointCreated\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"beaconBlockRoot\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validatorCount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CheckpointFinalized\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"totalShareDeltaWei\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EigenPodStaked\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NonBeaconChainETHReceived\",\"inputs\":[{\"name\":\"amountReceived\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProofSubmitterUpdated\",\"inputs\":[{\"name\":\"prevProofSubmitter\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newProofSubmitter\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RestakedBeaconChainETHWithdrawn\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorBalanceUpdated\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"},{\"name\":\"balanceTimestamp\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"newValidatorBalanceGwei\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorCheckpointed\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":true,\"internalType\":\"uint40\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRestaked\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorWithdrawn\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":true,\"internalType\":\"uint40\"}],\"anonymous\":false}]", + Bin: "0x60e06040523480156200001157600080fd5b5060405162004ad038038062004ad0833981016040819052620000349162000142565b6001600160a01b03808416608052821660a0526001600160401b03811660c0526200005e62000067565b505050620001a1565b600054610100900460ff1615620000d45760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000127576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b03811681146200013f57600080fd5b50565b6000806000606084860312156200015857600080fd5b8351620001658162000129565b6020850151909350620001788162000129565b60408501519092506001600160401b03811681146200019657600080fd5b809150509250925092565b60805160a05160c0516148b26200021e60003960006105ff0152600081816102bd0152818161063a015281816106ec01528181610abf01528181610d6c015281816110f40152818161119c0152818161143c015281816118db01528181611a8401526131250152600081816104b8015261126701526148b26000f3fe60806040526004361061016a5760003560e01c80636fcd0e53116100d1578063c49074421161008a578063dda3346c11610064578063dda3346c1461058d578063ee94d67c146105ad578063f074ba62146105cd578063f2882461146105ed57600080fd5b8063c49074421461052d578063c4d66de81461054d578063d06d55871461056d57600080fd5b80636fcd0e53146104425780637439841f1461046f57806374cdd798146104a657806388676cad146104da5780639b4e4634146104fa578063b522538a1461050d57600080fd5b80634665bcda116101235780634665bcda146102ab57806347d28372146102df57806352396a591461039f57806358753357146103d557806358eaee79146103f55780636c0d2d5a1461042257600080fd5b8063039157d2146101a95780630b18ff66146101cb5780632340e8d3146102085780633474aa161461022c5780633f65cf191461026457806342ecff2a1461028457600080fd5b366101a4576040513481527f6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf499060200160405180910390a1005b600080fd5b3480156101b557600080fd5b506101c96101c4366004613b66565b610621565b005b3480156101d757600080fd5b506033546101eb906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021457600080fd5b5061021e60395481565b6040519081526020016101ff565b34801561023857600080fd5b5060345461024c906001600160401b031681565b6040516001600160401b0390911681526020016101ff565b34801561027057600080fd5b506101c961027f366004613c24565b610a67565b34801561029057600080fd5b50603a5461024c90600160401b90046001600160401b031681565b3480156102b757600080fd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102eb57600080fd5b5061035b6040805160808101825260008082526020820181905291810182905260608101919091525060408051608081018252603c548152603d5462ffffff811660208301526001600160401b03630100000082041692820192909252600160581b909104600f0b606082015290565b6040516101ff91908151815260208083015162ffffff16908201526040808301516001600160401b031690820152606091820151600f0b9181019190915260800190565b3480156103ab57600080fd5b5061024c6103ba366004613cf2565b603b602052600090815260409020546001600160401b031681565b3480156103e157600080fd5b50603e546101eb906001600160a01b031681565b34801561040157600080fd5b50610415610410366004613d4e565b610dd6565b6040516101ff9190613dc7565b34801561042e57600080fd5b5061021e61043d366004613cf2565b610e3b565b34801561044e57600080fd5b5061046261045d366004613dd5565b610fef565b6040516101ff9190613dee565b34801561047b57600080fd5b5061041561048a366004613dd5565b600090815260366020526040902054600160c01b900460ff1690565b3480156104b257600080fd5b506101eb7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e657600080fd5b506101c96104f5366004613e44565b61109c565b6101c9610508366004613e61565b611191565b34801561051957600080fd5b50610462610528366004613d4e565b61133e565b34801561053957600080fd5b506101c9610548366004613ef4565b611431565b34801561055957600080fd5b506101c9610568366004613f20565b61166e565b34801561057957600080fd5b506101c9610588366004613f20565b611805565b34801561059957600080fd5b506101c96105a8366004614011565b611898565b3480156105b957600080fd5b50603a5461024c906001600160401b031681565b3480156105d957600080fd5b506101c96105e83660046140e2565b611a6b565b3480156105f957600080fd5b5061024c7f000000000000000000000000000000000000000000000000000000000000000081565b604051635ac86ab760e01b8152600660048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa158015610689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ad919061414a565b156106d35760405162461bcd60e51b81526004016106ca90614167565b60405180910390fd5b604051635ac86ab760e01b8152600860048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa15801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f919061414a565b1561077c5760405162461bcd60e51b81526004016106ca90614167565b60006107c261078b85806141c4565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611ebe92505050565b6000818152603660209081526040808320815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b8104909416928101929092529394509192906060830190600160c01b900460ff16600281111561083157610831613d8f565b600281111561084257610842613d8f565b81525050905080604001516001600160401b0316876001600160401b0316116108d5576040805162461bcd60e51b81526020600482015260248101919091527f456967656e506f642e7665726966795374616c6542616c616e63653a2070726f60448201527f6f66206973206f6c646572207468616e206c61737420636865636b706f696e7460648201526084016106ca565b6001816060015160028111156108ed576108ed613d8f565b146109575760405162461bcd60e51b815260206004820152603460248201527f456967656e506f642e7665726966795374616c6542616c616e63653a2076616c604482015273696461746f72206973206e6f742061637469766560601b60648201526084016106ca565b61099b61096486806141c4565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611ee292505050565b610a1f5760405162461bcd60e51b815260206004820152604960248201527f456967656e506f642e7665726966795374616c6542616c616e63653a2076616c60448201527f696461746f72206d75737420626520736c617368656420746f206265206d61726064820152686b6564207374616c6560b81b608482015260a4016106ca565b610a31610a2b88610e3b565b87611f0c565b610a548635610a4087806141c4565b610a4d60208a018a61420d565b8651612067565b610a5e600061227e565b50505050505050565b6033546001600160a01b0316331480610a8a5750603e546001600160a01b031633145b610aa65760405162461bcd60e51b81526004016106ca90614253565b604051635ac86ab760e01b8152600260048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa158015610b0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b32919061414a565b15610b4f5760405162461bcd60e51b81526004016106ca90614167565b8584148015610b5d57508382145b610bed5760405162461bcd60e51b815260206004820152605560248201527f456967656e506f642e7665726966795769746864726177616c43726564656e7460448201527f69616c733a2076616c696461746f72496e646963657320616e642070726f6f666064820152740e640daeae6e840c4ca40e6c2daca40d8cadccee8d605b1b608482015260a4016106ca565b603a546001600160401b03600160401b9091048116908a1611610c8d5760405162461bcd60e51b815260206004820152604c60248201527f456967656e506f642e7665726966795769746864726177616c43726564656e7460448201527f69616c733a207370656369666965642074696d657374616d7020697320746f6f60648201526b0819985c881a5b881c185cdd60a21b608482015260a4016106ca565b610c9f610c998a610e3b565b89611f0c565b6000805b87811015610d4257610d248a358a8a84818110610cc257610cc26142c7565b9050602002016020810190610cd791906142dd565b898985818110610ce957610ce96142c7565b9050602002810190610cfb919061420d565b898987818110610d0d57610d0d6142c7565b9050602002810190610d1f91906141c4565b612514565b610d2e908361431a565b915080610d3a81614332565b915050610ca3565b5060335460405163030b147160e61b81526001600160a01b039182166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000009091169063c2c51c4090604401600060405180830381600087803b158015610db257600080fd5b505af1158015610dc6573d6000803e3d6000fd5b5050505050505050505050505050565b600080610e1884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612afa92505050565b600090815260366020526040902054600160c01b900460ff169150505b92915050565b6000610e4a611fff600c61434d565b610e5d6001600160401b0384164261436c565b10610ec65760405162461bcd60e51b815260206004820152603360248201527f456967656e506f642e676574506172656e74426c6f636b526f6f743a2074696d604482015272657374616d70206f7574206f662072616e676560681b60648201526084016106ca565b604080516001600160401b03841660208201526000918291720f3df6d732807ef1319fb7b8bb8522d0beac02910160408051601f1981840301815290829052610f0e916143b3565b600060405180830381855afa9150503d8060008114610f49576040519150601f19603f3d011682016040523d82523d6000602084013e610f4e565b606091505b5091509150818015610f61575060008151115b610fd35760405162461bcd60e51b815260206004820152603860248201527f456967656e506f642e676574506172656e74426c6f636b526f6f743a20696e7660448201527f616c696420626c6f636b20726f6f742072657475726e6564000000000000000060648201526084016106ca565b80806020019051810190610fe791906143cf565b949350505050565b6110176040805160808101825260008082526020820181905291810182905290606082015290565b600082815260366020908152604091829020825160808101845281546001600160401b038082168352600160401b8204811694830194909452600160801b810490931693810193909352906060830190600160c01b900460ff16600281111561108257611082613d8f565b600281111561109357611093613d8f565b90525092915050565b6033546001600160a01b03163314806110bf5750603e546001600160a01b031633145b6110db5760405162461bcd60e51b81526004016106ca90614253565b604051635ac86ab760e01b8152600660048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa158015611143573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611167919061414a565b156111845760405162461bcd60e51b81526004016106ca90614167565b61118d8261227e565b5050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111d95760405162461bcd60e51b81526004016106ca906143e8565b346801bc16d674ec800000146112655760405162461bcd60e51b8152602060048201526044602482018190527f456967656e506f642e7374616b653a206d75737420696e697469616c6c792073908201527f74616b6520666f7220616e792076616c696461746f72207769746820333220656064820152633a3432b960e11b608482015260a4016106ca565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663228951186801bc16d674ec80000087876112a8612bf4565b8888886040518863ffffffff1660e01b81526004016112cc9695949392919061448e565b6000604051808303818588803b1580156112e557600080fd5b505af11580156112f9573d6000803e3d6000fd5b50505050507f606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23858560405161132f9291906144dd565b60405180910390a15050505050565b6113666040805160808101825260008082526020820181905291810182905290606082015290565b603660006113a985858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612afa92505050565b81526020808201929092526040908101600020815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b81049094169281019290925290916060830190600160c01b900460ff16600281111561141657611416613d8f565b600281111561142757611427613d8f565b9052509392505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114795760405162461bcd60e51b81526004016106ca906143e8565b611487633b9aca0082614507565b156115115760405162461bcd60e51b815260206004820152604e60248201527f456967656e506f642e776974686472617752657374616b6564426561636f6e4360448201527f6861696e4554483a20616d6f756e74576569206d75737420626520612077686f60648201526d1b194811ddd95a48185b5bdd5b9d60921b608482015260a4016106ca565b6000611521633b9aca008361451b565b6034549091506001600160401b0390811690821611156115da5760405162461bcd60e51b815260206004820152606260248201527f456967656e506f642e776974686472617752657374616b6564426561636f6e4360448201527f6861696e4554483a20616d6f756e74477765692065786365656473207769746860648201527f6472617761626c6552657374616b6564457865637574696f6e4c617965724777608482015261656960f01b60a482015260c4016106ca565b603480548291906000906115f89084906001600160401b031661452f565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550826001600160a01b03167f8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e8360405161165791815260200190565b60405180910390a26116698383612c39565b505050565b600054610100900460ff161580801561168e5750600054600160ff909116105b806116a85750303b1580156116a8575060005460ff166001145b61170b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106ca565b6000805460ff19166001179055801561172e576000805461ff0019166101001790555b6001600160a01b0382166117a15760405162461bcd60e51b815260206004820152603460248201527f456967656e506f642e696e697469616c697a653a20706f644f776e65722063616044820152736e6e6f74206265207a65726f206164647265737360601b60648201526084016106ca565b603380546001600160a01b0319166001600160a01b038416179055801561118d576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6033546001600160a01b0316331461182f5760405162461bcd60e51b81526004016106ca90614557565b603e54604080516001600160a01b03928316815291831660208301527ffb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac910160405180910390a1603e80546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b031633146118c25760405162461bcd60e51b81526004016106ca90614557565b604051635ac86ab760e01b8152600560048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa15801561192a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194e919061414a565b1561196b5760405162461bcd60e51b81526004016106ca90614167565b82518451146119f65760405162461bcd60e51b815260206004820152604b60248201527f456967656e506f642e7265636f766572546f6b656e733a20746f6b656e4c697360448201527f7420616e6420616d6f756e7473546f5769746864726177206d7573742062652060648201526a0e6c2daca40d8cadccee8d60ab1b608482015260a4016106ca565b60005b8451811015611a6457611a5283858381518110611a1857611a186142c7565b6020026020010151878481518110611a3257611a326142c7565b60200260200101516001600160a01b0316612d529092919063ffffffff16565b80611a5c81614332565b9150506119f9565b5050505050565b604051635ac86ab760e01b8152600760048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635ac86ab790602401602060405180830381865afa158015611ad3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af7919061414a565b15611b145760405162461bcd60e51b81526004016106ca90614167565b603a54600160401b90046001600160401b031680611bc05760405162461bcd60e51b815260206004820152605860248201527f456967656e506f642e766572696679436865636b706f696e7450726f6f66733a60448201527f206d75737420686176652061637469766520636865636b706f696e7420746f2060648201527f706572666f726d20636865636b706f696e742070726f6f660000000000000000608482015260a4016106ca565b60408051608081018252603c54808252603d5462ffffff811660208401526001600160401b03630100000082041693830193909352600160581b909204600f0b606082015290611c109087612da4565b6000805b85811015611e645736878783818110611c2f57611c2f6142c7565b9050602002810190611c41919061459f565b80356000908152603660209081526040808320815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b8104909416928101929092529394509192906060830190600160c01b900460ff166002811115611cb257611cb2613d8f565b6002811115611cc357611cc3613d8f565b9052509050600181606001516002811115611ce057611ce0613d8f565b14611cec575050611e52565b856001600160401b031681604001516001600160401b031610611d10575050611e52565b600080611d2083898e3587612f20565b602089018051929450909250611d35826145b5565b62ffffff16905250606087018051839190611d519083906145d4565b600f0b905250611d618187614623565b84356000908152603660209081526040918290208651815492880151938801516001600160401b03908116600160801b0267ffffffffffffffff60801b19958216600160401b026001600160801b0319909516919092161792909217928316821781556060870151939950869390929091839160ff60c01b1990911668ffffffffffffffffff60801b1990911617600160c01b836002811115611e0657611e06613d8f565b021790555050835160405164ffffffffff90911691506001600160401b038a16907fa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f90600090a3505050505b80611e5c81614332565b915050611c14565b506001600160401b038084166000908152603b6020526040812080548493919291611e9191859116614623565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610a5e82613042565b600081600081518110611ed357611ed36142c7565b60200260200101519050919050565b600081600381518110611ef757611ef76142c7565b60200260200101516000801b14159050919050565b611f186003602061434d565b611f25602083018361420d565b905014611f9a5760405162461bcd60e51b815260206004820152603d60248201527f426561636f6e436861696e50726f6f66732e7665726966795374617465526f6f60448201527f743a2050726f6f662068617320696e636f7272656374206c656e67746800000060648201526084016106ca565b611fea611faa602083018361420d565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925050843590506003613249565b61118d5760405162461bcd60e51b815260206004820152604260248201527f426561636f6e436861696e50726f6f66732e7665726966795374617465526f6f60448201527f743a20496e76616c696420737461746520726f6f74206d65726b6c652070726f60648201526137b360f11b608482015260a4016106ca565b600884146120e25760405162461bcd60e51b815260206004820152604e602482015260008051602061485d83398151915260448201527f724669656c64733a2056616c696461746f72206669656c64732068617320696e60648201526d0c6dee4e4cac6e840d8cadccee8d60931b608482015260a4016106ca565b60056120f06028600161431a565b6120fa919061431a565b61210590602061434d565b82146121735760405162461bcd60e51b8152602060048201526043602482015260008051602061485d83398151915260448201527f724669656c64733a2050726f6f662068617320696e636f7272656374206c656e6064820152620cee8d60eb1b608482015260a4016106ca565b60006121b186868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061326192505050565b9050600064ffffffffff83166121c96028600161431a565b600b901b17905061221485858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c9250869150859050613249565b6122745760405162461bcd60e51b815260206004820152603d602482015260008051602061485d83398151915260448201527f724669656c64733a20496e76616c6964206d65726b6c652070726f6f6600000060648201526084016106ca565b5050505050505050565b603a54600160401b90046001600160401b03161561231f5760405162461bcd60e51b815260206004820152605260248201527f456967656e506f642e5f7374617274436865636b706f696e743a206d7573742060448201527f66696e6973682070726576696f757320636865636b706f696e74206265666f72606482015271329039ba30b93a34b7339030b737ba3432b960711b608482015260a4016106ca565b603a54426001600160401b03908116911614156123a45760405162461bcd60e51b815260206004820152603f60248201527f456967656e506f642e5f7374617274436865636b706f696e743a2063616e6e6f60448201527f7420636865636b706f696e7420747769636520696e206f6e6520626c6f636b0060648201526084016106ca565b6034546000906001600160401b03166123c1633b9aca004761451b565b6123cb919061452f565b90508180156123e157506001600160401b038116155b156124545760405162461bcd60e51b815260206004820152603d60248201527f456967656e506f642e5f7374617274436865636b706f696e743a206e6f20626160448201527f6c616e636520617661696c61626c6520746f20636865636b706f696e7400000060648201526084016106ca565b6000604051806080016040528061246a42610e3b565b815260200160395462ffffff168152602001836001600160401b031681526020016000600f0b815250905042603a60086101000a8154816001600160401b0302191690836001600160401b031602179055506124c581613042565b805160208083015160405162ffffff90911681526001600160401b034216917f575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076910160405180910390a3505050565b600080612553848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611ebe92505050565b6000818152603660209081526040808320815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b8104909416928101929092529394509192906060830190600160c01b900460ff1660028111156125c2576125c2613d8f565b60028111156125d3576125d3613d8f565b90525090506000816060015160028111156125f0576125f0613d8f565b146126815760405162461bcd60e51b8152602060048201526061602482015260008051602061483d83398151915260448201527f7469616c733a2076616c696461746f72206d75737420626520696e616374697660648201527f6520746f2070726f7665207769746864726177616c2063726564656e7469616c6084820152607360f81b60a482015260c4016106ca565b6001600160401b0380166126c786868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061350e92505050565b6001600160401b031614156127505760405162461bcd60e51b8152602060048201526055602482015260008051602061483d83398151915260448201527f7469616c733a2076616c696461746f72206d75737420626520696e207468652060648201527470726f63657373206f662061637469766174696e6760581b608482015260a4016106ca565b6001600160401b03801661279686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061353392505050565b6001600160401b03161461280e5760405162461bcd60e51b81526020600482015260446024820181905260008051602061483d833981519152908201527f7469616c733a2076616c696461746f72206d757374206e6f742062652065786960648201526374696e6760e01b608482015260a4016106ca565b612816612bf4565b61281f9061464e565b61285b86868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061354b92505050565b146128ca5760405162461bcd60e51b8152602060048201526045602482015260008051602061483d83398151915260448201527f7469616c733a2070726f6f66206973206e6f7420666f72207468697320456967606482015264195b941bd960da1b608482015260a4016106ca565b600061290886868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061356092505050565b90506129188a87878b8b8e612067565b6039805490600061292883614332565b9091555050603a54600090600160401b90046001600160401b03161561296057603a54600160401b90046001600160401b031661296d565b603a546001600160401b03165b6040805160808101825264ffffffffff8d1681526001600160401b03858116602083015283169181019190915290915060608101600190526000858152603660209081526040918290208351815492850151938501516001600160401b03908116600160801b0267ffffffffffffffff60801b19958216600160401b026001600160801b031990951691909216179290921792831682178155606084015190929091839160ff60c01b1990911668ffffffffffffffffff60801b1990911617600160c01b836002811115612a4357612a43613d8f565b02179055505060405164ffffffffff8c1681527f2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449915060200160405180910390a16040805164ffffffffff8c1681526001600160401b03838116602083015284168183015290517f0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df9181900360600190a1612aeb633b9aca006001600160401b03841661434d565b9b9a5050505050505050505050565b60008151603014612b835760405162461bcd60e51b815260206004820152604760248201527f456967656e506f642e5f63616c63756c61746556616c696461746f725075626b60448201527f657948617368206d75737420626520612034382d6279746520424c53207075626064820152666c6963206b657960c81b608482015260a4016106ca565b604051600290612b9a908490600090602001614672565b60408051601f1981840301815290829052612bb4916143b3565b602060405180830381855afa158015612bd1573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e3591906143cf565b60408051600160f81b60208201526000602182015230606090811b6bffffffffffffffffffffffff1916602c8301529101604051602081830303815290604052905090565b80471015612c895760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016106ca565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612cd6576040519150601f19603f3d011682016040523d82523d6000602084013e612cdb565b606091505b50509050806116695760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016106ca565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611669908490613578565b612db06005600361431a565b612dbb90602061434d565b612dc8602083018361420d565b905014612e4b5760405162461bcd60e51b8152602060048201526044602482018190527f426561636f6e436861696e50726f6f66732e76657269667942616c616e636543908201527f6f6e7461696e65723a2050726f6f662068617320696e636f7272656374206c656064820152630dccee8d60e31b608482015260a4016106ca565b606c612e9c612e5d602084018461420d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250508535905084613249565b6116695760405162461bcd60e51b815260206004820152604960248201527f426561636f6e436861696e50726f6f66732e76657269667942616c616e63654360448201527f6f6e7461696e65723a20696e76616c69642062616c616e636520636f6e7461696064820152683732b910383937b7b360b91b608482015260a4016106ca565b83516020850151600091829182612f3887848861364a565b9050816001600160401b0316816001600160401b031614612fb257612f5d81836137c1565b6040805164ffffffffff861681526001600160401b038b8116602083015284168183015290519196507f0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df919081900360600190a15b6001600160401b0380821660208b0181905290891660408b01526130365760398054906000612fe0836146a1565b9091555050600260608a0152612ff5856146b8565b93508264ffffffffff16886001600160401b03167f2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a60405160405180910390a35b50505094509492505050565b602081015162ffffff166131c9576000633b9aca00826060015183604001516001600160401b031661307491906145d4565b600f0b61308191906146df565b60408301516034805492935090916000906130a69084906001600160401b0316614623565b82546101009290920a6001600160401b03818102199093169183160217909155603a8054600160401b81049092166001600160801b0319909216919091179055506000603c55603d80546001600160d81b031916905560335460405163030b147160e61b81526001600160a01b039182166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000009091169063c2c51c4090604401600060405180830381600087803b15801561316b57600080fd5b505af115801561317f573d6000803e3d6000fd5b5050603a546040518481526001600160401b0390911692507f525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44915060200160405180910390a25050565b8051603c556020810151603d8054604084015160608501516fffffffffffffffffffffffffffffffff16600160581b026fffffffffffffffffffffffffffffffff60581b196001600160401b039092166301000000026affffffffffffffffffffff1990931662ffffff9095169490941791909117169190911790555b50565b6000836132578685856137d9565b1495945050505050565b60008060028351613272919061451b565b90506000816001600160401b0381111561328e5761328e613f3d565b6040519080825280602002602001820160405280156132b7578160200160208202803683370190505b50905060005b828110156133be576002856132d2838361434d565b815181106132e2576132e26142c7565b6020026020010151868360026132f8919061434d565b61330390600161431a565b81518110613313576133136142c7565b6020026020010151604051602001613335929190918252602082015260400190565b60408051601f198184030181529082905261334f916143b3565b602060405180830381855afa15801561336c573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061338f91906143cf565b8282815181106133a1576133a16142c7565b6020908102919091010152806133b681614332565b9150506132bd565b506133ca60028361451b565b91505b81156134ea5760005b828110156134d7576002826133eb838361434d565b815181106133fb576133fb6142c7565b602002602001015183836002613411919061434d565b61341c90600161431a565b8151811061342c5761342c6142c7565b602002602001015160405160200161344e929190918252602082015260400190565b60408051601f1981840301815290829052613468916143b3565b602060405180830381855afa158015613485573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906134a891906143cf565b8282815181106134ba576134ba6142c7565b6020908102919091010152806134cf81614332565b9150506133d6565b506134e360028361451b565b91506133cd565b806000815181106134fd576134fd6142c7565b602002602001015192505050919050565b6000610e3582600581518110613526576135266142c7565b6020026020010151613925565b6000610e3582600681518110613526576135266142c7565b600081600181518110611ed357611ed36142c7565b6000610e3582600281518110613526576135266142c7565b60006135cd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661398c9092919063ffffffff16565b80519091501561166957808060200190518101906135eb919061414a565b6116695760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106ca565b60006136586026600161431a565b61366390602061434d565b613670604084018461420d565b9050146136e15760405162461bcd60e51b81526020600482015260446024820181905260008051602061485d833981519152908201527f7242616c616e63653a2050726f6f662068617320696e636f7272656374206c656064820152630dccee8d60e31b608482015260a4016106ca565b60006136ee600485614764565b64ffffffffff169050613748613707604085018561420d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508992505050602086013584613249565b6137a85760405162461bcd60e51b815260206004820152603e602482015260008051602061485d83398151915260448201527f7242616c616e63653a20496e76616c6964206d65726b6c652070726f6f66000060648201526084016106ca565b6137b683602001358561399b565b9150505b9392505050565b60006137ba6001600160401b03808416908516614788565b600083516000141580156137f85750602084516137f69190614507565b155b6138875760405162461bcd60e51b815260206004820152605460248201527f4d65726b6c652e70726f63657373496e636c7573696f6e50726f6f665368613260448201527f35363a2070726f6f66206c656e6774682073686f756c642062652061206e6f6e60648201527316bd32b9379036bab63a34b836329037b310199960611b608482015260a4016106ca565b604080516020808201909252848152905b8551811161391b576138ab600285614507565b6138de578151600052808601516020526020826040600060026107d05a03fa6138d357600080fd5b600284049350613909565b8086015160005281516020526020826040600060026107d05a03fa61390257600080fd5b6002840493505b61391460208261431a565b9050613898565b5051949350505050565b60f881901c60e882901c61ff00161760d882901c62ff0000161760c882901c63ff000000161764ff0000000060b883901c161765ff000000000060a883901c161766ff000000000000609883901c161767ff0000000000000060889290921c919091161790565b6060610fe784846000856139c8565b6000806139a96004846147d8565b6139b49060406147fc565b64ffffffffff169050610fe784821b613925565b606082471015613a295760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106ca565b6001600160a01b0385163b613a805760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106ca565b600080866001600160a01b03168587604051613a9c91906143b3565b60006040518083038185875af1925050503d8060008114613ad9576040519150601f19603f3d011682016040523d82523d6000602084013e613ade565b606091505b5091509150613aee828286613af9565b979650505050505050565b60608315613b085750816137ba565b825115613b185782518084602001fd5b8160405162461bcd60e51b81526004016106ca9190614829565b80356001600160401b0381168114613b4957600080fd5b919050565b600060408284031215613b6057600080fd5b50919050565b600080600060608486031215613b7b57600080fd5b613b8484613b32565b925060208401356001600160401b0380821115613ba057600080fd5b613bac87838801613b4e565b93506040860135915080821115613bc257600080fd5b50613bcf86828701613b4e565b9150509250925092565b60008083601f840112613beb57600080fd5b5081356001600160401b03811115613c0257600080fd5b6020830191508360208260051b8501011115613c1d57600080fd5b9250929050565b60008060008060008060008060a0898b031215613c4057600080fd5b613c4989613b32565b975060208901356001600160401b0380821115613c6557600080fd5b613c718c838d01613b4e565b985060408b0135915080821115613c8757600080fd5b613c938c838d01613bd9565b909850965060608b0135915080821115613cac57600080fd5b613cb88c838d01613bd9565b909650945060808b0135915080821115613cd157600080fd5b50613cde8b828c01613bd9565b999c989b5096995094979396929594505050565b600060208284031215613d0457600080fd5b6137ba82613b32565b60008083601f840112613d1f57600080fd5b5081356001600160401b03811115613d3657600080fd5b602083019150836020828501011115613c1d57600080fd5b60008060208385031215613d6157600080fd5b82356001600160401b03811115613d7757600080fd5b613d8385828601613d0d565b90969095509350505050565b634e487b7160e01b600052602160045260246000fd5b60038110613dc357634e487b7160e01b600052602160045260246000fd5b9052565b60208101610e358284613da5565b600060208284031215613de757600080fd5b5035919050565b60006080820190506001600160401b03808451168352806020850151166020840152806040850151166040840152506060830151613e2f6060840182613da5565b5092915050565b801515811461324657600080fd5b600060208284031215613e5657600080fd5b81356137ba81613e36565b600080600080600060608688031215613e7957600080fd5b85356001600160401b0380821115613e9057600080fd5b613e9c89838a01613d0d565b90975095506020880135915080821115613eb557600080fd5b50613ec288828901613d0d565b96999598509660400135949350505050565b6001600160a01b038116811461324657600080fd5b8035613b4981613ed4565b60008060408385031215613f0757600080fd5b8235613f1281613ed4565b946020939093013593505050565b600060208284031215613f3257600080fd5b81356137ba81613ed4565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613f7b57613f7b613f3d565b604052919050565b60006001600160401b03821115613f9c57613f9c613f3d565b5060051b60200190565b600082601f830112613fb757600080fd5b81356020613fcc613fc783613f83565b613f53565b82815260059290921b84018101918181019086841115613feb57600080fd5b8286015b848110156140065780358352918301918301613fef565b509695505050505050565b60008060006060848603121561402657600080fd5b83356001600160401b038082111561403d57600080fd5b818601915086601f83011261405157600080fd5b81356020614061613fc783613f83565b82815260059290921b8401810191818101908a84111561408057600080fd5b948201945b838610156140a757853561409881613ed4565b82529482019490820190614085565b975050870135925050808211156140bd57600080fd5b506140ca86828701613fa6565b9250506140d960408501613ee9565b90509250925092565b6000806000604084860312156140f757600080fd5b83356001600160401b038082111561410e57600080fd5b61411a87838801613b4e565b9450602086013591508082111561413057600080fd5b5061413d86828701613bd9565b9497909650939450505050565b60006020828403121561415c57600080fd5b81516137ba81613e36565b6020808252603e908201527f456967656e506f642e6f6e6c795768656e4e6f745061757365643a20696e646560408201527f782069732070617573656420696e20456967656e506f644d616e616765720000606082015260800190565b6000808335601e198436030181126141db57600080fd5b8301803591506001600160401b038211156141f557600080fd5b6020019150600581901b3603821315613c1d57600080fd5b6000808335601e1984360301811261422457600080fd5b8301803591506001600160401b0382111561423e57600080fd5b602001915036819003821315613c1d57600080fd5b6020808252604e908201527f456967656e506f642e6f6e6c794f776e65724f7250726f6f665375626d69747460408201527f65723a2063616c6c6572206973206e6f7420706f64206f776e6572206f72207060608201526d3937b7b31039bab136b4ba3a32b960911b608082015260a00190565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156142ef57600080fd5b813564ffffffffff811681146137ba57600080fd5b634e487b7160e01b600052601160045260246000fd5b6000821982111561432d5761432d614304565b500190565b600060001982141561434657614346614304565b5060010190565b600081600019048311821515161561436757614367614304565b500290565b60008282101561437e5761437e614304565b500390565b60005b8381101561439e578181015183820152602001614386565b838111156143ad576000848401525b50505050565b600082516143c5818460208701614383565b9190910192915050565b6000602082840312156143e157600080fd5b5051919050565b60208082526031908201527f456967656e506f642e6f6e6c79456967656e506f644d616e616765723a206e6f6040820152703a1032b4b3b2b72837b226b0b730b3b2b960791b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000815180845261447a816020860160208601614383565b601f01601f19169290920160200192915050565b6080815260006144a260808301888a614439565b82810360208401526144b48188614462565b905082810360408401526144c9818688614439565b915050826060830152979650505050505050565b602081526000610fe7602083018486614439565b634e487b7160e01b600052601260045260246000fd5b600082614516576145166144f1565b500690565b60008261452a5761452a6144f1565b500490565b60006001600160401b038381169083168181101561454f5761454f614304565b039392505050565b60208082526028908201527f456967656e506f642e6f6e6c79456967656e506f644f776e65723a206e6f74206040820152673837b227bbb732b960c11b606082015260800190565b60008235605e198336030181126143c557600080fd5b600062ffffff8216806145ca576145ca614304565b6000190192915050565b600081600f0b83600f0b600082128260016001607f1b03038213811516156145fe576145fe614304565b8260016001607f1b031903821281161561461a5761461a614304565b50019392505050565b60006001600160401b0380831681851680830382111561464557614645614304565b01949350505050565b80516020808301519190811015613b605760001960209190910360031b1b16919050565b60008351614684818460208801614383565b6001600160801b0319939093169190920190815260100192915050565b6000816146b0576146b0614304565b506000190190565b600081600f0b60016001607f1b03198114156146d6576146d6614304565b60000392915050565b60006001600160ff1b038184138284138082168684048611161561470557614705614304565b600160ff1b600087128281168783058912161561472457614724614304565b6000871292508782058712848416161561474057614740614304565b8785058712818416161561475657614756614304565b505050929093029392505050565b600064ffffffffff8084168061477c5761477c6144f1565b92169190910492915050565b600081600f0b83600f0b600081128160016001607f1b0319018312811516156147b3576147b3614304565b8160016001607f1b030183138116156147ce576147ce614304565b5090039392505050565b600064ffffffffff808416806147f0576147f06144f1565b92169190910692915050565b600064ffffffffff8083168185168183048111821515161561482057614820614304565b02949350505050565b6020815260006137ba602083018461446256fe456967656e506f642e5f7665726966795769746864726177616c43726564656e426561636f6e436861696e50726f6f66732e76657269667956616c696461746fa2646970667358221220721ae261e7ea8172633ca39b5c47509345abd9d23c9a1d07374863ca537d102264736f6c634300080c0033", } // EigenPodABI is the input ABI used to generate the binding from. @@ -74,7 +85,7 @@ var EigenPodABI = EigenPodMetaData.ABI var EigenPodBin = EigenPodMetaData.Bin // DeployEigenPod deploys a new Ethereum contract, binding an instance of EigenPod to it. -func DeployEigenPod(auth *bind.TransactOpts, backend bind.ContractBackend, _ethPOS common.Address, _delayedWithdrawalRouter common.Address, _eigenPodManager common.Address, _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR uint64, _GENESIS_TIME uint64) (common.Address, *types.Transaction, *EigenPod, error) { +func DeployEigenPod(auth *bind.TransactOpts, backend bind.ContractBackend, _ethPOS common.Address, _eigenPodManager common.Address, _GENESIS_TIME uint64) (common.Address, *types.Transaction, *EigenPod, error) { parsed, err := EigenPodMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -83,7 +94,7 @@ func DeployEigenPod(auth *bind.TransactOpts, backend bind.ContractBackend, _ethP return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EigenPodBin), backend, _ethPOS, _delayedWithdrawalRouter, _eigenPodManager, _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, _GENESIS_TIME) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EigenPodBin), backend, _ethPOS, _eigenPodManager, _GENESIS_TIME) if err != nil { return common.Address{}, nil, nil, err } @@ -263,12 +274,43 @@ func (_EigenPod *EigenPodCallerSession) GENESISTIME() (uint64, error) { return _EigenPod.Contract.GENESISTIME(&_EigenPod.CallOpts) } -// MAXRESTAKEDBALANCEGWEIPERVALIDATOR is a free data retrieval call binding the contract method 0x1d905d5c. +// ActiveValidatorCount is a free data retrieval call binding the contract method 0x2340e8d3. // -// Solidity: function MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() view returns(uint64) -func (_EigenPod *EigenPodCaller) MAXRESTAKEDBALANCEGWEIPERVALIDATOR(opts *bind.CallOpts) (uint64, error) { +// Solidity: function activeValidatorCount() view returns(uint256) +func (_EigenPod *EigenPodCaller) ActiveValidatorCount(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _EigenPod.contract.Call(opts, &out, "MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR") + err := _EigenPod.contract.Call(opts, &out, "activeValidatorCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ActiveValidatorCount is a free data retrieval call binding the contract method 0x2340e8d3. +// +// Solidity: function activeValidatorCount() view returns(uint256) +func (_EigenPod *EigenPodSession) ActiveValidatorCount() (*big.Int, error) { + return _EigenPod.Contract.ActiveValidatorCount(&_EigenPod.CallOpts) +} + +// ActiveValidatorCount is a free data retrieval call binding the contract method 0x2340e8d3. +// +// Solidity: function activeValidatorCount() view returns(uint256) +func (_EigenPod *EigenPodCallerSession) ActiveValidatorCount() (*big.Int, error) { + return _EigenPod.Contract.ActiveValidatorCount(&_EigenPod.CallOpts) +} + +// CheckpointBalanceExitedGwei is a free data retrieval call binding the contract method 0x52396a59. +// +// Solidity: function checkpointBalanceExitedGwei(uint64 ) view returns(uint64) +func (_EigenPod *EigenPodCaller) CheckpointBalanceExitedGwei(opts *bind.CallOpts, arg0 uint64) (uint64, error) { + var out []interface{} + err := _EigenPod.contract.Call(opts, &out, "checkpointBalanceExitedGwei", arg0) if err != nil { return *new(uint64), err @@ -280,49 +322,80 @@ func (_EigenPod *EigenPodCaller) MAXRESTAKEDBALANCEGWEIPERVALIDATOR(opts *bind.C } -// MAXRESTAKEDBALANCEGWEIPERVALIDATOR is a free data retrieval call binding the contract method 0x1d905d5c. +// CheckpointBalanceExitedGwei is a free data retrieval call binding the contract method 0x52396a59. // -// Solidity: function MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() view returns(uint64) -func (_EigenPod *EigenPodSession) MAXRESTAKEDBALANCEGWEIPERVALIDATOR() (uint64, error) { - return _EigenPod.Contract.MAXRESTAKEDBALANCEGWEIPERVALIDATOR(&_EigenPod.CallOpts) +// Solidity: function checkpointBalanceExitedGwei(uint64 ) view returns(uint64) +func (_EigenPod *EigenPodSession) CheckpointBalanceExitedGwei(arg0 uint64) (uint64, error) { + return _EigenPod.Contract.CheckpointBalanceExitedGwei(&_EigenPod.CallOpts, arg0) } -// MAXRESTAKEDBALANCEGWEIPERVALIDATOR is a free data retrieval call binding the contract method 0x1d905d5c. +// CheckpointBalanceExitedGwei is a free data retrieval call binding the contract method 0x52396a59. // -// Solidity: function MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() view returns(uint64) -func (_EigenPod *EigenPodCallerSession) MAXRESTAKEDBALANCEGWEIPERVALIDATOR() (uint64, error) { - return _EigenPod.Contract.MAXRESTAKEDBALANCEGWEIPERVALIDATOR(&_EigenPod.CallOpts) +// Solidity: function checkpointBalanceExitedGwei(uint64 ) view returns(uint64) +func (_EigenPod *EigenPodCallerSession) CheckpointBalanceExitedGwei(arg0 uint64) (uint64, error) { + return _EigenPod.Contract.CheckpointBalanceExitedGwei(&_EigenPod.CallOpts, arg0) } -// DelayedWithdrawalRouter is a free data retrieval call binding the contract method 0x1a5057be. +// CurrentCheckpoint is a free data retrieval call binding the contract method 0x47d28372. // -// Solidity: function delayedWithdrawalRouter() view returns(address) -func (_EigenPod *EigenPodCaller) DelayedWithdrawalRouter(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function currentCheckpoint() view returns((bytes32,uint24,uint64,int128)) +func (_EigenPod *EigenPodCaller) CurrentCheckpoint(opts *bind.CallOpts) (IEigenPodCheckpoint, error) { var out []interface{} - err := _EigenPod.contract.Call(opts, &out, "delayedWithdrawalRouter") + err := _EigenPod.contract.Call(opts, &out, "currentCheckpoint") if err != nil { - return *new(common.Address), err + return *new(IEigenPodCheckpoint), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new(IEigenPodCheckpoint)).(*IEigenPodCheckpoint) + + return out0, err + +} + +// CurrentCheckpoint is a free data retrieval call binding the contract method 0x47d28372. +// +// Solidity: function currentCheckpoint() view returns((bytes32,uint24,uint64,int128)) +func (_EigenPod *EigenPodSession) CurrentCheckpoint() (IEigenPodCheckpoint, error) { + return _EigenPod.Contract.CurrentCheckpoint(&_EigenPod.CallOpts) +} + +// CurrentCheckpoint is a free data retrieval call binding the contract method 0x47d28372. +// +// Solidity: function currentCheckpoint() view returns((bytes32,uint24,uint64,int128)) +func (_EigenPod *EigenPodCallerSession) CurrentCheckpoint() (IEigenPodCheckpoint, error) { + return _EigenPod.Contract.CurrentCheckpoint(&_EigenPod.CallOpts) +} + +// CurrentCheckpointTimestamp is a free data retrieval call binding the contract method 0x42ecff2a. +// +// Solidity: function currentCheckpointTimestamp() view returns(uint64) +func (_EigenPod *EigenPodCaller) CurrentCheckpointTimestamp(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _EigenPod.contract.Call(opts, &out, "currentCheckpointTimestamp") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) return out0, err } -// DelayedWithdrawalRouter is a free data retrieval call binding the contract method 0x1a5057be. +// CurrentCheckpointTimestamp is a free data retrieval call binding the contract method 0x42ecff2a. // -// Solidity: function delayedWithdrawalRouter() view returns(address) -func (_EigenPod *EigenPodSession) DelayedWithdrawalRouter() (common.Address, error) { - return _EigenPod.Contract.DelayedWithdrawalRouter(&_EigenPod.CallOpts) +// Solidity: function currentCheckpointTimestamp() view returns(uint64) +func (_EigenPod *EigenPodSession) CurrentCheckpointTimestamp() (uint64, error) { + return _EigenPod.Contract.CurrentCheckpointTimestamp(&_EigenPod.CallOpts) } -// DelayedWithdrawalRouter is a free data retrieval call binding the contract method 0x1a5057be. +// CurrentCheckpointTimestamp is a free data retrieval call binding the contract method 0x42ecff2a. // -// Solidity: function delayedWithdrawalRouter() view returns(address) -func (_EigenPod *EigenPodCallerSession) DelayedWithdrawalRouter() (common.Address, error) { - return _EigenPod.Contract.DelayedWithdrawalRouter(&_EigenPod.CallOpts) +// Solidity: function currentCheckpointTimestamp() view returns(uint64) +func (_EigenPod *EigenPodCallerSession) CurrentCheckpointTimestamp() (uint64, error) { + return _EigenPod.Contract.CurrentCheckpointTimestamp(&_EigenPod.CallOpts) } // EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. @@ -387,43 +460,43 @@ func (_EigenPod *EigenPodCallerSession) EthPOS() (common.Address, error) { return _EigenPod.Contract.EthPOS(&_EigenPod.CallOpts) } -// HasRestaked is a free data retrieval call binding the contract method 0x3106ab53. +// GetParentBlockRoot is a free data retrieval call binding the contract method 0x6c0d2d5a. // -// Solidity: function hasRestaked() view returns(bool) -func (_EigenPod *EigenPodCaller) HasRestaked(opts *bind.CallOpts) (bool, error) { +// Solidity: function getParentBlockRoot(uint64 timestamp) view returns(bytes32) +func (_EigenPod *EigenPodCaller) GetParentBlockRoot(opts *bind.CallOpts, timestamp uint64) ([32]byte, error) { var out []interface{} - err := _EigenPod.contract.Call(opts, &out, "hasRestaked") + err := _EigenPod.contract.Call(opts, &out, "getParentBlockRoot", timestamp) if err != nil { - return *new(bool), err + return *new([32]byte), err } - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) return out0, err } -// HasRestaked is a free data retrieval call binding the contract method 0x3106ab53. +// GetParentBlockRoot is a free data retrieval call binding the contract method 0x6c0d2d5a. // -// Solidity: function hasRestaked() view returns(bool) -func (_EigenPod *EigenPodSession) HasRestaked() (bool, error) { - return _EigenPod.Contract.HasRestaked(&_EigenPod.CallOpts) +// Solidity: function getParentBlockRoot(uint64 timestamp) view returns(bytes32) +func (_EigenPod *EigenPodSession) GetParentBlockRoot(timestamp uint64) ([32]byte, error) { + return _EigenPod.Contract.GetParentBlockRoot(&_EigenPod.CallOpts, timestamp) } -// HasRestaked is a free data retrieval call binding the contract method 0x3106ab53. +// GetParentBlockRoot is a free data retrieval call binding the contract method 0x6c0d2d5a. // -// Solidity: function hasRestaked() view returns(bool) -func (_EigenPod *EigenPodCallerSession) HasRestaked() (bool, error) { - return _EigenPod.Contract.HasRestaked(&_EigenPod.CallOpts) +// Solidity: function getParentBlockRoot(uint64 timestamp) view returns(bytes32) +func (_EigenPod *EigenPodCallerSession) GetParentBlockRoot(timestamp uint64) ([32]byte, error) { + return _EigenPod.Contract.GetParentBlockRoot(&_EigenPod.CallOpts, timestamp) } -// MostRecentWithdrawalTimestamp is a free data retrieval call binding the contract method 0x87e0d289. +// LastCheckpointTimestamp is a free data retrieval call binding the contract method 0xee94d67c. // -// Solidity: function mostRecentWithdrawalTimestamp() view returns(uint64) -func (_EigenPod *EigenPodCaller) MostRecentWithdrawalTimestamp(opts *bind.CallOpts) (uint64, error) { +// Solidity: function lastCheckpointTimestamp() view returns(uint64) +func (_EigenPod *EigenPodCaller) LastCheckpointTimestamp(opts *bind.CallOpts) (uint64, error) { var out []interface{} - err := _EigenPod.contract.Call(opts, &out, "mostRecentWithdrawalTimestamp") + err := _EigenPod.contract.Call(opts, &out, "lastCheckpointTimestamp") if err != nil { return *new(uint64), err @@ -435,49 +508,18 @@ func (_EigenPod *EigenPodCaller) MostRecentWithdrawalTimestamp(opts *bind.CallOp } -// MostRecentWithdrawalTimestamp is a free data retrieval call binding the contract method 0x87e0d289. -// -// Solidity: function mostRecentWithdrawalTimestamp() view returns(uint64) -func (_EigenPod *EigenPodSession) MostRecentWithdrawalTimestamp() (uint64, error) { - return _EigenPod.Contract.MostRecentWithdrawalTimestamp(&_EigenPod.CallOpts) -} - -// MostRecentWithdrawalTimestamp is a free data retrieval call binding the contract method 0x87e0d289. -// -// Solidity: function mostRecentWithdrawalTimestamp() view returns(uint64) -func (_EigenPod *EigenPodCallerSession) MostRecentWithdrawalTimestamp() (uint64, error) { - return _EigenPod.Contract.MostRecentWithdrawalTimestamp(&_EigenPod.CallOpts) -} - -// NonBeaconChainETHBalanceWei is a free data retrieval call binding the contract method 0xfe80b087. -// -// Solidity: function nonBeaconChainETHBalanceWei() view returns(uint256) -func (_EigenPod *EigenPodCaller) NonBeaconChainETHBalanceWei(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _EigenPod.contract.Call(opts, &out, "nonBeaconChainETHBalanceWei") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// NonBeaconChainETHBalanceWei is a free data retrieval call binding the contract method 0xfe80b087. +// LastCheckpointTimestamp is a free data retrieval call binding the contract method 0xee94d67c. // -// Solidity: function nonBeaconChainETHBalanceWei() view returns(uint256) -func (_EigenPod *EigenPodSession) NonBeaconChainETHBalanceWei() (*big.Int, error) { - return _EigenPod.Contract.NonBeaconChainETHBalanceWei(&_EigenPod.CallOpts) +// Solidity: function lastCheckpointTimestamp() view returns(uint64) +func (_EigenPod *EigenPodSession) LastCheckpointTimestamp() (uint64, error) { + return _EigenPod.Contract.LastCheckpointTimestamp(&_EigenPod.CallOpts) } -// NonBeaconChainETHBalanceWei is a free data retrieval call binding the contract method 0xfe80b087. +// LastCheckpointTimestamp is a free data retrieval call binding the contract method 0xee94d67c. // -// Solidity: function nonBeaconChainETHBalanceWei() view returns(uint256) -func (_EigenPod *EigenPodCallerSession) NonBeaconChainETHBalanceWei() (*big.Int, error) { - return _EigenPod.Contract.NonBeaconChainETHBalanceWei(&_EigenPod.CallOpts) +// Solidity: function lastCheckpointTimestamp() view returns(uint64) +func (_EigenPod *EigenPodCallerSession) LastCheckpointTimestamp() (uint64, error) { + return _EigenPod.Contract.LastCheckpointTimestamp(&_EigenPod.CallOpts) } // PodOwner is a free data retrieval call binding the contract method 0x0b18ff66. @@ -511,66 +553,35 @@ func (_EigenPod *EigenPodCallerSession) PodOwner() (common.Address, error) { return _EigenPod.Contract.PodOwner(&_EigenPod.CallOpts) } -// ProvenWithdrawal is a free data retrieval call binding the contract method 0x34bea20a. +// ProofSubmitter is a free data retrieval call binding the contract method 0x58753357. // -// Solidity: function provenWithdrawal(bytes32 , uint64 ) view returns(bool) -func (_EigenPod *EigenPodCaller) ProvenWithdrawal(opts *bind.CallOpts, arg0 [32]byte, arg1 uint64) (bool, error) { +// Solidity: function proofSubmitter() view returns(address) +func (_EigenPod *EigenPodCaller) ProofSubmitter(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _EigenPod.contract.Call(opts, &out, "provenWithdrawal", arg0, arg1) + err := _EigenPod.contract.Call(opts, &out, "proofSubmitter") if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// ProvenWithdrawal is a free data retrieval call binding the contract method 0x34bea20a. -// -// Solidity: function provenWithdrawal(bytes32 , uint64 ) view returns(bool) -func (_EigenPod *EigenPodSession) ProvenWithdrawal(arg0 [32]byte, arg1 uint64) (bool, error) { - return _EigenPod.Contract.ProvenWithdrawal(&_EigenPod.CallOpts, arg0, arg1) -} - -// ProvenWithdrawal is a free data retrieval call binding the contract method 0x34bea20a. -// -// Solidity: function provenWithdrawal(bytes32 , uint64 ) view returns(bool) -func (_EigenPod *EigenPodCallerSession) ProvenWithdrawal(arg0 [32]byte, arg1 uint64) (bool, error) { - return _EigenPod.Contract.ProvenWithdrawal(&_EigenPod.CallOpts, arg0, arg1) -} - -// SumOfPartialWithdrawalsClaimedGwei is a free data retrieval call binding the contract method 0x5d3f65b6. -// -// Solidity: function sumOfPartialWithdrawalsClaimedGwei() view returns(uint64) -func (_EigenPod *EigenPodCaller) SumOfPartialWithdrawalsClaimedGwei(opts *bind.CallOpts) (uint64, error) { - var out []interface{} - err := _EigenPod.contract.Call(opts, &out, "sumOfPartialWithdrawalsClaimedGwei") - - if err != nil { - return *new(uint64), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// SumOfPartialWithdrawalsClaimedGwei is a free data retrieval call binding the contract method 0x5d3f65b6. +// ProofSubmitter is a free data retrieval call binding the contract method 0x58753357. // -// Solidity: function sumOfPartialWithdrawalsClaimedGwei() view returns(uint64) -func (_EigenPod *EigenPodSession) SumOfPartialWithdrawalsClaimedGwei() (uint64, error) { - return _EigenPod.Contract.SumOfPartialWithdrawalsClaimedGwei(&_EigenPod.CallOpts) +// Solidity: function proofSubmitter() view returns(address) +func (_EigenPod *EigenPodSession) ProofSubmitter() (common.Address, error) { + return _EigenPod.Contract.ProofSubmitter(&_EigenPod.CallOpts) } -// SumOfPartialWithdrawalsClaimedGwei is a free data retrieval call binding the contract method 0x5d3f65b6. +// ProofSubmitter is a free data retrieval call binding the contract method 0x58753357. // -// Solidity: function sumOfPartialWithdrawalsClaimedGwei() view returns(uint64) -func (_EigenPod *EigenPodCallerSession) SumOfPartialWithdrawalsClaimedGwei() (uint64, error) { - return _EigenPod.Contract.SumOfPartialWithdrawalsClaimedGwei(&_EigenPod.CallOpts) +// Solidity: function proofSubmitter() view returns(address) +func (_EigenPod *EigenPodCallerSession) ProofSubmitter() (common.Address, error) { + return _EigenPod.Contract.ProofSubmitter(&_EigenPod.CallOpts) } // ValidatorPubkeyHashToInfo is a free data retrieval call binding the contract method 0x6fcd0e53. @@ -728,27 +739,6 @@ func (_EigenPod *EigenPodCallerSession) WithdrawableRestakedExecutionLayerGwei() return _EigenPod.Contract.WithdrawableRestakedExecutionLayerGwei(&_EigenPod.CallOpts) } -// ActivateRestaking is a paid mutator transaction binding the contract method 0x0cd4649e. -// -// Solidity: function activateRestaking() returns() -func (_EigenPod *EigenPodTransactor) ActivateRestaking(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EigenPod.contract.Transact(opts, "activateRestaking") -} - -// ActivateRestaking is a paid mutator transaction binding the contract method 0x0cd4649e. -// -// Solidity: function activateRestaking() returns() -func (_EigenPod *EigenPodSession) ActivateRestaking() (*types.Transaction, error) { - return _EigenPod.Contract.ActivateRestaking(&_EigenPod.TransactOpts) -} - -// ActivateRestaking is a paid mutator transaction binding the contract method 0x0cd4649e. -// -// Solidity: function activateRestaking() returns() -func (_EigenPod *EigenPodTransactorSession) ActivateRestaking() (*types.Transaction, error) { - return _EigenPod.Contract.ActivateRestaking(&_EigenPod.TransactOpts) -} - // Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // // Solidity: function initialize(address _podOwner) returns() @@ -791,6 +781,27 @@ func (_EigenPod *EigenPodTransactorSession) RecoverTokens(tokenList []common.Add return _EigenPod.Contract.RecoverTokens(&_EigenPod.TransactOpts, tokenList, amountsToWithdraw, recipient) } +// SetProofSubmitter is a paid mutator transaction binding the contract method 0xd06d5587. +// +// Solidity: function setProofSubmitter(address newProofSubmitter) returns() +func (_EigenPod *EigenPodTransactor) SetProofSubmitter(opts *bind.TransactOpts, newProofSubmitter common.Address) (*types.Transaction, error) { + return _EigenPod.contract.Transact(opts, "setProofSubmitter", newProofSubmitter) +} + +// SetProofSubmitter is a paid mutator transaction binding the contract method 0xd06d5587. +// +// Solidity: function setProofSubmitter(address newProofSubmitter) returns() +func (_EigenPod *EigenPodSession) SetProofSubmitter(newProofSubmitter common.Address) (*types.Transaction, error) { + return _EigenPod.Contract.SetProofSubmitter(&_EigenPod.TransactOpts, newProofSubmitter) +} + +// SetProofSubmitter is a paid mutator transaction binding the contract method 0xd06d5587. +// +// Solidity: function setProofSubmitter(address newProofSubmitter) returns() +func (_EigenPod *EigenPodTransactorSession) SetProofSubmitter(newProofSubmitter common.Address) (*types.Transaction, error) { + return _EigenPod.Contract.SetProofSubmitter(&_EigenPod.TransactOpts, newProofSubmitter) +} + // Stake is a paid mutator transaction binding the contract method 0x9b4e4634. // // Solidity: function stake(bytes pubkey, bytes signature, bytes32 depositDataRoot) payable returns() @@ -812,109 +823,88 @@ func (_EigenPod *EigenPodTransactorSession) Stake(pubkey []byte, signature []byt return _EigenPod.Contract.Stake(&_EigenPod.TransactOpts, pubkey, signature, depositDataRoot) } -// VerifyAndProcessWithdrawals is a paid mutator transaction binding the contract method 0xe251ef52. +// StartCheckpoint is a paid mutator transaction binding the contract method 0x88676cad. // -// Solidity: function verifyAndProcessWithdrawals(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, (bytes,bytes,bytes,bytes,bytes,uint64,uint64,uint64,bytes32,bytes32,bytes32,bytes32)[] withdrawalProofs, bytes[] validatorFieldsProofs, bytes32[][] validatorFields, bytes32[][] withdrawalFields) returns() -func (_EigenPod *EigenPodTransactor) VerifyAndProcessWithdrawals(opts *bind.TransactOpts, oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, withdrawalProofs []BeaconChainProofsWithdrawalProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte, withdrawalFields [][][32]byte) (*types.Transaction, error) { - return _EigenPod.contract.Transact(opts, "verifyAndProcessWithdrawals", oracleTimestamp, stateRootProof, withdrawalProofs, validatorFieldsProofs, validatorFields, withdrawalFields) +// Solidity: function startCheckpoint(bool revertIfNoBalance) returns() +func (_EigenPod *EigenPodTransactor) StartCheckpoint(opts *bind.TransactOpts, revertIfNoBalance bool) (*types.Transaction, error) { + return _EigenPod.contract.Transact(opts, "startCheckpoint", revertIfNoBalance) } -// VerifyAndProcessWithdrawals is a paid mutator transaction binding the contract method 0xe251ef52. +// StartCheckpoint is a paid mutator transaction binding the contract method 0x88676cad. // -// Solidity: function verifyAndProcessWithdrawals(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, (bytes,bytes,bytes,bytes,bytes,uint64,uint64,uint64,bytes32,bytes32,bytes32,bytes32)[] withdrawalProofs, bytes[] validatorFieldsProofs, bytes32[][] validatorFields, bytes32[][] withdrawalFields) returns() -func (_EigenPod *EigenPodSession) VerifyAndProcessWithdrawals(oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, withdrawalProofs []BeaconChainProofsWithdrawalProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte, withdrawalFields [][][32]byte) (*types.Transaction, error) { - return _EigenPod.Contract.VerifyAndProcessWithdrawals(&_EigenPod.TransactOpts, oracleTimestamp, stateRootProof, withdrawalProofs, validatorFieldsProofs, validatorFields, withdrawalFields) +// Solidity: function startCheckpoint(bool revertIfNoBalance) returns() +func (_EigenPod *EigenPodSession) StartCheckpoint(revertIfNoBalance bool) (*types.Transaction, error) { + return _EigenPod.Contract.StartCheckpoint(&_EigenPod.TransactOpts, revertIfNoBalance) } -// VerifyAndProcessWithdrawals is a paid mutator transaction binding the contract method 0xe251ef52. +// StartCheckpoint is a paid mutator transaction binding the contract method 0x88676cad. // -// Solidity: function verifyAndProcessWithdrawals(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, (bytes,bytes,bytes,bytes,bytes,uint64,uint64,uint64,bytes32,bytes32,bytes32,bytes32)[] withdrawalProofs, bytes[] validatorFieldsProofs, bytes32[][] validatorFields, bytes32[][] withdrawalFields) returns() -func (_EigenPod *EigenPodTransactorSession) VerifyAndProcessWithdrawals(oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, withdrawalProofs []BeaconChainProofsWithdrawalProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte, withdrawalFields [][][32]byte) (*types.Transaction, error) { - return _EigenPod.Contract.VerifyAndProcessWithdrawals(&_EigenPod.TransactOpts, oracleTimestamp, stateRootProof, withdrawalProofs, validatorFieldsProofs, validatorFields, withdrawalFields) +// Solidity: function startCheckpoint(bool revertIfNoBalance) returns() +func (_EigenPod *EigenPodTransactorSession) StartCheckpoint(revertIfNoBalance bool) (*types.Transaction, error) { + return _EigenPod.Contract.StartCheckpoint(&_EigenPod.TransactOpts, revertIfNoBalance) } -// VerifyBalanceUpdates is a paid mutator transaction binding the contract method 0xa50600f4. +// VerifyCheckpointProofs is a paid mutator transaction binding the contract method 0xf074ba62. // -// Solidity: function verifyBalanceUpdates(uint64 oracleTimestamp, uint40[] validatorIndices, (bytes32,bytes) stateRootProof, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() -func (_EigenPod *EigenPodTransactor) VerifyBalanceUpdates(opts *bind.TransactOpts, oracleTimestamp uint64, validatorIndices []*big.Int, stateRootProof BeaconChainProofsStateRootProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _EigenPod.contract.Transact(opts, "verifyBalanceUpdates", oracleTimestamp, validatorIndices, stateRootProof, validatorFieldsProofs, validatorFields) +// Solidity: function verifyCheckpointProofs((bytes32,bytes) balanceContainerProof, (bytes32,bytes32,bytes)[] proofs) returns() +func (_EigenPod *EigenPodTransactor) VerifyCheckpointProofs(opts *bind.TransactOpts, balanceContainerProof BeaconChainProofsBalanceContainerProof, proofs []BeaconChainProofsBalanceProof) (*types.Transaction, error) { + return _EigenPod.contract.Transact(opts, "verifyCheckpointProofs", balanceContainerProof, proofs) } -// VerifyBalanceUpdates is a paid mutator transaction binding the contract method 0xa50600f4. +// VerifyCheckpointProofs is a paid mutator transaction binding the contract method 0xf074ba62. // -// Solidity: function verifyBalanceUpdates(uint64 oracleTimestamp, uint40[] validatorIndices, (bytes32,bytes) stateRootProof, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() -func (_EigenPod *EigenPodSession) VerifyBalanceUpdates(oracleTimestamp uint64, validatorIndices []*big.Int, stateRootProof BeaconChainProofsStateRootProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _EigenPod.Contract.VerifyBalanceUpdates(&_EigenPod.TransactOpts, oracleTimestamp, validatorIndices, stateRootProof, validatorFieldsProofs, validatorFields) +// Solidity: function verifyCheckpointProofs((bytes32,bytes) balanceContainerProof, (bytes32,bytes32,bytes)[] proofs) returns() +func (_EigenPod *EigenPodSession) VerifyCheckpointProofs(balanceContainerProof BeaconChainProofsBalanceContainerProof, proofs []BeaconChainProofsBalanceProof) (*types.Transaction, error) { + return _EigenPod.Contract.VerifyCheckpointProofs(&_EigenPod.TransactOpts, balanceContainerProof, proofs) } -// VerifyBalanceUpdates is a paid mutator transaction binding the contract method 0xa50600f4. +// VerifyCheckpointProofs is a paid mutator transaction binding the contract method 0xf074ba62. // -// Solidity: function verifyBalanceUpdates(uint64 oracleTimestamp, uint40[] validatorIndices, (bytes32,bytes) stateRootProof, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() -func (_EigenPod *EigenPodTransactorSession) VerifyBalanceUpdates(oracleTimestamp uint64, validatorIndices []*big.Int, stateRootProof BeaconChainProofsStateRootProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _EigenPod.Contract.VerifyBalanceUpdates(&_EigenPod.TransactOpts, oracleTimestamp, validatorIndices, stateRootProof, validatorFieldsProofs, validatorFields) +// Solidity: function verifyCheckpointProofs((bytes32,bytes) balanceContainerProof, (bytes32,bytes32,bytes)[] proofs) returns() +func (_EigenPod *EigenPodTransactorSession) VerifyCheckpointProofs(balanceContainerProof BeaconChainProofsBalanceContainerProof, proofs []BeaconChainProofsBalanceProof) (*types.Transaction, error) { + return _EigenPod.Contract.VerifyCheckpointProofs(&_EigenPod.TransactOpts, balanceContainerProof, proofs) } -// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. +// VerifyStaleBalance is a paid mutator transaction binding the contract method 0x039157d2. // -// Solidity: function verifyWithdrawalCredentials(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() -func (_EigenPod *EigenPodTransactor) VerifyWithdrawalCredentials(opts *bind.TransactOpts, oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _EigenPod.contract.Transact(opts, "verifyWithdrawalCredentials", oracleTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) +// Solidity: function verifyStaleBalance(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, (bytes32[],bytes) proof) returns() +func (_EigenPod *EigenPodTransactor) VerifyStaleBalance(opts *bind.TransactOpts, beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, proof BeaconChainProofsValidatorProof) (*types.Transaction, error) { + return _EigenPod.contract.Transact(opts, "verifyStaleBalance", beaconTimestamp, stateRootProof, proof) } -// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. +// VerifyStaleBalance is a paid mutator transaction binding the contract method 0x039157d2. // -// Solidity: function verifyWithdrawalCredentials(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() -func (_EigenPod *EigenPodSession) VerifyWithdrawalCredentials(oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _EigenPod.Contract.VerifyWithdrawalCredentials(&_EigenPod.TransactOpts, oracleTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) +// Solidity: function verifyStaleBalance(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, (bytes32[],bytes) proof) returns() +func (_EigenPod *EigenPodSession) VerifyStaleBalance(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, proof BeaconChainProofsValidatorProof) (*types.Transaction, error) { + return _EigenPod.Contract.VerifyStaleBalance(&_EigenPod.TransactOpts, beaconTimestamp, stateRootProof, proof) } -// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. +// VerifyStaleBalance is a paid mutator transaction binding the contract method 0x039157d2. // -// Solidity: function verifyWithdrawalCredentials(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() -func (_EigenPod *EigenPodTransactorSession) VerifyWithdrawalCredentials(oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _EigenPod.Contract.VerifyWithdrawalCredentials(&_EigenPod.TransactOpts, oracleTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) +// Solidity: function verifyStaleBalance(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, (bytes32[],bytes) proof) returns() +func (_EigenPod *EigenPodTransactorSession) VerifyStaleBalance(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, proof BeaconChainProofsValidatorProof) (*types.Transaction, error) { + return _EigenPod.Contract.VerifyStaleBalance(&_EigenPod.TransactOpts, beaconTimestamp, stateRootProof, proof) } -// WithdrawBeforeRestaking is a paid mutator transaction binding the contract method 0xbaa7145a. -// -// Solidity: function withdrawBeforeRestaking() returns() -func (_EigenPod *EigenPodTransactor) WithdrawBeforeRestaking(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EigenPod.contract.Transact(opts, "withdrawBeforeRestaking") -} - -// WithdrawBeforeRestaking is a paid mutator transaction binding the contract method 0xbaa7145a. -// -// Solidity: function withdrawBeforeRestaking() returns() -func (_EigenPod *EigenPodSession) WithdrawBeforeRestaking() (*types.Transaction, error) { - return _EigenPod.Contract.WithdrawBeforeRestaking(&_EigenPod.TransactOpts) -} - -// WithdrawBeforeRestaking is a paid mutator transaction binding the contract method 0xbaa7145a. -// -// Solidity: function withdrawBeforeRestaking() returns() -func (_EigenPod *EigenPodTransactorSession) WithdrawBeforeRestaking() (*types.Transaction, error) { - return _EigenPod.Contract.WithdrawBeforeRestaking(&_EigenPod.TransactOpts) -} - -// WithdrawNonBeaconChainETHBalanceWei is a paid mutator transaction binding the contract method 0xe2c83445. +// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. // -// Solidity: function withdrawNonBeaconChainETHBalanceWei(address recipient, uint256 amountToWithdraw) returns() -func (_EigenPod *EigenPodTransactor) WithdrawNonBeaconChainETHBalanceWei(opts *bind.TransactOpts, recipient common.Address, amountToWithdraw *big.Int) (*types.Transaction, error) { - return _EigenPod.contract.Transact(opts, "withdrawNonBeaconChainETHBalanceWei", recipient, amountToWithdraw) +// Solidity: function verifyWithdrawalCredentials(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() +func (_EigenPod *EigenPodTransactor) VerifyWithdrawalCredentials(opts *bind.TransactOpts, beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { + return _EigenPod.contract.Transact(opts, "verifyWithdrawalCredentials", beaconTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) } -// WithdrawNonBeaconChainETHBalanceWei is a paid mutator transaction binding the contract method 0xe2c83445. +// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. // -// Solidity: function withdrawNonBeaconChainETHBalanceWei(address recipient, uint256 amountToWithdraw) returns() -func (_EigenPod *EigenPodSession) WithdrawNonBeaconChainETHBalanceWei(recipient common.Address, amountToWithdraw *big.Int) (*types.Transaction, error) { - return _EigenPod.Contract.WithdrawNonBeaconChainETHBalanceWei(&_EigenPod.TransactOpts, recipient, amountToWithdraw) +// Solidity: function verifyWithdrawalCredentials(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() +func (_EigenPod *EigenPodSession) VerifyWithdrawalCredentials(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { + return _EigenPod.Contract.VerifyWithdrawalCredentials(&_EigenPod.TransactOpts, beaconTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) } -// WithdrawNonBeaconChainETHBalanceWei is a paid mutator transaction binding the contract method 0xe2c83445. +// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. // -// Solidity: function withdrawNonBeaconChainETHBalanceWei(address recipient, uint256 amountToWithdraw) returns() -func (_EigenPod *EigenPodTransactorSession) WithdrawNonBeaconChainETHBalanceWei(recipient common.Address, amountToWithdraw *big.Int) (*types.Transaction, error) { - return _EigenPod.Contract.WithdrawNonBeaconChainETHBalanceWei(&_EigenPod.TransactOpts, recipient, amountToWithdraw) +// Solidity: function verifyWithdrawalCredentials(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() +func (_EigenPod *EigenPodTransactorSession) VerifyWithdrawalCredentials(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { + return _EigenPod.Contract.VerifyWithdrawalCredentials(&_EigenPod.TransactOpts, beaconTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) } // WithdrawRestakedBeaconChainETH is a paid mutator transaction binding the contract method 0xc4907442. @@ -959,9 +949,9 @@ func (_EigenPod *EigenPodTransactorSession) Receive() (*types.Transaction, error return _EigenPod.Contract.Receive(&_EigenPod.TransactOpts) } -// EigenPodEigenPodStakedIterator is returned from FilterEigenPodStaked and is used to iterate over the raw logs and unpacked data for EigenPodStaked events raised by the EigenPod contract. -type EigenPodEigenPodStakedIterator struct { - Event *EigenPodEigenPodStaked // Event containing the contract specifics and raw log +// EigenPodCheckpointCreatedIterator is returned from FilterCheckpointCreated and is used to iterate over the raw logs and unpacked data for CheckpointCreated events raised by the EigenPod contract. +type EigenPodCheckpointCreatedIterator struct { + Event *EigenPodCheckpointCreated // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -975,7 +965,7 @@ type EigenPodEigenPodStakedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodEigenPodStakedIterator) Next() bool { +func (it *EigenPodCheckpointCreatedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -984,7 +974,7 @@ func (it *EigenPodEigenPodStakedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodEigenPodStaked) + it.Event = new(EigenPodCheckpointCreated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -999,7 +989,7 @@ func (it *EigenPodEigenPodStakedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodEigenPodStaked) + it.Event = new(EigenPodCheckpointCreated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1015,41 +1005,61 @@ func (it *EigenPodEigenPodStakedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodEigenPodStakedIterator) Error() error { +func (it *EigenPodCheckpointCreatedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodEigenPodStakedIterator) Close() error { +func (it *EigenPodCheckpointCreatedIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodEigenPodStaked represents a EigenPodStaked event raised by the EigenPod contract. -type EigenPodEigenPodStaked struct { - Pubkey []byte - Raw types.Log // Blockchain specific contextual infos +// EigenPodCheckpointCreated represents a CheckpointCreated event raised by the EigenPod contract. +type EigenPodCheckpointCreated struct { + CheckpointTimestamp uint64 + BeaconBlockRoot [32]byte + ValidatorCount *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterEigenPodStaked is a free log retrieval operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// FilterCheckpointCreated is a free log retrieval operation binding the contract event 0x575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076. // -// Solidity: event EigenPodStaked(bytes pubkey) -func (_EigenPod *EigenPodFilterer) FilterEigenPodStaked(opts *bind.FilterOpts) (*EigenPodEigenPodStakedIterator, error) { +// Solidity: event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount) +func (_EigenPod *EigenPodFilterer) FilterCheckpointCreated(opts *bind.FilterOpts, checkpointTimestamp []uint64, beaconBlockRoot [][32]byte) (*EigenPodCheckpointCreatedIterator, error) { - logs, sub, err := _EigenPod.contract.FilterLogs(opts, "EigenPodStaked") + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var beaconBlockRootRule []interface{} + for _, beaconBlockRootItem := range beaconBlockRoot { + beaconBlockRootRule = append(beaconBlockRootRule, beaconBlockRootItem) + } + + logs, sub, err := _EigenPod.contract.FilterLogs(opts, "CheckpointCreated", checkpointTimestampRule, beaconBlockRootRule) if err != nil { return nil, err } - return &EigenPodEigenPodStakedIterator{contract: _EigenPod.contract, event: "EigenPodStaked", logs: logs, sub: sub}, nil + return &EigenPodCheckpointCreatedIterator{contract: _EigenPod.contract, event: "CheckpointCreated", logs: logs, sub: sub}, nil } -// WatchEigenPodStaked is a free log subscription operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// WatchCheckpointCreated is a free log subscription operation binding the contract event 0x575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076. // -// Solidity: event EigenPodStaked(bytes pubkey) -func (_EigenPod *EigenPodFilterer) WatchEigenPodStaked(opts *bind.WatchOpts, sink chan<- *EigenPodEigenPodStaked) (event.Subscription, error) { +// Solidity: event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount) +func (_EigenPod *EigenPodFilterer) WatchCheckpointCreated(opts *bind.WatchOpts, sink chan<- *EigenPodCheckpointCreated, checkpointTimestamp []uint64, beaconBlockRoot [][32]byte) (event.Subscription, error) { - logs, sub, err := _EigenPod.contract.WatchLogs(opts, "EigenPodStaked") + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var beaconBlockRootRule []interface{} + for _, beaconBlockRootItem := range beaconBlockRoot { + beaconBlockRootRule = append(beaconBlockRootRule, beaconBlockRootItem) + } + + logs, sub, err := _EigenPod.contract.WatchLogs(opts, "CheckpointCreated", checkpointTimestampRule, beaconBlockRootRule) if err != nil { return nil, err } @@ -1059,8 +1069,8 @@ func (_EigenPod *EigenPodFilterer) WatchEigenPodStaked(opts *bind.WatchOpts, sin select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodEigenPodStaked) - if err := _EigenPod.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { + event := new(EigenPodCheckpointCreated) + if err := _EigenPod.contract.UnpackLog(event, "CheckpointCreated", log); err != nil { return err } event.Raw = log @@ -1081,21 +1091,21 @@ func (_EigenPod *EigenPodFilterer) WatchEigenPodStaked(opts *bind.WatchOpts, sin }), nil } -// ParseEigenPodStaked is a log parse operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// ParseCheckpointCreated is a log parse operation binding the contract event 0x575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076. // -// Solidity: event EigenPodStaked(bytes pubkey) -func (_EigenPod *EigenPodFilterer) ParseEigenPodStaked(log types.Log) (*EigenPodEigenPodStaked, error) { - event := new(EigenPodEigenPodStaked) - if err := _EigenPod.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { +// Solidity: event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount) +func (_EigenPod *EigenPodFilterer) ParseCheckpointCreated(log types.Log) (*EigenPodCheckpointCreated, error) { + event := new(EigenPodCheckpointCreated) + if err := _EigenPod.contract.UnpackLog(event, "CheckpointCreated", log); err != nil { return nil, err } event.Raw = log return event, nil } -// EigenPodFullWithdrawalRedeemedIterator is returned from FilterFullWithdrawalRedeemed and is used to iterate over the raw logs and unpacked data for FullWithdrawalRedeemed events raised by the EigenPod contract. -type EigenPodFullWithdrawalRedeemedIterator struct { - Event *EigenPodFullWithdrawalRedeemed // Event containing the contract specifics and raw log +// EigenPodCheckpointFinalizedIterator is returned from FilterCheckpointFinalized and is used to iterate over the raw logs and unpacked data for CheckpointFinalized events raised by the EigenPod contract. +type EigenPodCheckpointFinalizedIterator struct { + Event *EigenPodCheckpointFinalized // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1109,7 +1119,7 @@ type EigenPodFullWithdrawalRedeemedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodFullWithdrawalRedeemedIterator) Next() bool { +func (it *EigenPodCheckpointFinalizedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1118,7 +1128,7 @@ func (it *EigenPodFullWithdrawalRedeemedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodFullWithdrawalRedeemed) + it.Event = new(EigenPodCheckpointFinalized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1133,7 +1143,7 @@ func (it *EigenPodFullWithdrawalRedeemedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodFullWithdrawalRedeemed) + it.Event = new(EigenPodCheckpointFinalized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1149,54 +1159,186 @@ func (it *EigenPodFullWithdrawalRedeemedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodFullWithdrawalRedeemedIterator) Error() error { +func (it *EigenPodCheckpointFinalizedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodFullWithdrawalRedeemedIterator) Close() error { +func (it *EigenPodCheckpointFinalizedIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodFullWithdrawalRedeemed represents a FullWithdrawalRedeemed event raised by the EigenPod contract. -type EigenPodFullWithdrawalRedeemed struct { - ValidatorIndex *big.Int - WithdrawalTimestamp uint64 - Recipient common.Address - WithdrawalAmountGwei uint64 - Raw types.Log // Blockchain specific contextual infos +// EigenPodCheckpointFinalized represents a CheckpointFinalized event raised by the EigenPod contract. +type EigenPodCheckpointFinalized struct { + CheckpointTimestamp uint64 + TotalShareDeltaWei *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterFullWithdrawalRedeemed is a free log retrieval operation binding the contract event 0xb76a93bb649ece524688f1a01d184e0bbebcda58eae80c28a898bec3fb5a0963. +// FilterCheckpointFinalized is a free log retrieval operation binding the contract event 0x525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44. // -// Solidity: event FullWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 withdrawalAmountGwei) -func (_EigenPod *EigenPodFilterer) FilterFullWithdrawalRedeemed(opts *bind.FilterOpts, recipient []common.Address) (*EigenPodFullWithdrawalRedeemedIterator, error) { +// Solidity: event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei) +func (_EigenPod *EigenPodFilterer) FilterCheckpointFinalized(opts *bind.FilterOpts, checkpointTimestamp []uint64) (*EigenPodCheckpointFinalizedIterator, error) { - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) } - logs, sub, err := _EigenPod.contract.FilterLogs(opts, "FullWithdrawalRedeemed", recipientRule) + logs, sub, err := _EigenPod.contract.FilterLogs(opts, "CheckpointFinalized", checkpointTimestampRule) if err != nil { return nil, err } - return &EigenPodFullWithdrawalRedeemedIterator{contract: _EigenPod.contract, event: "FullWithdrawalRedeemed", logs: logs, sub: sub}, nil + return &EigenPodCheckpointFinalizedIterator{contract: _EigenPod.contract, event: "CheckpointFinalized", logs: logs, sub: sub}, nil } -// WatchFullWithdrawalRedeemed is a free log subscription operation binding the contract event 0xb76a93bb649ece524688f1a01d184e0bbebcda58eae80c28a898bec3fb5a0963. +// WatchCheckpointFinalized is a free log subscription operation binding the contract event 0x525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44. // -// Solidity: event FullWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 withdrawalAmountGwei) -func (_EigenPod *EigenPodFilterer) WatchFullWithdrawalRedeemed(opts *bind.WatchOpts, sink chan<- *EigenPodFullWithdrawalRedeemed, recipient []common.Address) (event.Subscription, error) { +// Solidity: event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei) +func (_EigenPod *EigenPodFilterer) WatchCheckpointFinalized(opts *bind.WatchOpts, sink chan<- *EigenPodCheckpointFinalized, checkpointTimestamp []uint64) (event.Subscription, error) { - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + + logs, sub, err := _EigenPod.contract.WatchLogs(opts, "CheckpointFinalized", checkpointTimestampRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodCheckpointFinalized) + if err := _EigenPod.contract.UnpackLog(event, "CheckpointFinalized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCheckpointFinalized is a log parse operation binding the contract event 0x525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44. +// +// Solidity: event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei) +func (_EigenPod *EigenPodFilterer) ParseCheckpointFinalized(log types.Log) (*EigenPodCheckpointFinalized, error) { + event := new(EigenPodCheckpointFinalized) + if err := _EigenPod.contract.UnpackLog(event, "CheckpointFinalized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodEigenPodStakedIterator is returned from FilterEigenPodStaked and is used to iterate over the raw logs and unpacked data for EigenPodStaked events raised by the EigenPod contract. +type EigenPodEigenPodStakedIterator struct { + Event *EigenPodEigenPodStaked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodEigenPodStakedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodEigenPodStaked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodEigenPodStaked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodEigenPodStakedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodEigenPodStakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodEigenPodStaked represents a EigenPodStaked event raised by the EigenPod contract. +type EigenPodEigenPodStaked struct { + Pubkey []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEigenPodStaked is a free log retrieval operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// +// Solidity: event EigenPodStaked(bytes pubkey) +func (_EigenPod *EigenPodFilterer) FilterEigenPodStaked(opts *bind.FilterOpts) (*EigenPodEigenPodStakedIterator, error) { + + logs, sub, err := _EigenPod.contract.FilterLogs(opts, "EigenPodStaked") + if err != nil { + return nil, err } + return &EigenPodEigenPodStakedIterator{contract: _EigenPod.contract, event: "EigenPodStaked", logs: logs, sub: sub}, nil +} + +// WatchEigenPodStaked is a free log subscription operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// +// Solidity: event EigenPodStaked(bytes pubkey) +func (_EigenPod *EigenPodFilterer) WatchEigenPodStaked(opts *bind.WatchOpts, sink chan<- *EigenPodEigenPodStaked) (event.Subscription, error) { - logs, sub, err := _EigenPod.contract.WatchLogs(opts, "FullWithdrawalRedeemed", recipientRule) + logs, sub, err := _EigenPod.contract.WatchLogs(opts, "EigenPodStaked") if err != nil { return nil, err } @@ -1206,8 +1348,8 @@ func (_EigenPod *EigenPodFilterer) WatchFullWithdrawalRedeemed(opts *bind.WatchO select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodFullWithdrawalRedeemed) - if err := _EigenPod.contract.UnpackLog(event, "FullWithdrawalRedeemed", log); err != nil { + event := new(EigenPodEigenPodStaked) + if err := _EigenPod.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { return err } event.Raw = log @@ -1228,12 +1370,12 @@ func (_EigenPod *EigenPodFilterer) WatchFullWithdrawalRedeemed(opts *bind.WatchO }), nil } -// ParseFullWithdrawalRedeemed is a log parse operation binding the contract event 0xb76a93bb649ece524688f1a01d184e0bbebcda58eae80c28a898bec3fb5a0963. +// ParseEigenPodStaked is a log parse operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. // -// Solidity: event FullWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 withdrawalAmountGwei) -func (_EigenPod *EigenPodFilterer) ParseFullWithdrawalRedeemed(log types.Log) (*EigenPodFullWithdrawalRedeemed, error) { - event := new(EigenPodFullWithdrawalRedeemed) - if err := _EigenPod.contract.UnpackLog(event, "FullWithdrawalRedeemed", log); err != nil { +// Solidity: event EigenPodStaked(bytes pubkey) +func (_EigenPod *EigenPodFilterer) ParseEigenPodStaked(log types.Log) (*EigenPodEigenPodStaked, error) { + event := new(EigenPodEigenPodStaked) + if err := _EigenPod.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { return nil, err } event.Raw = log @@ -1508,9 +1650,9 @@ func (_EigenPod *EigenPodFilterer) ParseNonBeaconChainETHReceived(log types.Log) return event, nil } -// EigenPodNonBeaconChainETHWithdrawnIterator is returned from FilterNonBeaconChainETHWithdrawn and is used to iterate over the raw logs and unpacked data for NonBeaconChainETHWithdrawn events raised by the EigenPod contract. -type EigenPodNonBeaconChainETHWithdrawnIterator struct { - Event *EigenPodNonBeaconChainETHWithdrawn // Event containing the contract specifics and raw log +// EigenPodProofSubmitterUpdatedIterator is returned from FilterProofSubmitterUpdated and is used to iterate over the raw logs and unpacked data for ProofSubmitterUpdated events raised by the EigenPod contract. +type EigenPodProofSubmitterUpdatedIterator struct { + Event *EigenPodProofSubmitterUpdated // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1524,7 +1666,7 @@ type EigenPodNonBeaconChainETHWithdrawnIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodNonBeaconChainETHWithdrawnIterator) Next() bool { +func (it *EigenPodProofSubmitterUpdatedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1533,7 +1675,7 @@ func (it *EigenPodNonBeaconChainETHWithdrawnIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodNonBeaconChainETHWithdrawn) + it.Event = new(EigenPodProofSubmitterUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1548,7 +1690,7 @@ func (it *EigenPodNonBeaconChainETHWithdrawnIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodNonBeaconChainETHWithdrawn) + it.Event = new(EigenPodProofSubmitterUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1564,52 +1706,42 @@ func (it *EigenPodNonBeaconChainETHWithdrawnIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodNonBeaconChainETHWithdrawnIterator) Error() error { +func (it *EigenPodProofSubmitterUpdatedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodNonBeaconChainETHWithdrawnIterator) Close() error { +func (it *EigenPodProofSubmitterUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodNonBeaconChainETHWithdrawn represents a NonBeaconChainETHWithdrawn event raised by the EigenPod contract. -type EigenPodNonBeaconChainETHWithdrawn struct { - Recipient common.Address - AmountWithdrawn *big.Int - Raw types.Log // Blockchain specific contextual infos +// EigenPodProofSubmitterUpdated represents a ProofSubmitterUpdated event raised by the EigenPod contract. +type EigenPodProofSubmitterUpdated struct { + PrevProofSubmitter common.Address + NewProofSubmitter common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterNonBeaconChainETHWithdrawn is a free log retrieval operation binding the contract event 0x30420aacd028abb3c1fd03aba253ae725d6ddd52d16c9ac4cb5742cd43f53096. +// FilterProofSubmitterUpdated is a free log retrieval operation binding the contract event 0xfb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac. // -// Solidity: event NonBeaconChainETHWithdrawn(address indexed recipient, uint256 amountWithdrawn) -func (_EigenPod *EigenPodFilterer) FilterNonBeaconChainETHWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*EigenPodNonBeaconChainETHWithdrawnIterator, error) { +// Solidity: event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter) +func (_EigenPod *EigenPodFilterer) FilterProofSubmitterUpdated(opts *bind.FilterOpts) (*EigenPodProofSubmitterUpdatedIterator, error) { - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) - } - - logs, sub, err := _EigenPod.contract.FilterLogs(opts, "NonBeaconChainETHWithdrawn", recipientRule) + logs, sub, err := _EigenPod.contract.FilterLogs(opts, "ProofSubmitterUpdated") if err != nil { return nil, err } - return &EigenPodNonBeaconChainETHWithdrawnIterator{contract: _EigenPod.contract, event: "NonBeaconChainETHWithdrawn", logs: logs, sub: sub}, nil + return &EigenPodProofSubmitterUpdatedIterator{contract: _EigenPod.contract, event: "ProofSubmitterUpdated", logs: logs, sub: sub}, nil } -// WatchNonBeaconChainETHWithdrawn is a free log subscription operation binding the contract event 0x30420aacd028abb3c1fd03aba253ae725d6ddd52d16c9ac4cb5742cd43f53096. +// WatchProofSubmitterUpdated is a free log subscription operation binding the contract event 0xfb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac. // -// Solidity: event NonBeaconChainETHWithdrawn(address indexed recipient, uint256 amountWithdrawn) -func (_EigenPod *EigenPodFilterer) WatchNonBeaconChainETHWithdrawn(opts *bind.WatchOpts, sink chan<- *EigenPodNonBeaconChainETHWithdrawn, recipient []common.Address) (event.Subscription, error) { +// Solidity: event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter) +func (_EigenPod *EigenPodFilterer) WatchProofSubmitterUpdated(opts *bind.WatchOpts, sink chan<- *EigenPodProofSubmitterUpdated) (event.Subscription, error) { - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) - } - - logs, sub, err := _EigenPod.contract.WatchLogs(opts, "NonBeaconChainETHWithdrawn", recipientRule) + logs, sub, err := _EigenPod.contract.WatchLogs(opts, "ProofSubmitterUpdated") if err != nil { return nil, err } @@ -1619,8 +1751,8 @@ func (_EigenPod *EigenPodFilterer) WatchNonBeaconChainETHWithdrawn(opts *bind.Wa select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodNonBeaconChainETHWithdrawn) - if err := _EigenPod.contract.UnpackLog(event, "NonBeaconChainETHWithdrawn", log); err != nil { + event := new(EigenPodProofSubmitterUpdated) + if err := _EigenPod.contract.UnpackLog(event, "ProofSubmitterUpdated", log); err != nil { return err } event.Raw = log @@ -1641,21 +1773,21 @@ func (_EigenPod *EigenPodFilterer) WatchNonBeaconChainETHWithdrawn(opts *bind.Wa }), nil } -// ParseNonBeaconChainETHWithdrawn is a log parse operation binding the contract event 0x30420aacd028abb3c1fd03aba253ae725d6ddd52d16c9ac4cb5742cd43f53096. +// ParseProofSubmitterUpdated is a log parse operation binding the contract event 0xfb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac. // -// Solidity: event NonBeaconChainETHWithdrawn(address indexed recipient, uint256 amountWithdrawn) -func (_EigenPod *EigenPodFilterer) ParseNonBeaconChainETHWithdrawn(log types.Log) (*EigenPodNonBeaconChainETHWithdrawn, error) { - event := new(EigenPodNonBeaconChainETHWithdrawn) - if err := _EigenPod.contract.UnpackLog(event, "NonBeaconChainETHWithdrawn", log); err != nil { +// Solidity: event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter) +func (_EigenPod *EigenPodFilterer) ParseProofSubmitterUpdated(log types.Log) (*EigenPodProofSubmitterUpdated, error) { + event := new(EigenPodProofSubmitterUpdated) + if err := _EigenPod.contract.UnpackLog(event, "ProofSubmitterUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -// EigenPodPartialWithdrawalRedeemedIterator is returned from FilterPartialWithdrawalRedeemed and is used to iterate over the raw logs and unpacked data for PartialWithdrawalRedeemed events raised by the EigenPod contract. -type EigenPodPartialWithdrawalRedeemedIterator struct { - Event *EigenPodPartialWithdrawalRedeemed // Event containing the contract specifics and raw log +// EigenPodRestakedBeaconChainETHWithdrawnIterator is returned from FilterRestakedBeaconChainETHWithdrawn and is used to iterate over the raw logs and unpacked data for RestakedBeaconChainETHWithdrawn events raised by the EigenPod contract. +type EigenPodRestakedBeaconChainETHWithdrawnIterator struct { + Event *EigenPodRestakedBeaconChainETHWithdrawn // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1669,7 +1801,7 @@ type EigenPodPartialWithdrawalRedeemedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodPartialWithdrawalRedeemedIterator) Next() bool { +func (it *EigenPodRestakedBeaconChainETHWithdrawnIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1678,7 +1810,7 @@ func (it *EigenPodPartialWithdrawalRedeemedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodPartialWithdrawalRedeemed) + it.Event = new(EigenPodRestakedBeaconChainETHWithdrawn) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1693,7 +1825,7 @@ func (it *EigenPodPartialWithdrawalRedeemedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodPartialWithdrawalRedeemed) + it.Event = new(EigenPodRestakedBeaconChainETHWithdrawn) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1709,54 +1841,52 @@ func (it *EigenPodPartialWithdrawalRedeemedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodPartialWithdrawalRedeemedIterator) Error() error { +func (it *EigenPodRestakedBeaconChainETHWithdrawnIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodPartialWithdrawalRedeemedIterator) Close() error { +func (it *EigenPodRestakedBeaconChainETHWithdrawnIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodPartialWithdrawalRedeemed represents a PartialWithdrawalRedeemed event raised by the EigenPod contract. -type EigenPodPartialWithdrawalRedeemed struct { - ValidatorIndex *big.Int - WithdrawalTimestamp uint64 - Recipient common.Address - PartialWithdrawalAmountGwei uint64 - Raw types.Log // Blockchain specific contextual infos +// EigenPodRestakedBeaconChainETHWithdrawn represents a RestakedBeaconChainETHWithdrawn event raised by the EigenPod contract. +type EigenPodRestakedBeaconChainETHWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterPartialWithdrawalRedeemed is a free log retrieval operation binding the contract event 0x8a7335714231dbd551aaba6314f4a97a14c201e53a3e25e1140325cdf67d7a4e. +// FilterRestakedBeaconChainETHWithdrawn is a free log retrieval operation binding the contract event 0x8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e. // -// Solidity: event PartialWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 partialWithdrawalAmountGwei) -func (_EigenPod *EigenPodFilterer) FilterPartialWithdrawalRedeemed(opts *bind.FilterOpts, recipient []common.Address) (*EigenPodPartialWithdrawalRedeemedIterator, error) { +// Solidity: event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount) +func (_EigenPod *EigenPodFilterer) FilterRestakedBeaconChainETHWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*EigenPodRestakedBeaconChainETHWithdrawnIterator, error) { var recipientRule []interface{} for _, recipientItem := range recipient { recipientRule = append(recipientRule, recipientItem) } - logs, sub, err := _EigenPod.contract.FilterLogs(opts, "PartialWithdrawalRedeemed", recipientRule) + logs, sub, err := _EigenPod.contract.FilterLogs(opts, "RestakedBeaconChainETHWithdrawn", recipientRule) if err != nil { return nil, err } - return &EigenPodPartialWithdrawalRedeemedIterator{contract: _EigenPod.contract, event: "PartialWithdrawalRedeemed", logs: logs, sub: sub}, nil + return &EigenPodRestakedBeaconChainETHWithdrawnIterator{contract: _EigenPod.contract, event: "RestakedBeaconChainETHWithdrawn", logs: logs, sub: sub}, nil } -// WatchPartialWithdrawalRedeemed is a free log subscription operation binding the contract event 0x8a7335714231dbd551aaba6314f4a97a14c201e53a3e25e1140325cdf67d7a4e. +// WatchRestakedBeaconChainETHWithdrawn is a free log subscription operation binding the contract event 0x8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e. // -// Solidity: event PartialWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 partialWithdrawalAmountGwei) -func (_EigenPod *EigenPodFilterer) WatchPartialWithdrawalRedeemed(opts *bind.WatchOpts, sink chan<- *EigenPodPartialWithdrawalRedeemed, recipient []common.Address) (event.Subscription, error) { +// Solidity: event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount) +func (_EigenPod *EigenPodFilterer) WatchRestakedBeaconChainETHWithdrawn(opts *bind.WatchOpts, sink chan<- *EigenPodRestakedBeaconChainETHWithdrawn, recipient []common.Address) (event.Subscription, error) { var recipientRule []interface{} for _, recipientItem := range recipient { recipientRule = append(recipientRule, recipientItem) } - logs, sub, err := _EigenPod.contract.WatchLogs(opts, "PartialWithdrawalRedeemed", recipientRule) + logs, sub, err := _EigenPod.contract.WatchLogs(opts, "RestakedBeaconChainETHWithdrawn", recipientRule) if err != nil { return nil, err } @@ -1766,8 +1896,8 @@ func (_EigenPod *EigenPodFilterer) WatchPartialWithdrawalRedeemed(opts *bind.Wat select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodPartialWithdrawalRedeemed) - if err := _EigenPod.contract.UnpackLog(event, "PartialWithdrawalRedeemed", log); err != nil { + event := new(EigenPodRestakedBeaconChainETHWithdrawn) + if err := _EigenPod.contract.UnpackLog(event, "RestakedBeaconChainETHWithdrawn", log); err != nil { return err } event.Raw = log @@ -1788,21 +1918,21 @@ func (_EigenPod *EigenPodFilterer) WatchPartialWithdrawalRedeemed(opts *bind.Wat }), nil } -// ParsePartialWithdrawalRedeemed is a log parse operation binding the contract event 0x8a7335714231dbd551aaba6314f4a97a14c201e53a3e25e1140325cdf67d7a4e. +// ParseRestakedBeaconChainETHWithdrawn is a log parse operation binding the contract event 0x8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e. // -// Solidity: event PartialWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 partialWithdrawalAmountGwei) -func (_EigenPod *EigenPodFilterer) ParsePartialWithdrawalRedeemed(log types.Log) (*EigenPodPartialWithdrawalRedeemed, error) { - event := new(EigenPodPartialWithdrawalRedeemed) - if err := _EigenPod.contract.UnpackLog(event, "PartialWithdrawalRedeemed", log); err != nil { +// Solidity: event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount) +func (_EigenPod *EigenPodFilterer) ParseRestakedBeaconChainETHWithdrawn(log types.Log) (*EigenPodRestakedBeaconChainETHWithdrawn, error) { + event := new(EigenPodRestakedBeaconChainETHWithdrawn) + if err := _EigenPod.contract.UnpackLog(event, "RestakedBeaconChainETHWithdrawn", log); err != nil { return nil, err } event.Raw = log return event, nil } -// EigenPodRestakedBeaconChainETHWithdrawnIterator is returned from FilterRestakedBeaconChainETHWithdrawn and is used to iterate over the raw logs and unpacked data for RestakedBeaconChainETHWithdrawn events raised by the EigenPod contract. -type EigenPodRestakedBeaconChainETHWithdrawnIterator struct { - Event *EigenPodRestakedBeaconChainETHWithdrawn // Event containing the contract specifics and raw log +// EigenPodValidatorBalanceUpdatedIterator is returned from FilterValidatorBalanceUpdated and is used to iterate over the raw logs and unpacked data for ValidatorBalanceUpdated events raised by the EigenPod contract. +type EigenPodValidatorBalanceUpdatedIterator struct { + Event *EigenPodValidatorBalanceUpdated // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1816,7 +1946,7 @@ type EigenPodRestakedBeaconChainETHWithdrawnIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodRestakedBeaconChainETHWithdrawnIterator) Next() bool { +func (it *EigenPodValidatorBalanceUpdatedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1825,7 +1955,7 @@ func (it *EigenPodRestakedBeaconChainETHWithdrawnIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodRestakedBeaconChainETHWithdrawn) + it.Event = new(EigenPodValidatorBalanceUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1840,7 +1970,7 @@ func (it *EigenPodRestakedBeaconChainETHWithdrawnIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodRestakedBeaconChainETHWithdrawn) + it.Event = new(EigenPodValidatorBalanceUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1856,52 +1986,43 @@ func (it *EigenPodRestakedBeaconChainETHWithdrawnIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodRestakedBeaconChainETHWithdrawnIterator) Error() error { +func (it *EigenPodValidatorBalanceUpdatedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodRestakedBeaconChainETHWithdrawnIterator) Close() error { +func (it *EigenPodValidatorBalanceUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodRestakedBeaconChainETHWithdrawn represents a RestakedBeaconChainETHWithdrawn event raised by the EigenPod contract. -type EigenPodRestakedBeaconChainETHWithdrawn struct { - Recipient common.Address - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos +// EigenPodValidatorBalanceUpdated represents a ValidatorBalanceUpdated event raised by the EigenPod contract. +type EigenPodValidatorBalanceUpdated struct { + ValidatorIndex *big.Int + BalanceTimestamp uint64 + NewValidatorBalanceGwei uint64 + Raw types.Log // Blockchain specific contextual infos } -// FilterRestakedBeaconChainETHWithdrawn is a free log retrieval operation binding the contract event 0x8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e. +// FilterValidatorBalanceUpdated is a free log retrieval operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. // -// Solidity: event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount) -func (_EigenPod *EigenPodFilterer) FilterRestakedBeaconChainETHWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*EigenPodRestakedBeaconChainETHWithdrawnIterator, error) { - - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) - } +// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) +func (_EigenPod *EigenPodFilterer) FilterValidatorBalanceUpdated(opts *bind.FilterOpts) (*EigenPodValidatorBalanceUpdatedIterator, error) { - logs, sub, err := _EigenPod.contract.FilterLogs(opts, "RestakedBeaconChainETHWithdrawn", recipientRule) + logs, sub, err := _EigenPod.contract.FilterLogs(opts, "ValidatorBalanceUpdated") if err != nil { return nil, err } - return &EigenPodRestakedBeaconChainETHWithdrawnIterator{contract: _EigenPod.contract, event: "RestakedBeaconChainETHWithdrawn", logs: logs, sub: sub}, nil + return &EigenPodValidatorBalanceUpdatedIterator{contract: _EigenPod.contract, event: "ValidatorBalanceUpdated", logs: logs, sub: sub}, nil } -// WatchRestakedBeaconChainETHWithdrawn is a free log subscription operation binding the contract event 0x8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e. +// WatchValidatorBalanceUpdated is a free log subscription operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. // -// Solidity: event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount) -func (_EigenPod *EigenPodFilterer) WatchRestakedBeaconChainETHWithdrawn(opts *bind.WatchOpts, sink chan<- *EigenPodRestakedBeaconChainETHWithdrawn, recipient []common.Address) (event.Subscription, error) { - - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) - } +// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) +func (_EigenPod *EigenPodFilterer) WatchValidatorBalanceUpdated(opts *bind.WatchOpts, sink chan<- *EigenPodValidatorBalanceUpdated) (event.Subscription, error) { - logs, sub, err := _EigenPod.contract.WatchLogs(opts, "RestakedBeaconChainETHWithdrawn", recipientRule) + logs, sub, err := _EigenPod.contract.WatchLogs(opts, "ValidatorBalanceUpdated") if err != nil { return nil, err } @@ -1911,8 +2032,8 @@ func (_EigenPod *EigenPodFilterer) WatchRestakedBeaconChainETHWithdrawn(opts *bi select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodRestakedBeaconChainETHWithdrawn) - if err := _EigenPod.contract.UnpackLog(event, "RestakedBeaconChainETHWithdrawn", log); err != nil { + event := new(EigenPodValidatorBalanceUpdated) + if err := _EigenPod.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { return err } event.Raw = log @@ -1933,21 +2054,21 @@ func (_EigenPod *EigenPodFilterer) WatchRestakedBeaconChainETHWithdrawn(opts *bi }), nil } -// ParseRestakedBeaconChainETHWithdrawn is a log parse operation binding the contract event 0x8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e. +// ParseValidatorBalanceUpdated is a log parse operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. // -// Solidity: event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount) -func (_EigenPod *EigenPodFilterer) ParseRestakedBeaconChainETHWithdrawn(log types.Log) (*EigenPodRestakedBeaconChainETHWithdrawn, error) { - event := new(EigenPodRestakedBeaconChainETHWithdrawn) - if err := _EigenPod.contract.UnpackLog(event, "RestakedBeaconChainETHWithdrawn", log); err != nil { +// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) +func (_EigenPod *EigenPodFilterer) ParseValidatorBalanceUpdated(log types.Log) (*EigenPodValidatorBalanceUpdated, error) { + event := new(EigenPodValidatorBalanceUpdated) + if err := _EigenPod.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -// EigenPodRestakingActivatedIterator is returned from FilterRestakingActivated and is used to iterate over the raw logs and unpacked data for RestakingActivated events raised by the EigenPod contract. -type EigenPodRestakingActivatedIterator struct { - Event *EigenPodRestakingActivated // Event containing the contract specifics and raw log +// EigenPodValidatorCheckpointedIterator is returned from FilterValidatorCheckpointed and is used to iterate over the raw logs and unpacked data for ValidatorCheckpointed events raised by the EigenPod contract. +type EigenPodValidatorCheckpointedIterator struct { + Event *EigenPodValidatorCheckpointed // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1961,7 +2082,7 @@ type EigenPodRestakingActivatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodRestakingActivatedIterator) Next() bool { +func (it *EigenPodValidatorCheckpointedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1970,7 +2091,7 @@ func (it *EigenPodRestakingActivatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodRestakingActivated) + it.Event = new(EigenPodValidatorCheckpointed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1985,7 +2106,7 @@ func (it *EigenPodRestakingActivatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodRestakingActivated) + it.Event = new(EigenPodValidatorCheckpointed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2001,51 +2122,60 @@ func (it *EigenPodRestakingActivatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodRestakingActivatedIterator) Error() error { +func (it *EigenPodValidatorCheckpointedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodRestakingActivatedIterator) Close() error { +func (it *EigenPodValidatorCheckpointedIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodRestakingActivated represents a RestakingActivated event raised by the EigenPod contract. -type EigenPodRestakingActivated struct { - PodOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// EigenPodValidatorCheckpointed represents a ValidatorCheckpointed event raised by the EigenPod contract. +type EigenPodValidatorCheckpointed struct { + CheckpointTimestamp uint64 + ValidatorIndex *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterRestakingActivated is a free log retrieval operation binding the contract event 0xca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd. +// FilterValidatorCheckpointed is a free log retrieval operation binding the contract event 0xa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f. // -// Solidity: event RestakingActivated(address indexed podOwner) -func (_EigenPod *EigenPodFilterer) FilterRestakingActivated(opts *bind.FilterOpts, podOwner []common.Address) (*EigenPodRestakingActivatedIterator, error) { +// Solidity: event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPod *EigenPodFilterer) FilterValidatorCheckpointed(opts *bind.FilterOpts, checkpointTimestamp []uint64, validatorIndex []*big.Int) (*EigenPodValidatorCheckpointedIterator, error) { - var podOwnerRule []interface{} - for _, podOwnerItem := range podOwner { - podOwnerRule = append(podOwnerRule, podOwnerItem) + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) } - logs, sub, err := _EigenPod.contract.FilterLogs(opts, "RestakingActivated", podOwnerRule) + logs, sub, err := _EigenPod.contract.FilterLogs(opts, "ValidatorCheckpointed", checkpointTimestampRule, validatorIndexRule) if err != nil { return nil, err } - return &EigenPodRestakingActivatedIterator{contract: _EigenPod.contract, event: "RestakingActivated", logs: logs, sub: sub}, nil + return &EigenPodValidatorCheckpointedIterator{contract: _EigenPod.contract, event: "ValidatorCheckpointed", logs: logs, sub: sub}, nil } -// WatchRestakingActivated is a free log subscription operation binding the contract event 0xca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd. +// WatchValidatorCheckpointed is a free log subscription operation binding the contract event 0xa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f. // -// Solidity: event RestakingActivated(address indexed podOwner) -func (_EigenPod *EigenPodFilterer) WatchRestakingActivated(opts *bind.WatchOpts, sink chan<- *EigenPodRestakingActivated, podOwner []common.Address) (event.Subscription, error) { +// Solidity: event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPod *EigenPodFilterer) WatchValidatorCheckpointed(opts *bind.WatchOpts, sink chan<- *EigenPodValidatorCheckpointed, checkpointTimestamp []uint64, validatorIndex []*big.Int) (event.Subscription, error) { - var podOwnerRule []interface{} - for _, podOwnerItem := range podOwner { - podOwnerRule = append(podOwnerRule, podOwnerItem) + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) } - logs, sub, err := _EigenPod.contract.WatchLogs(opts, "RestakingActivated", podOwnerRule) + logs, sub, err := _EigenPod.contract.WatchLogs(opts, "ValidatorCheckpointed", checkpointTimestampRule, validatorIndexRule) if err != nil { return nil, err } @@ -2055,8 +2185,8 @@ func (_EigenPod *EigenPodFilterer) WatchRestakingActivated(opts *bind.WatchOpts, select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodRestakingActivated) - if err := _EigenPod.contract.UnpackLog(event, "RestakingActivated", log); err != nil { + event := new(EigenPodValidatorCheckpointed) + if err := _EigenPod.contract.UnpackLog(event, "ValidatorCheckpointed", log); err != nil { return err } event.Raw = log @@ -2077,21 +2207,21 @@ func (_EigenPod *EigenPodFilterer) WatchRestakingActivated(opts *bind.WatchOpts, }), nil } -// ParseRestakingActivated is a log parse operation binding the contract event 0xca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd. +// ParseValidatorCheckpointed is a log parse operation binding the contract event 0xa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f. // -// Solidity: event RestakingActivated(address indexed podOwner) -func (_EigenPod *EigenPodFilterer) ParseRestakingActivated(log types.Log) (*EigenPodRestakingActivated, error) { - event := new(EigenPodRestakingActivated) - if err := _EigenPod.contract.UnpackLog(event, "RestakingActivated", log); err != nil { +// Solidity: event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPod *EigenPodFilterer) ParseValidatorCheckpointed(log types.Log) (*EigenPodValidatorCheckpointed, error) { + event := new(EigenPodValidatorCheckpointed) + if err := _EigenPod.contract.UnpackLog(event, "ValidatorCheckpointed", log); err != nil { return nil, err } event.Raw = log return event, nil } -// EigenPodValidatorBalanceUpdatedIterator is returned from FilterValidatorBalanceUpdated and is used to iterate over the raw logs and unpacked data for ValidatorBalanceUpdated events raised by the EigenPod contract. -type EigenPodValidatorBalanceUpdatedIterator struct { - Event *EigenPodValidatorBalanceUpdated // Event containing the contract specifics and raw log +// EigenPodValidatorRestakedIterator is returned from FilterValidatorRestaked and is used to iterate over the raw logs and unpacked data for ValidatorRestaked events raised by the EigenPod contract. +type EigenPodValidatorRestakedIterator struct { + Event *EigenPodValidatorRestaked // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2105,7 +2235,7 @@ type EigenPodValidatorBalanceUpdatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodValidatorBalanceUpdatedIterator) Next() bool { +func (it *EigenPodValidatorRestakedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2114,7 +2244,7 @@ func (it *EigenPodValidatorBalanceUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodValidatorBalanceUpdated) + it.Event = new(EigenPodValidatorRestaked) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2129,7 +2259,7 @@ func (it *EigenPodValidatorBalanceUpdatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodValidatorBalanceUpdated) + it.Event = new(EigenPodValidatorRestaked) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2145,43 +2275,41 @@ func (it *EigenPodValidatorBalanceUpdatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodValidatorBalanceUpdatedIterator) Error() error { +func (it *EigenPodValidatorRestakedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodValidatorBalanceUpdatedIterator) Close() error { +func (it *EigenPodValidatorRestakedIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodValidatorBalanceUpdated represents a ValidatorBalanceUpdated event raised by the EigenPod contract. -type EigenPodValidatorBalanceUpdated struct { - ValidatorIndex *big.Int - BalanceTimestamp uint64 - NewValidatorBalanceGwei uint64 - Raw types.Log // Blockchain specific contextual infos +// EigenPodValidatorRestaked represents a ValidatorRestaked event raised by the EigenPod contract. +type EigenPodValidatorRestaked struct { + ValidatorIndex *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterValidatorBalanceUpdated is a free log retrieval operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. +// FilterValidatorRestaked is a free log retrieval operation binding the contract event 0x2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449. // -// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) -func (_EigenPod *EigenPodFilterer) FilterValidatorBalanceUpdated(opts *bind.FilterOpts) (*EigenPodValidatorBalanceUpdatedIterator, error) { +// Solidity: event ValidatorRestaked(uint40 validatorIndex) +func (_EigenPod *EigenPodFilterer) FilterValidatorRestaked(opts *bind.FilterOpts) (*EigenPodValidatorRestakedIterator, error) { - logs, sub, err := _EigenPod.contract.FilterLogs(opts, "ValidatorBalanceUpdated") + logs, sub, err := _EigenPod.contract.FilterLogs(opts, "ValidatorRestaked") if err != nil { return nil, err } - return &EigenPodValidatorBalanceUpdatedIterator{contract: _EigenPod.contract, event: "ValidatorBalanceUpdated", logs: logs, sub: sub}, nil + return &EigenPodValidatorRestakedIterator{contract: _EigenPod.contract, event: "ValidatorRestaked", logs: logs, sub: sub}, nil } -// WatchValidatorBalanceUpdated is a free log subscription operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. +// WatchValidatorRestaked is a free log subscription operation binding the contract event 0x2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449. // -// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) -func (_EigenPod *EigenPodFilterer) WatchValidatorBalanceUpdated(opts *bind.WatchOpts, sink chan<- *EigenPodValidatorBalanceUpdated) (event.Subscription, error) { +// Solidity: event ValidatorRestaked(uint40 validatorIndex) +func (_EigenPod *EigenPodFilterer) WatchValidatorRestaked(opts *bind.WatchOpts, sink chan<- *EigenPodValidatorRestaked) (event.Subscription, error) { - logs, sub, err := _EigenPod.contract.WatchLogs(opts, "ValidatorBalanceUpdated") + logs, sub, err := _EigenPod.contract.WatchLogs(opts, "ValidatorRestaked") if err != nil { return nil, err } @@ -2191,8 +2319,8 @@ func (_EigenPod *EigenPodFilterer) WatchValidatorBalanceUpdated(opts *bind.Watch select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodValidatorBalanceUpdated) - if err := _EigenPod.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { + event := new(EigenPodValidatorRestaked) + if err := _EigenPod.contract.UnpackLog(event, "ValidatorRestaked", log); err != nil { return err } event.Raw = log @@ -2213,21 +2341,21 @@ func (_EigenPod *EigenPodFilterer) WatchValidatorBalanceUpdated(opts *bind.Watch }), nil } -// ParseValidatorBalanceUpdated is a log parse operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. +// ParseValidatorRestaked is a log parse operation binding the contract event 0x2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449. // -// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) -func (_EigenPod *EigenPodFilterer) ParseValidatorBalanceUpdated(log types.Log) (*EigenPodValidatorBalanceUpdated, error) { - event := new(EigenPodValidatorBalanceUpdated) - if err := _EigenPod.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { +// Solidity: event ValidatorRestaked(uint40 validatorIndex) +func (_EigenPod *EigenPodFilterer) ParseValidatorRestaked(log types.Log) (*EigenPodValidatorRestaked, error) { + event := new(EigenPodValidatorRestaked) + if err := _EigenPod.contract.UnpackLog(event, "ValidatorRestaked", log); err != nil { return nil, err } event.Raw = log return event, nil } -// EigenPodValidatorRestakedIterator is returned from FilterValidatorRestaked and is used to iterate over the raw logs and unpacked data for ValidatorRestaked events raised by the EigenPod contract. -type EigenPodValidatorRestakedIterator struct { - Event *EigenPodValidatorRestaked // Event containing the contract specifics and raw log +// EigenPodValidatorWithdrawnIterator is returned from FilterValidatorWithdrawn and is used to iterate over the raw logs and unpacked data for ValidatorWithdrawn events raised by the EigenPod contract. +type EigenPodValidatorWithdrawnIterator struct { + Event *EigenPodValidatorWithdrawn // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2241,7 +2369,7 @@ type EigenPodValidatorRestakedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodValidatorRestakedIterator) Next() bool { +func (it *EigenPodValidatorWithdrawnIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2250,7 +2378,7 @@ func (it *EigenPodValidatorRestakedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodValidatorRestaked) + it.Event = new(EigenPodValidatorWithdrawn) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2265,7 +2393,7 @@ func (it *EigenPodValidatorRestakedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodValidatorRestaked) + it.Event = new(EigenPodValidatorWithdrawn) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2281,41 +2409,60 @@ func (it *EigenPodValidatorRestakedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodValidatorRestakedIterator) Error() error { +func (it *EigenPodValidatorWithdrawnIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodValidatorRestakedIterator) Close() error { +func (it *EigenPodValidatorWithdrawnIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodValidatorRestaked represents a ValidatorRestaked event raised by the EigenPod contract. -type EigenPodValidatorRestaked struct { - ValidatorIndex *big.Int - Raw types.Log // Blockchain specific contextual infos +// EigenPodValidatorWithdrawn represents a ValidatorWithdrawn event raised by the EigenPod contract. +type EigenPodValidatorWithdrawn struct { + CheckpointTimestamp uint64 + ValidatorIndex *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterValidatorRestaked is a free log retrieval operation binding the contract event 0x2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449. +// FilterValidatorWithdrawn is a free log retrieval operation binding the contract event 0x2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a. // -// Solidity: event ValidatorRestaked(uint40 validatorIndex) -func (_EigenPod *EigenPodFilterer) FilterValidatorRestaked(opts *bind.FilterOpts) (*EigenPodValidatorRestakedIterator, error) { +// Solidity: event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPod *EigenPodFilterer) FilterValidatorWithdrawn(opts *bind.FilterOpts, checkpointTimestamp []uint64, validatorIndex []*big.Int) (*EigenPodValidatorWithdrawnIterator, error) { - logs, sub, err := _EigenPod.contract.FilterLogs(opts, "ValidatorRestaked") + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _EigenPod.contract.FilterLogs(opts, "ValidatorWithdrawn", checkpointTimestampRule, validatorIndexRule) if err != nil { return nil, err } - return &EigenPodValidatorRestakedIterator{contract: _EigenPod.contract, event: "ValidatorRestaked", logs: logs, sub: sub}, nil + return &EigenPodValidatorWithdrawnIterator{contract: _EigenPod.contract, event: "ValidatorWithdrawn", logs: logs, sub: sub}, nil } -// WatchValidatorRestaked is a free log subscription operation binding the contract event 0x2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449. +// WatchValidatorWithdrawn is a free log subscription operation binding the contract event 0x2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a. // -// Solidity: event ValidatorRestaked(uint40 validatorIndex) -func (_EigenPod *EigenPodFilterer) WatchValidatorRestaked(opts *bind.WatchOpts, sink chan<- *EigenPodValidatorRestaked) (event.Subscription, error) { +// Solidity: event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPod *EigenPodFilterer) WatchValidatorWithdrawn(opts *bind.WatchOpts, sink chan<- *EigenPodValidatorWithdrawn, checkpointTimestamp []uint64, validatorIndex []*big.Int) (event.Subscription, error) { - logs, sub, err := _EigenPod.contract.WatchLogs(opts, "ValidatorRestaked") + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _EigenPod.contract.WatchLogs(opts, "ValidatorWithdrawn", checkpointTimestampRule, validatorIndexRule) if err != nil { return nil, err } @@ -2325,8 +2472,8 @@ func (_EigenPod *EigenPodFilterer) WatchValidatorRestaked(opts *bind.WatchOpts, select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodValidatorRestaked) - if err := _EigenPod.contract.UnpackLog(event, "ValidatorRestaked", log); err != nil { + event := new(EigenPodValidatorWithdrawn) + if err := _EigenPod.contract.UnpackLog(event, "ValidatorWithdrawn", log); err != nil { return err } event.Raw = log @@ -2347,12 +2494,12 @@ func (_EigenPod *EigenPodFilterer) WatchValidatorRestaked(opts *bind.WatchOpts, }), nil } -// ParseValidatorRestaked is a log parse operation binding the contract event 0x2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449. +// ParseValidatorWithdrawn is a log parse operation binding the contract event 0x2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a. // -// Solidity: event ValidatorRestaked(uint40 validatorIndex) -func (_EigenPod *EigenPodFilterer) ParseValidatorRestaked(log types.Log) (*EigenPodValidatorRestaked, error) { - event := new(EigenPodValidatorRestaked) - if err := _EigenPod.contract.UnpackLog(event, "ValidatorRestaked", log); err != nil { +// Solidity: event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPod *EigenPodFilterer) ParseValidatorWithdrawn(log types.Log) (*EigenPodValidatorWithdrawn, error) { + event := new(EigenPodValidatorWithdrawn) + if err := _EigenPod.contract.UnpackLog(event, "ValidatorWithdrawn", log); err != nil { return nil, err } event.Raw = log diff --git a/pkg/bindings/EigenPodManager/binding.go b/pkg/bindings/EigenPodManager/binding.go index 28304bf6e..9b44ba82d 100644 --- a/pkg/bindings/EigenPodManager/binding.go +++ b/pkg/bindings/EigenPodManager/binding.go @@ -31,8 +31,8 @@ var ( // EigenPodManagerMetaData contains all meta data concerning the EigenPodManager contract. var EigenPodManagerMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_ethPOS\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"},{\"name\":\"_eigenPodBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_strategyManager\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"},{\"name\":\"_slasher\",\"type\":\"address\",\"internalType\":\"contractISlasher\"},{\"name\":\"_delegationManager\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"beaconChainOracle\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeaconChainOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createPod\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegationManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"denebForkTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBlockRootAtTimestamp\",\"inputs\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_beaconChainOracle\",\"type\":\"address\",\"internalType\":\"contractIBeaconChainOracle\"},{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"_initPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"numPods\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerToPod\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwnerShares\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recordBeaconChainETHBalanceUpdate\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setDenebForkTimestamp\",\"inputs\":[{\"name\":\"newDenebForkTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slasher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISlasher\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateBeaconChainOracle\",\"inputs\":[{\"name\":\"newBeaconChainOracle\",\"type\":\"address\",\"internalType\":\"contractIBeaconChainOracle\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSharesAsTokens\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destination\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"BeaconChainETHDeposited\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainETHWithdrawalCompleted\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"nonce\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"delegatedAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconOracleUpdated\",\"inputs\":[{\"name\":\"newOracleAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DenebForkTimestampUpdated\",\"inputs\":[{\"name\":\"newValue\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodDeployed\",\"inputs\":[{\"name\":\"eigenPod\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodSharesUpdated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", - Bin: "0x6101206040523480156200001257600080fd5b50604051620034e7380380620034e783398101604081905262000035916200014b565b6001600160a01b0380861660805280851660a05280841660c05280831660e0528116610100526200006562000070565b5050505050620001cb565b600054610100900460ff1615620000dd5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000130576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b03811681146200014857600080fd5b50565b600080600080600060a086880312156200016457600080fd5b8551620001718162000132565b6020870151909550620001848162000132565b6040870151909450620001978162000132565b6060870151909350620001aa8162000132565b6080870151909250620001bd8162000132565b809150509295509295909350565b60805160a05160c05160e051610100516132a66200024160003960008181610636015281816106e001528181610b0e015281816113e70152818161187c015261196c01526000610542015260006102e601526000818161027a01528181611366015261203a0152600061041401526132a66000f3fe6080604052600436106101ee5760003560e01c80638da5cb5b1161010d578063c052bd61116100a0578063d1c64cc91161006f578063d1c64cc914610604578063ea4d3c9b14610624578063f2fde38b14610658578063f6848d2414610678578063fabc1cbc146106b357600080fd5b8063c052bd6114610584578063c1de3aef146105a4578063c2c51c40146105c4578063cf756fdf146105e457600080fd5b8063a38406a3116100dc578063a38406a3146104fa578063a6a509be1461051a578063b134427114610530578063beffbb891461056457600080fd5b80638da5cb5b1461046b5780639104c319146104895780639b4e4634146104b15780639ba06275146104c457600080fd5b8063595c6a6711610185578063715018a611610154578063715018a6146103ed57806374cdd7981461040257806384d8106214610436578063886f11951461044b57600080fd5b8063595c6a67146103565780635ac86ab71461036b5780635c975abb146103ab57806360f4062b146103c057600080fd5b8063387b1300116101c1578063387b1300146102b457806339b70e38146102d457806344e71c8014610308578063463db0381461033657600080fd5b80630e81073c146101f357806310d67a2f14610226578063136439dd14610248578063292b7b2b14610268575b600080fd5b3480156101ff57600080fd5b5061021361020e366004612406565b6106d3565b6040519081526020015b60405180910390f35b34801561023257600080fd5b50610246610241366004612432565b610911565b005b34801561025457600080fd5b5061024661026336600461244f565b6109c4565b34801561027457600080fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161021d565b3480156102c057600080fd5b506102466102cf366004612468565b610b03565b3480156102e057600080fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561031457600080fd5b5061031d610ea1565b60405167ffffffffffffffff909116815260200161021d565b34801561034257600080fd5b506102466103513660046124a9565b610eca565b34801561036257600080fd5b50610246611056565b34801561037757600080fd5b5061039b6103863660046124d3565b606654600160ff9092169190911b9081161490565b604051901515815260200161021d565b3480156103b757600080fd5b50606654610213565b3480156103cc57600080fd5b506102136103db366004612432565b609b6020526000908152604090205481565b3480156103f957600080fd5b5061024661111d565b34801561040e57600080fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561044257600080fd5b5061029c611131565b34801561045757600080fd5b5060655461029c906001600160a01b031681565b34801561047757600080fd5b506033546001600160a01b031661029c565b34801561049557600080fd5b5061029c73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b6102466104bf36600461253f565b61121b565b3480156104d057600080fd5b5061029c6104df366004612432565b6098602052600090815260409020546001600160a01b031681565b34801561050657600080fd5b5061029c610515366004612432565b61130a565b34801561052657600080fd5b5061021360995481565b34801561053c57600080fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561057057600080fd5b5061024661057f366004612406565b6113dc565b34801561059057600080fd5b5060975461029c906001600160a01b031681565b3480156105b057600080fd5b506102466105bf366004612432565b6115f3565b3480156105d057600080fd5b506102466105df366004612406565b611604565b3480156105f057600080fd5b506102466105ff3660046125b3565b611a07565b34801561061057600080fd5b5061021361061f3660046124a9565b611b30565b34801561063057600080fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066457600080fd5b50610246610673366004612432565b611c3b565b34801561068457600080fd5b5061039b610693366004612432565b6001600160a01b0390811660009081526098602052604090205416151590565b3480156106bf57600080fd5b506102466106ce36600461244f565b611cb1565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107265760405162461bcd60e51b815260040161071d90612604565b60405180910390fd5b6001600160a01b0383166107a25760405162461bcd60e51b815260206004820152603a60248201527f456967656e506f644d616e616765722e6164645368617265733a20706f644f7760448201527f6e65722063616e6e6f74206265207a65726f2061646472657373000000000000606482015260840161071d565b60008212156108105760405162461bcd60e51b815260206004820152603460248201527f456967656e506f644d616e616765722e6164645368617265733a207368617265604482015273732063616e6e6f74206265206e6567617469766560601b606482015260840161071d565b61081e633b9aca0083612678565b156108915760405162461bcd60e51b815260206004820152603d60248201527f456967656e506f644d616e616765722e6164645368617265733a20736861726560448201527f73206d75737420626520612077686f6c65204777656920616d6f756e74000000606482015260840161071d565b6001600160a01b0383166000908152609b6020526040812054906108b584836126a2565b6001600160a01b0386166000818152609b6020526040908190208390555191925090600080516020613231833981519152906108f49087815260200190565b60405180910390a26109068282611e0d565b925050505b92915050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610964573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098891906126e3565b6001600160a01b0316336001600160a01b0316146109b85760405162461bcd60e51b815260040161071d90612700565b6109c181611e4f565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610a0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a30919061274a565b610a4c5760405162461bcd60e51b815260040161071d9061276c565b60665481811614610ac55760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c6974790000000000000000606482015260840161071d565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b4b5760405162461bcd60e51b815260040161071d90612604565b6001600160a01b038316610bc55760405162461bcd60e51b8152602060048201526047602482015260008051602061325183398151915260448201527f546f6b656e733a20706f644f776e65722063616e6e6f74206265207a65726f206064820152666164647265737360c81b608482015260a40161071d565b6001600160a01b038216610c425760405162461bcd60e51b815260206004820152604a602482015260008051602061325183398151915260448201527f546f6b656e733a2064657374696e6174696f6e2063616e6e6f74206265207a65606482015269726f206164647265737360b01b608482015260a40161071d565b6000811215610cb15760405162461bcd60e51b8152602060048201526041602482015260008051602061325183398151915260448201527f546f6b656e733a207368617265732063616e6e6f74206265206e6567617469766064820152606560f81b608482015260a40161071d565b610cbf633b9aca0082612678565b15610d335760405162461bcd60e51b815260206004820152604a602482015260008051602061325183398151915260448201527f546f6b656e733a20736861726573206d75737420626520612077686f6c6520476064820152691dd95a48185b5bdd5b9d60b21b608482015260a40161071d565b6001600160a01b0383166000908152609b602052604081205490811215610e26576000610d5f826127b4565b905080831115610dc4576001600160a01b0385166000908152609b6020526040812055610d8c81846127d1565b9250846001600160a01b031660008051602061323183398151915282604051610db791815260200190565b60405180910390a2610e24565b6001600160a01b0385166000908152609b602052604081208054859290610dec9084906126a2565b90915550506040518381526001600160a01b038616906000805160206132318339815191529060200160405180910390a25050505050565b505b6001600160a01b03848116600090815260986020526040908190205490516362483a2160e11b815285831660048201526024810185905291169063c490744290604401600060405180830381600087803b158015610e8357600080fd5b505af1158015610e97573d6000803e3d6000fd5b5050505050505050565b609c5460009067ffffffffffffffff1680610ec55767ffffffffffffffff91505090565b919050565b610ed2611f46565b67ffffffffffffffff8116610f645760405162461bcd60e51b815260206004820152604c60248201527f456967656e506f644d616e616765722e73657444656e6562466f726b54696d6560448201527f7374616d703a2063616e6e6f7420736574206e657744656e6562466f726b546960648201526b06d657374616d7020746f20360a41b608482015260a40161071d565b609c5467ffffffffffffffff16156110005760405162461bcd60e51b815260206004820152605360248201527f456967656e506f644d616e616765722e73657444656e6562466f726b54696d6560448201527f7374616d703a2063616e6e6f74207365742064656e6562466f726b54696d657360648201527274616d70206d6f7265207468616e206f6e636560681b608482015260a40161071d565b609c805467ffffffffffffffff191667ffffffffffffffff83169081179091556040519081527f19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db9060200160405180910390a150565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa15801561109e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c2919061274a565b6110de5760405162461bcd60e51b815260040161071d9061276c565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b611125611f46565b61112f6000611fa0565b565b6066546000908190600190811614156111885760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161071d565b336000908152609860205260409020546001600160a01b03161561120a5760405162461bcd60e51b815260206004820152603360248201527f456967656e506f644d616e616765722e637265617465506f643a2053656e64656044820152721c88185b1c9958591e481a185cc818481c1bd9606a1b606482015260840161071d565b6000611214611ff2565b9250505090565b606654600090600190811614156112705760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161071d565b336000908152609860205260409020546001600160a01b03168061129957611296611ff2565b90505b6040516326d3918d60e21b81526001600160a01b03821690639b4e46349034906112cf908b908b908b908b908b90600401612811565b6000604051808303818588803b1580156112e857600080fd5b505af11580156112fc573d6000803e3d6000fd5b505050505050505050505050565b6001600160a01b038082166000908152609860205260408120549091168061090b576113d5836001600160a01b031660001b60405180610940016040528061090e815260200161292361090e9139604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166020820152808201919091526000606082015260800160408051601f19818403018152908290526113ba9291602001612886565b60405160208183030381529060405280519060200120612157565b9392505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114245760405162461bcd60e51b815260040161071d90612604565b600081121561149b5760405162461bcd60e51b815260206004820152603760248201527f456967656e506f644d616e616765722e72656d6f76655368617265733a20736860448201527f617265732063616e6e6f74206265206e65676174697665000000000000000000606482015260840161071d565b6114a9633b9aca0082612678565b1561151e576040805162461bcd60e51b81526020600482015260248101919091527f456967656e506f644d616e616765722e72656d6f76655368617265733a20736860448201527f61726573206d75737420626520612077686f6c65204777656920616d6f756e74606482015260840161071d565b6001600160a01b0382166000908152609b602052604081205461154290839061289b565b905060008112156115d35760405162461bcd60e51b815260206004820152604f60248201527f456967656e506f644d616e616765722e72656d6f76655368617265733a20636160448201527f6e6e6f7420726573756c7420696e20706f64206f776e657220686176696e672060648201526e6e656761746976652073686172657360881b608482015260a40161071d565b6001600160a01b039092166000908152609b602052604090209190915550565b6115fb611f46565b6109c1816121b3565b6001600160a01b03808316600090815260986020526040902054839116331461167f5760405162461bcd60e51b815260206004820152602760248201527f456967656e506f644d616e616765722e6f6e6c79456967656e506f643a206e6f6044820152661d0818481c1bd960ca1b606482015260840161071d565b600260c95414156116d25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161071d565b600260c9556001600160a01b03831661176e5760405162461bcd60e51b815260206004820152605260248201527f456967656e506f644d616e616765722e7265636f7264426561636f6e4368616960448201527f6e45544842616c616e63655570646174653a20706f644f776e65722063616e6e6064820152716f74206265207a65726f206164647265737360701b608482015260a40161071d565b61177c633b9aca00836128da565b156118155760405162461bcd60e51b815260206004820152605a60248201527f456967656e506f644d616e616765722e7265636f7264426561636f6e4368616960448201527f6e45544842616c616e63655570646174653a2073686172657344656c7461206d60648201527f75737420626520612077686f6c65204777656920616d6f756e74000000000000608482015260a40161071d565b6001600160a01b0383166000908152609b60205260408120549061183984836126a2565b6001600160a01b0386166000908152609b602052604081208290559091506118618383611e0d565b905080156119c957600081121561192c576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663132d49678773beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06118c0856127b4565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561190f57600080fd5b505af1158015611923573d6000803e3d6000fd5b505050506119c9565b604051631452b9d760e11b81526001600160a01b03878116600483015273beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06024830152604482018390527f000000000000000000000000000000000000000000000000000000000000000016906328a573ae90606401600060405180830381600087803b1580156119b057600080fd5b505af11580156119c4573d6000803e3d6000fd5b505050505b856001600160a01b0316600080516020613231833981519152866040516119f291815260200190565b60405180910390a25050600160c95550505050565b600054610100900460ff1615808015611a275750600054600160ff909116105b80611a415750303b158015611a41575060005460ff166001145b611aa45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161071d565b6000805460ff191660011790558015611ac7576000805461ff0019166101001790555b611ad0856121b3565b611ad984611fa0565b611ae383836121fd565b8015611b29576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60975460405163321accf960e11b815267ffffffffffffffff8316600482015260009182916001600160a01b039091169063643599f290602401602060405180830381865afa158015611b87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bab91906128ee565b90508061090b5760405162461bcd60e51b815260206004820152605260248201527f456967656e506f644d616e616765722e676574426c6f636b526f6f744174546960448201527f6d657374616d703a20737461746520726f6f742061742074696d657374616d70606482015271081b9bdd081e595d08199a5b985b1a5e995960721b608482015260a40161071d565b611c43611f46565b6001600160a01b038116611ca85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161071d565b6109c181611fa0565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2891906126e3565b6001600160a01b0316336001600160a01b031614611d585760405162461bcd60e51b815260040161071d90612700565b606654198119606654191614611dd65760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c6974790000000000000000606482015260840161071d565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610af8565b6000808313611e2d5760008213611e265750600061090b565b508061090b565b60008213611e4557611e3e836127b4565b905061090b565b611e3e838361289b565b6001600160a01b038116611edd5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a40161071d565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b0316331461112f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161071d565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060996000815461200390612907565b9091555060408051610940810190915261090e8082526000916120a291839133916129236020830139604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166020820152808201919091526000606082015260800160408051601f198184030181529082905261208e9291602001612886565b6040516020818303038152906040526122e7565b60405163189acdbd60e31b81523360048201529091506001600160a01b0382169063c4d66de890602401600060405180830381600087803b1580156120e657600080fd5b505af11580156120fa573d6000803e3d6000fd5b50503360008181526098602052604080822080546001600160a01b0319166001600160a01b038816908117909155905192945092507f21c99d0db02213c32fff5b05cf0a718ab5f858802b91498f80d82270289d856a91a3919050565b604080516001600160f81b03196020808301919091526bffffffffffffffffffffffff193060601b16602183015260358201859052605580830185905283518084039091018152607590920190925280519101206000906113d5565b609780546001600160a01b0319166001600160a01b0383169081179091556040517f08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f690600090a250565b6065546001600160a01b031615801561221e57506001600160a01b03821615155b6122a05760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a40161071d565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26122e382611e4f565b5050565b6000808447101561233a5760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e6365000000604482015260640161071d565b82516123885760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f604482015260640161071d565b8383516020850187f590506001600160a01b0381166123e95760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f7900000000000000604482015260640161071d565b949350505050565b6001600160a01b03811681146109c157600080fd5b6000806040838503121561241957600080fd5b8235612424816123f1565b946020939093013593505050565b60006020828403121561244457600080fd5b81356113d5816123f1565b60006020828403121561246157600080fd5b5035919050565b60008060006060848603121561247d57600080fd5b8335612488816123f1565b92506020840135612498816123f1565b929592945050506040919091013590565b6000602082840312156124bb57600080fd5b813567ffffffffffffffff811681146113d557600080fd5b6000602082840312156124e557600080fd5b813560ff811681146113d557600080fd5b60008083601f84011261250857600080fd5b50813567ffffffffffffffff81111561252057600080fd5b60208301915083602082850101111561253857600080fd5b9250929050565b60008060008060006060868803121561255757600080fd5b853567ffffffffffffffff8082111561256f57600080fd5b61257b89838a016124f6565b9097509550602088013591508082111561259457600080fd5b506125a1888289016124f6565b96999598509660400135949350505050565b600080600080608085870312156125c957600080fd5b84356125d4816123f1565b935060208501356125e4816123f1565b925060408501356125f4816123f1565b9396929550929360600135925050565b602080825260409082018190527f456967656e506f644d616e616765722e6f6e6c7944656c65676174696f6e4d61908201527f6e616765723a206e6f74207468652044656c65676174696f6e4d616e61676572606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60008261268757612687612662565b500690565b634e487b7160e01b600052601160045260246000fd5b600080821280156001600160ff1b03849003851316156126c4576126c461268c565b600160ff1b83900384128116156126dd576126dd61268c565b50500190565b6000602082840312156126f557600080fd5b81516113d5816123f1565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60006020828403121561275c57600080fd5b815180151581146113d557600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b6000600160ff1b8214156127ca576127ca61268c565b5060000390565b6000828210156127e3576127e361268c565b500390565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060815260006128256060830187896127e8565b82810360208401526128388186886127e8565b9150508260408301529695505050505050565b6000815160005b8181101561286c5760208185018101518683015201612852565b8181111561287b576000828601525b509290920192915050565b60006123e9612895838661284b565b8461284b565b60008083128015600160ff1b8501841216156128b9576128b961268c565b6001600160ff1b03840183138116156128d4576128d461268c565b50500390565b6000826128e9576128e9612662565b500790565b60006020828403121561290057600080fd5b5051919050565b600060001982141561291b5761291b61268c565b506001019056fe608060405260405161090e38038061090e83398101604081905261002291610460565b61002e82826000610035565b505061058a565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610520565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610520565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108e7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe919061053b565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c65782516103bf576001600160a01b0385163b6103bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d0565b6103d083836103d8565b949350505050565b8151156103e85781518083602001fd5b8060405162461bcd60e51b81526004016101699190610557565b80516001600160a01b038116811461041957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044f578181015183820152602001610437565b838111156100f95750506000910152565b6000806040838503121561047357600080fd5b61047c83610402565b60208401519092506001600160401b038082111561049957600080fd5b818501915085601f8301126104ad57600080fd5b8151818111156104bf576104bf61041e565b604051601f8201601f19908116603f011681019083821181831017156104e7576104e761041e565b8160405282815288602084870101111561050057600080fd5b610511836020830160208801610434565b80955050505050509250929050565b60006020828403121561053257600080fd5b6102c882610402565b6000825161054d818460208701610434565b9190910192915050565b6020815260008251806020840152610576816040850160208701610434565b601f01601f19169190910160400192915050565b61034e806105996000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102f260279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb9190610249565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b03168560405161014191906102a2565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020d578251610206576001600160a01b0385163b6102065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610217565b610217838361021f565b949350505050565b81511561022f5781518083602001fd5b8060405162461bcd60e51b81526004016101fd91906102be565b60006020828403121561025b57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028d578181015183820152602001610275565b8381111561029c576000848401525b50505050565b600082516102b4818460208701610272565b9190910192915050565b60208152600082518060208401526102dd816040850160208701610272565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d51e81d3bc5ed20a26aeb05dce7e825c503b2061aa78628027300c8d65b9d89a64736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c65644e2b791dedccd9fb30141b088cabf5c14a8912b52f59375c95c010700b8c6193456967656e506f644d616e616765722e77697468647261775368617265734173a264697066735822122004788f8dd07899132ea5c1e14eaf911cee4bc9c2c0086e0b752d9b98d2a1d56864736f6c634300080c0033", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_ethPOS\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"},{\"name\":\"_eigenPodBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_strategyManager\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"},{\"name\":\"_slasher\",\"type\":\"address\",\"internalType\":\"contractISlasher\"},{\"name\":\"_delegationManager\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createPod\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegationManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"_initPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"numPods\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerToPod\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwnerShares\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recordBeaconChainETHBalanceUpdate\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slasher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISlasher\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSharesAsTokens\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destination\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"BeaconChainETHDeposited\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainETHWithdrawalCompleted\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"nonce\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"delegatedAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NewTotalShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newTotalShares\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodDeployed\",\"inputs\":[{\"name\":\"eigenPod\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodSharesUpdated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + Bin: "0x6101206040523480156200001257600080fd5b50604051620031693803806200316983398101604081905262000035916200014b565b6001600160a01b0380861660805280851660a05280841660c05280831660e0528116610100526200006562000070565b5050505050620001cb565b600054610100900460ff1615620000dd5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000130576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b03811681146200014857600080fd5b50565b600080600080600060a086880312156200016457600080fd5b8551620001718162000132565b6020870151909550620001848162000132565b6040870151909450620001978162000132565b6060870151909350620001aa8162000132565b6080870151909250620001bd8162000132565b809150509295509295909350565b60805160a05160c05160e05161010051612f286200024160003960008181610551015281816105fb01528181610b7901528181611313015281816117bf01526118af015260006104dd015260006102cf015260008181610263015281816112920152611e64015260006103af0152612f286000f3fe6080604052600436106101b75760003560e01c8063886f1195116100ec578063b13442711161008a578063ea4d3c9b11610064578063ea4d3c9b1461053f578063f2fde38b14610573578063f6848d2414610593578063fabc1cbc146105ce57600080fd5b8063b1344271146104cb578063beffbb89146104ff578063c2c51c401461051f57600080fd5b80639b4e4634116100c65780639b4e46341461044c5780639ba062751461045f578063a38406a314610495578063a6a509be146104b557600080fd5b8063886f1195146103e65780638da5cb5b146104065780639104c3191461042457600080fd5b8063595c6a671161015957806360f4062b1161013357806360f4062b1461035b578063715018a61461038857806374cdd7981461039d57806384d81062146103d157600080fd5b8063595c6a67146102f15780635ac86ab7146103065780635c975abb1461034657600080fd5b80631794bb3c116101955780631794bb3c14610231578063292b7b2b14610251578063387b13001461029d57806339b70e38146102bd57600080fd5b80630e81073c146101bc57806310d67a2f146101ef578063136439dd14610211575b600080fd5b3480156101c857600080fd5b506101dc6101d73660046120fc565b6105ee565b6040519081526020015b60405180910390f35b3480156101fb57600080fd5b5061020f61020a366004612128565b61085d565b005b34801561021d57600080fd5b5061020f61022c366004612145565b610910565b34801561023d57600080fd5b5061020f61024c36600461215e565b610a4f565b34801561025d57600080fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101e6565b3480156102a957600080fd5b5061020f6102b836600461215e565b610b6e565b3480156102c957600080fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b3480156102fd57600080fd5b5061020f610f82565b34801561031257600080fd5b5061033661032136600461219f565b606654600160ff9092169190911b9081161490565b60405190151581526020016101e6565b34801561035257600080fd5b506066546101dc565b34801561036757600080fd5b506101dc610376366004612128565b609b6020526000908152604090205481565b34801561039457600080fd5b5061020f611049565b3480156103a957600080fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b3480156103dd57600080fd5b5061028561105d565b3480156103f257600080fd5b50606554610285906001600160a01b031681565b34801561041257600080fd5b506033546001600160a01b0316610285565b34801561043057600080fd5b5061028573beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b61020f61045a36600461220b565b611147565b34801561046b57600080fd5b5061028561047a366004612128565b6098602052600090815260409020546001600160a01b031681565b3480156104a157600080fd5b506102856104b0366004612128565b611236565b3480156104c157600080fd5b506101dc60995481565b3480156104d757600080fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b34801561050b57600080fd5b5061020f61051a3660046120fc565b611308565b34801561052b57600080fd5b5061020f61053a3660046120fc565b611547565b34801561054b57600080fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b34801561057f57600080fd5b5061020f61058e366004612128565b61197b565b34801561059f57600080fd5b506103366105ae366004612128565b6001600160a01b0390811660009081526098602052604090205416151590565b3480156105da57600080fd5b5061020f6105e9366004612145565b6119f1565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106415760405162461bcd60e51b81526004016106389061227f565b60405180910390fd5b6001600160a01b0383166106bd5760405162461bcd60e51b815260206004820152603a60248201527f456967656e506f644d616e616765722e6164645368617265733a20706f644f7760448201527f6e65722063616e6e6f74206265207a65726f20616464726573730000000000006064820152608401610638565b600082121561072b5760405162461bcd60e51b815260206004820152603460248201527f456967656e506f644d616e616765722e6164645368617265733a207368617265604482015273732063616e6e6f74206265206e6567617469766560601b6064820152608401610638565b610739633b9aca00836122f3565b156107ac5760405162461bcd60e51b815260206004820152603d60248201527f456967656e506f644d616e616765722e6164645368617265733a20736861726560448201527f73206d75737420626520612077686f6c65204777656920616d6f756e740000006064820152608401610638565b6001600160a01b0383166000908152609b6020526040812054906107d0848361231d565b6001600160a01b0386166000818152609b6020526040908190208390555191925090600080516020612eb38339815191529061080f9087815260200190565b60405180910390a2846001600160a01b03166000805160206125858339815191528260405161084091815260200190565b60405180910390a26108528282611b4d565b925050505b92915050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d4919061235e565b6001600160a01b0316336001600160a01b0316146109045760405162461bcd60e51b81526004016106389061237b565b61090d81611b8f565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610958573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097c91906123c5565b6109985760405162461bcd60e51b8152600401610638906123e7565b60665481811614610a115760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610638565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b600054610100900460ff1615808015610a6f5750600054600160ff909116105b80610a895750303b158015610a89575060005460ff166001145b610aec5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610638565b6000805460ff191660011790558015610b0f576000805461ff0019166101001790555b610b1884611c86565b610b228383611cd8565b8015610b68576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610bb65760405162461bcd60e51b81526004016106389061227f565b6001600160a01b038316610c305760405162461bcd60e51b81526020600482015260476024820152600080516020612ed383398151915260448201527f546f6b656e733a20706f644f776e65722063616e6e6f74206265207a65726f206064820152666164647265737360c81b608482015260a401610638565b6001600160a01b038216610cad5760405162461bcd60e51b815260206004820152604a6024820152600080516020612ed383398151915260448201527f546f6b656e733a2064657374696e6174696f6e2063616e6e6f74206265207a65606482015269726f206164647265737360b01b608482015260a401610638565b6000811215610d1c5760405162461bcd60e51b81526020600482015260416024820152600080516020612ed383398151915260448201527f546f6b656e733a207368617265732063616e6e6f74206265206e6567617469766064820152606560f81b608482015260a401610638565b610d2a633b9aca00826122f3565b15610d9e5760405162461bcd60e51b815260206004820152604a6024820152600080516020612ed383398151915260448201527f546f6b656e733a20736861726573206d75737420626520612077686f6c6520476064820152691dd95a48185b5bdd5b9d60b21b608482015260a401610638565b6001600160a01b0383166000908152609b602052604081205490811215610f07576000610dca8261242f565b905080831115610e61576001600160a01b0385166000908152609b6020526040812055610df7818461244c565b9250846001600160a01b0316600080516020612eb383398151915282604051610e2291815260200190565b60405180910390a2846001600160a01b03166000805160206125858339815191526000604051610e5491815260200190565b60405180910390a2610f05565b6001600160a01b0385166000908152609b6020526040812054610e8590859061231d565b6001600160a01b0387166000818152609b6020526040908190208390555191925090600080516020612eb383398151915290610ec49087815260200190565b60405180910390a2856001600160a01b031660008051602061258583398151915282604051610ef591815260200190565b60405180910390a2505050505050565b505b6001600160a01b03848116600090815260986020526040908190205490516362483a2160e11b815285831660048201526024810185905291169063c490744290604401600060405180830381600087803b158015610f6457600080fd5b505af1158015610f78573d6000803e3d6000fd5b5050505050505050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fee91906123c5565b61100a5760405162461bcd60e51b8152600401610638906123e7565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b611051611dc2565b61105b6000611c86565b565b6066546000908190600190811614156110b45760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610638565b336000908152609860205260409020546001600160a01b0316156111365760405162461bcd60e51b815260206004820152603360248201527f456967656e506f644d616e616765722e637265617465506f643a2053656e64656044820152721c88185b1c9958591e481a185cc818481c1bd9606a1b6064820152608401610638565b6000611140611e1c565b9250505090565b6066546000906001908116141561119c5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610638565b336000908152609860205260409020546001600160a01b0316806111c5576111c2611e1c565b90505b6040516326d3918d60e21b81526001600160a01b03821690639b4e46349034906111fb908b908b908b908b908b9060040161248c565b6000604051808303818588803b15801561121457600080fd5b505af1158015611228573d6000803e3d6000fd5b505050505050505050505050565b6001600160a01b038082166000908152609860205260408120549091168061085757611301836001600160a01b031660001b60405180610940016040528061090e81526020016125a561090e9139604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166020820152808201919091526000606082015260800160408051601f19818403018152908290526112e69291602001612501565b60405160208183030381529060405280519060200120611f81565b9392505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113505760405162461bcd60e51b81526004016106389061227f565b60008112156113c75760405162461bcd60e51b815260206004820152603760248201527f456967656e506f644d616e616765722e72656d6f76655368617265733a20736860448201527f617265732063616e6e6f74206265206e656761746976650000000000000000006064820152608401610638565b6113d5633b9aca00826122f3565b1561144a576040805162461bcd60e51b81526020600482015260248101919091527f456967656e506f644d616e616765722e72656d6f76655368617265733a20736860448201527f61726573206d75737420626520612077686f6c65204777656920616d6f756e746064820152608401610638565b6001600160a01b0382166000908152609b602052604081205461146e908390612516565b905060008112156114ff5760405162461bcd60e51b815260206004820152604f60248201527f456967656e506f644d616e616765722e72656d6f76655368617265733a20636160448201527f6e6e6f7420726573756c7420696e20706f64206f776e657220686176696e672060648201526e6e656761746976652073686172657360881b608482015260a401610638565b6001600160a01b0383166000818152609b602052604090819020839055516000805160206125858339815191529061153a9084815260200190565b60405180910390a2505050565b6001600160a01b0380831660009081526098602052604090205483911633146115c25760405162461bcd60e51b815260206004820152602760248201527f456967656e506f644d616e616765722e6f6e6c79456967656e506f643a206e6f6044820152661d0818481c1bd960ca1b6064820152608401610638565b600260c95414156116155760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610638565b600260c9556001600160a01b0383166116b15760405162461bcd60e51b815260206004820152605260248201527f456967656e506f644d616e616765722e7265636f7264426561636f6e4368616960448201527f6e45544842616c616e63655570646174653a20706f644f776e65722063616e6e6064820152716f74206265207a65726f206164647265737360701b608482015260a401610638565b6116bf633b9aca0083612555565b156117585760405162461bcd60e51b815260206004820152605a60248201527f456967656e506f644d616e616765722e7265636f7264426561636f6e4368616960448201527f6e45544842616c616e63655570646174653a2073686172657344656c7461206d60648201527f75737420626520612077686f6c65204777656920616d6f756e74000000000000608482015260a401610638565b6001600160a01b0383166000908152609b60205260408120549061177c848361231d565b6001600160a01b0386166000908152609b602052604081208290559091506117a48383611b4d565b9050801561190c57600081121561186f576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663132d49678773beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06118038561242f565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561185257600080fd5b505af1158015611866573d6000803e3d6000fd5b5050505061190c565b604051631452b9d760e11b81526001600160a01b03878116600483015273beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06024830152604482018390527f000000000000000000000000000000000000000000000000000000000000000016906328a573ae90606401600060405180830381600087803b1580156118f357600080fd5b505af1158015611907573d6000803e3d6000fd5b505050505b856001600160a01b0316600080516020612eb38339815191528660405161193591815260200190565b60405180910390a2856001600160a01b03166000805160206125858339815191528360405161196691815260200190565b60405180910390a25050600160c95550505050565b611983611dc2565b6001600160a01b0381166119e85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610638565b61090d81611c86565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a68919061235e565b6001600160a01b0316336001600160a01b031614611a985760405162461bcd60e51b81526004016106389061237b565b606654198119606654191614611b165760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610638565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610a44565b6000808313611b6d5760008213611b6657506000610857565b5080610857565b60008213611b8557611b7e8361242f565b9050610857565b611b7e8383612516565b6001600160a01b038116611c1d5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610638565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6065546001600160a01b0316158015611cf957506001600160a01b03821615155b611d7b5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610638565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2611dbe82611b8f565b5050565b6033546001600160a01b0316331461105b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610638565b6000609960008154611e2d90612569565b9091555060408051610940810190915261090e808252600091611ecc91839133916125a56020830139604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166020820152808201919091526000606082015260800160408051601f1981840301815290829052611eb89291602001612501565b604051602081830303815290604052611fdd565b60405163189acdbd60e31b81523360048201529091506001600160a01b0382169063c4d66de890602401600060405180830381600087803b158015611f1057600080fd5b505af1158015611f24573d6000803e3d6000fd5b50503360008181526098602052604080822080546001600160a01b0319166001600160a01b038816908117909155905192945092507f21c99d0db02213c32fff5b05cf0a718ab5f858802b91498f80d82270289d856a91a3919050565b604080516001600160f81b03196020808301919091526bffffffffffffffffffffffff193060601b1660218301526035820185905260558083018590528351808403909101815260759092019092528051910120600090611301565b600080844710156120305760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610638565b825161207e5760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610638565b8383516020850187f590506001600160a01b0381166120df5760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610638565b949350505050565b6001600160a01b038116811461090d57600080fd5b6000806040838503121561210f57600080fd5b823561211a816120e7565b946020939093013593505050565b60006020828403121561213a57600080fd5b8135611301816120e7565b60006020828403121561215757600080fd5b5035919050565b60008060006060848603121561217357600080fd5b833561217e816120e7565b9250602084013561218e816120e7565b929592945050506040919091013590565b6000602082840312156121b157600080fd5b813560ff8116811461130157600080fd5b60008083601f8401126121d457600080fd5b50813567ffffffffffffffff8111156121ec57600080fd5b60208301915083602082850101111561220457600080fd5b9250929050565b60008060008060006060868803121561222357600080fd5b853567ffffffffffffffff8082111561223b57600080fd5b61224789838a016121c2565b9097509550602088013591508082111561226057600080fd5b5061226d888289016121c2565b96999598509660400135949350505050565b602080825260409082018190527f456967656e506f644d616e616765722e6f6e6c7944656c65676174696f6e4d61908201527f6e616765723a206e6f74207468652044656c65676174696f6e4d616e61676572606082015260800190565b634e487b7160e01b600052601260045260246000fd5b600082612302576123026122dd565b500690565b634e487b7160e01b600052601160045260246000fd5b600080821280156001600160ff1b038490038513161561233f5761233f612307565b600160ff1b839003841281161561235857612358612307565b50500190565b60006020828403121561237057600080fd5b8151611301816120e7565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b6000602082840312156123d757600080fd5b8151801515811461130157600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b6000600160ff1b82141561244557612445612307565b5060000390565b60008282101561245e5761245e612307565b500390565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060815260006124a0606083018789612463565b82810360208401526124b3818688612463565b9150508260408301529695505050505050565b6000815160005b818110156124e757602081850181015186830152016124cd565b818111156124f6576000828601525b509290920192915050565b60006120df61251083866124c6565b846124c6565b60008083128015600160ff1b85018412161561253457612534612307565b6001600160ff1b038401831381161561254f5761254f612307565b50500390565b600082612564576125646122dd565b500790565b600060001982141561257d5761257d612307565b506001019056fed4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098608060405260405161090e38038061090e83398101604081905261002291610460565b61002e82826000610035565b505061058a565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610520565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610520565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108e7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe919061053b565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c65782516103bf576001600160a01b0385163b6103bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d0565b6103d083836103d8565b949350505050565b8151156103e85781518083602001fd5b8060405162461bcd60e51b81526004016101699190610557565b80516001600160a01b038116811461041957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044f578181015183820152602001610437565b838111156100f95750506000910152565b6000806040838503121561047357600080fd5b61047c83610402565b60208401519092506001600160401b038082111561049957600080fd5b818501915085601f8301126104ad57600080fd5b8151818111156104bf576104bf61041e565b604051601f8201601f19908116603f011681019083821181831017156104e7576104e761041e565b8160405282815288602084870101111561050057600080fd5b610511836020830160208801610434565b80955050505050509250929050565b60006020828403121561053257600080fd5b6102c882610402565b6000825161054d818460208701610434565b9190910192915050565b6020815260008251806020840152610576816040850160208701610434565b601f01601f19169190910160400192915050565b61034e806105996000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102f260279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb9190610249565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b03168560405161014191906102a2565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020d578251610206576001600160a01b0385163b6102065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610217565b610217838361021f565b949350505050565b81511561022f5781518083602001fd5b8060405162461bcd60e51b81526004016101fd91906102be565b60006020828403121561025b57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028d578181015183820152602001610275565b8381111561029c576000848401525b50505050565b600082516102b4818460208701610272565b9190910192915050565b60208152600082518060208401526102dd816040850160208701610272565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d51e81d3bc5ed20a26aeb05dce7e825c503b2061aa78628027300c8d65b9d89a64736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c65644e2b791dedccd9fb30141b088cabf5c14a8912b52f59375c95c010700b8c6193456967656e506f644d616e616765722e77697468647261775368617265734173a264697066735822122069d3a03119733341cd267e296785e37b1c350fc350d796fc97aa45c1e8213da664736f6c634300080c0033", } // EigenPodManagerABI is the input ABI used to generate the binding from. @@ -233,37 +233,6 @@ func (_EigenPodManager *EigenPodManagerCallerSession) BeaconChainETHStrategy() ( return _EigenPodManager.Contract.BeaconChainETHStrategy(&_EigenPodManager.CallOpts) } -// BeaconChainOracle is a free data retrieval call binding the contract method 0xc052bd61. -// -// Solidity: function beaconChainOracle() view returns(address) -func (_EigenPodManager *EigenPodManagerCaller) BeaconChainOracle(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _EigenPodManager.contract.Call(opts, &out, "beaconChainOracle") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// BeaconChainOracle is a free data retrieval call binding the contract method 0xc052bd61. -// -// Solidity: function beaconChainOracle() view returns(address) -func (_EigenPodManager *EigenPodManagerSession) BeaconChainOracle() (common.Address, error) { - return _EigenPodManager.Contract.BeaconChainOracle(&_EigenPodManager.CallOpts) -} - -// BeaconChainOracle is a free data retrieval call binding the contract method 0xc052bd61. -// -// Solidity: function beaconChainOracle() view returns(address) -func (_EigenPodManager *EigenPodManagerCallerSession) BeaconChainOracle() (common.Address, error) { - return _EigenPodManager.Contract.BeaconChainOracle(&_EigenPodManager.CallOpts) -} - // DelegationManager is a free data retrieval call binding the contract method 0xea4d3c9b. // // Solidity: function delegationManager() view returns(address) @@ -295,37 +264,6 @@ func (_EigenPodManager *EigenPodManagerCallerSession) DelegationManager() (commo return _EigenPodManager.Contract.DelegationManager(&_EigenPodManager.CallOpts) } -// DenebForkTimestamp is a free data retrieval call binding the contract method 0x44e71c80. -// -// Solidity: function denebForkTimestamp() view returns(uint64) -func (_EigenPodManager *EigenPodManagerCaller) DenebForkTimestamp(opts *bind.CallOpts) (uint64, error) { - var out []interface{} - err := _EigenPodManager.contract.Call(opts, &out, "denebForkTimestamp") - - if err != nil { - return *new(uint64), err - } - - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) - - return out0, err - -} - -// DenebForkTimestamp is a free data retrieval call binding the contract method 0x44e71c80. -// -// Solidity: function denebForkTimestamp() view returns(uint64) -func (_EigenPodManager *EigenPodManagerSession) DenebForkTimestamp() (uint64, error) { - return _EigenPodManager.Contract.DenebForkTimestamp(&_EigenPodManager.CallOpts) -} - -// DenebForkTimestamp is a free data retrieval call binding the contract method 0x44e71c80. -// -// Solidity: function denebForkTimestamp() view returns(uint64) -func (_EigenPodManager *EigenPodManagerCallerSession) DenebForkTimestamp() (uint64, error) { - return _EigenPodManager.Contract.DenebForkTimestamp(&_EigenPodManager.CallOpts) -} - // EigenPodBeacon is a free data retrieval call binding the contract method 0x292b7b2b. // // Solidity: function eigenPodBeacon() view returns(address) @@ -388,37 +326,6 @@ func (_EigenPodManager *EigenPodManagerCallerSession) EthPOS() (common.Address, return _EigenPodManager.Contract.EthPOS(&_EigenPodManager.CallOpts) } -// GetBlockRootAtTimestamp is a free data retrieval call binding the contract method 0xd1c64cc9. -// -// Solidity: function getBlockRootAtTimestamp(uint64 timestamp) view returns(bytes32) -func (_EigenPodManager *EigenPodManagerCaller) GetBlockRootAtTimestamp(opts *bind.CallOpts, timestamp uint64) ([32]byte, error) { - var out []interface{} - err := _EigenPodManager.contract.Call(opts, &out, "getBlockRootAtTimestamp", timestamp) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// GetBlockRootAtTimestamp is a free data retrieval call binding the contract method 0xd1c64cc9. -// -// Solidity: function getBlockRootAtTimestamp(uint64 timestamp) view returns(bytes32) -func (_EigenPodManager *EigenPodManagerSession) GetBlockRootAtTimestamp(timestamp uint64) ([32]byte, error) { - return _EigenPodManager.Contract.GetBlockRootAtTimestamp(&_EigenPodManager.CallOpts, timestamp) -} - -// GetBlockRootAtTimestamp is a free data retrieval call binding the contract method 0xd1c64cc9. -// -// Solidity: function getBlockRootAtTimestamp(uint64 timestamp) view returns(bytes32) -func (_EigenPodManager *EigenPodManagerCallerSession) GetBlockRootAtTimestamp(timestamp uint64) ([32]byte, error) { - return _EigenPodManager.Contract.GetBlockRootAtTimestamp(&_EigenPodManager.CallOpts, timestamp) -} - // GetPod is a free data retrieval call binding the contract method 0xa38406a3. // // Solidity: function getPod(address podOwner) view returns(address) @@ -802,25 +709,25 @@ func (_EigenPodManager *EigenPodManagerTransactorSession) CreatePod() (*types.Tr return _EigenPodManager.Contract.CreatePod(&_EigenPodManager.TransactOpts) } -// Initialize is a paid mutator transaction binding the contract method 0xcf756fdf. +// Initialize is a paid mutator transaction binding the contract method 0x1794bb3c. // -// Solidity: function initialize(address _beaconChainOracle, address initialOwner, address _pauserRegistry, uint256 _initPausedStatus) returns() -func (_EigenPodManager *EigenPodManagerTransactor) Initialize(opts *bind.TransactOpts, _beaconChainOracle common.Address, initialOwner common.Address, _pauserRegistry common.Address, _initPausedStatus *big.Int) (*types.Transaction, error) { - return _EigenPodManager.contract.Transact(opts, "initialize", _beaconChainOracle, initialOwner, _pauserRegistry, _initPausedStatus) +// Solidity: function initialize(address initialOwner, address _pauserRegistry, uint256 _initPausedStatus) returns() +func (_EigenPodManager *EigenPodManagerTransactor) Initialize(opts *bind.TransactOpts, initialOwner common.Address, _pauserRegistry common.Address, _initPausedStatus *big.Int) (*types.Transaction, error) { + return _EigenPodManager.contract.Transact(opts, "initialize", initialOwner, _pauserRegistry, _initPausedStatus) } -// Initialize is a paid mutator transaction binding the contract method 0xcf756fdf. +// Initialize is a paid mutator transaction binding the contract method 0x1794bb3c. // -// Solidity: function initialize(address _beaconChainOracle, address initialOwner, address _pauserRegistry, uint256 _initPausedStatus) returns() -func (_EigenPodManager *EigenPodManagerSession) Initialize(_beaconChainOracle common.Address, initialOwner common.Address, _pauserRegistry common.Address, _initPausedStatus *big.Int) (*types.Transaction, error) { - return _EigenPodManager.Contract.Initialize(&_EigenPodManager.TransactOpts, _beaconChainOracle, initialOwner, _pauserRegistry, _initPausedStatus) +// Solidity: function initialize(address initialOwner, address _pauserRegistry, uint256 _initPausedStatus) returns() +func (_EigenPodManager *EigenPodManagerSession) Initialize(initialOwner common.Address, _pauserRegistry common.Address, _initPausedStatus *big.Int) (*types.Transaction, error) { + return _EigenPodManager.Contract.Initialize(&_EigenPodManager.TransactOpts, initialOwner, _pauserRegistry, _initPausedStatus) } -// Initialize is a paid mutator transaction binding the contract method 0xcf756fdf. +// Initialize is a paid mutator transaction binding the contract method 0x1794bb3c. // -// Solidity: function initialize(address _beaconChainOracle, address initialOwner, address _pauserRegistry, uint256 _initPausedStatus) returns() -func (_EigenPodManager *EigenPodManagerTransactorSession) Initialize(_beaconChainOracle common.Address, initialOwner common.Address, _pauserRegistry common.Address, _initPausedStatus *big.Int) (*types.Transaction, error) { - return _EigenPodManager.Contract.Initialize(&_EigenPodManager.TransactOpts, _beaconChainOracle, initialOwner, _pauserRegistry, _initPausedStatus) +// Solidity: function initialize(address initialOwner, address _pauserRegistry, uint256 _initPausedStatus) returns() +func (_EigenPodManager *EigenPodManagerTransactorSession) Initialize(initialOwner common.Address, _pauserRegistry common.Address, _initPausedStatus *big.Int) (*types.Transaction, error) { + return _EigenPodManager.Contract.Initialize(&_EigenPodManager.TransactOpts, initialOwner, _pauserRegistry, _initPausedStatus) } // Pause is a paid mutator transaction binding the contract method 0x136439dd. @@ -928,27 +835,6 @@ func (_EigenPodManager *EigenPodManagerTransactorSession) RenounceOwnership() (* return _EigenPodManager.Contract.RenounceOwnership(&_EigenPodManager.TransactOpts) } -// SetDenebForkTimestamp is a paid mutator transaction binding the contract method 0x463db038. -// -// Solidity: function setDenebForkTimestamp(uint64 newDenebForkTimestamp) returns() -func (_EigenPodManager *EigenPodManagerTransactor) SetDenebForkTimestamp(opts *bind.TransactOpts, newDenebForkTimestamp uint64) (*types.Transaction, error) { - return _EigenPodManager.contract.Transact(opts, "setDenebForkTimestamp", newDenebForkTimestamp) -} - -// SetDenebForkTimestamp is a paid mutator transaction binding the contract method 0x463db038. -// -// Solidity: function setDenebForkTimestamp(uint64 newDenebForkTimestamp) returns() -func (_EigenPodManager *EigenPodManagerSession) SetDenebForkTimestamp(newDenebForkTimestamp uint64) (*types.Transaction, error) { - return _EigenPodManager.Contract.SetDenebForkTimestamp(&_EigenPodManager.TransactOpts, newDenebForkTimestamp) -} - -// SetDenebForkTimestamp is a paid mutator transaction binding the contract method 0x463db038. -// -// Solidity: function setDenebForkTimestamp(uint64 newDenebForkTimestamp) returns() -func (_EigenPodManager *EigenPodManagerTransactorSession) SetDenebForkTimestamp(newDenebForkTimestamp uint64) (*types.Transaction, error) { - return _EigenPodManager.Contract.SetDenebForkTimestamp(&_EigenPodManager.TransactOpts, newDenebForkTimestamp) -} - // SetPauserRegistry is a paid mutator transaction binding the contract method 0x10d67a2f. // // Solidity: function setPauserRegistry(address newPauserRegistry) returns() @@ -1033,27 +919,6 @@ func (_EigenPodManager *EigenPodManagerTransactorSession) Unpause(newPausedStatu return _EigenPodManager.Contract.Unpause(&_EigenPodManager.TransactOpts, newPausedStatus) } -// UpdateBeaconChainOracle is a paid mutator transaction binding the contract method 0xc1de3aef. -// -// Solidity: function updateBeaconChainOracle(address newBeaconChainOracle) returns() -func (_EigenPodManager *EigenPodManagerTransactor) UpdateBeaconChainOracle(opts *bind.TransactOpts, newBeaconChainOracle common.Address) (*types.Transaction, error) { - return _EigenPodManager.contract.Transact(opts, "updateBeaconChainOracle", newBeaconChainOracle) -} - -// UpdateBeaconChainOracle is a paid mutator transaction binding the contract method 0xc1de3aef. -// -// Solidity: function updateBeaconChainOracle(address newBeaconChainOracle) returns() -func (_EigenPodManager *EigenPodManagerSession) UpdateBeaconChainOracle(newBeaconChainOracle common.Address) (*types.Transaction, error) { - return _EigenPodManager.Contract.UpdateBeaconChainOracle(&_EigenPodManager.TransactOpts, newBeaconChainOracle) -} - -// UpdateBeaconChainOracle is a paid mutator transaction binding the contract method 0xc1de3aef. -// -// Solidity: function updateBeaconChainOracle(address newBeaconChainOracle) returns() -func (_EigenPodManager *EigenPodManagerTransactorSession) UpdateBeaconChainOracle(newBeaconChainOracle common.Address) (*types.Transaction, error) { - return _EigenPodManager.Contract.UpdateBeaconChainOracle(&_EigenPodManager.TransactOpts, newBeaconChainOracle) -} - // WithdrawSharesAsTokens is a paid mutator transaction binding the contract method 0x387b1300. // // Solidity: function withdrawSharesAsTokens(address podOwner, address destination, uint256 shares) returns() @@ -1369,9 +1234,9 @@ func (_EigenPodManager *EigenPodManagerFilterer) ParseBeaconChainETHWithdrawalCo return event, nil } -// EigenPodManagerBeaconOracleUpdatedIterator is returned from FilterBeaconOracleUpdated and is used to iterate over the raw logs and unpacked data for BeaconOracleUpdated events raised by the EigenPodManager contract. -type EigenPodManagerBeaconOracleUpdatedIterator struct { - Event *EigenPodManagerBeaconOracleUpdated // Event containing the contract specifics and raw log +// EigenPodManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the EigenPodManager contract. +type EigenPodManagerInitializedIterator struct { + Event *EigenPodManagerInitialized // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1385,7 +1250,7 @@ type EigenPodManagerBeaconOracleUpdatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodManagerBeaconOracleUpdatedIterator) Next() bool { +func (it *EigenPodManagerInitializedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1394,7 +1259,7 @@ func (it *EigenPodManagerBeaconOracleUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodManagerBeaconOracleUpdated) + it.Event = new(EigenPodManagerInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1409,7 +1274,7 @@ func (it *EigenPodManagerBeaconOracleUpdatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodManagerBeaconOracleUpdated) + it.Event = new(EigenPodManagerInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1425,51 +1290,41 @@ func (it *EigenPodManagerBeaconOracleUpdatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodManagerBeaconOracleUpdatedIterator) Error() error { +func (it *EigenPodManagerInitializedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodManagerBeaconOracleUpdatedIterator) Close() error { +func (it *EigenPodManagerInitializedIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodManagerBeaconOracleUpdated represents a BeaconOracleUpdated event raised by the EigenPodManager contract. -type EigenPodManagerBeaconOracleUpdated struct { - NewOracleAddress common.Address - Raw types.Log // Blockchain specific contextual infos +// EigenPodManagerInitialized represents a Initialized event raised by the EigenPodManager contract. +type EigenPodManagerInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// FilterBeaconOracleUpdated is a free log retrieval operation binding the contract event 0x08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f6. +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event BeaconOracleUpdated(address indexed newOracleAddress) -func (_EigenPodManager *EigenPodManagerFilterer) FilterBeaconOracleUpdated(opts *bind.FilterOpts, newOracleAddress []common.Address) (*EigenPodManagerBeaconOracleUpdatedIterator, error) { - - var newOracleAddressRule []interface{} - for _, newOracleAddressItem := range newOracleAddress { - newOracleAddressRule = append(newOracleAddressRule, newOracleAddressItem) - } +// Solidity: event Initialized(uint8 version) +func (_EigenPodManager *EigenPodManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*EigenPodManagerInitializedIterator, error) { - logs, sub, err := _EigenPodManager.contract.FilterLogs(opts, "BeaconOracleUpdated", newOracleAddressRule) + logs, sub, err := _EigenPodManager.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &EigenPodManagerBeaconOracleUpdatedIterator{contract: _EigenPodManager.contract, event: "BeaconOracleUpdated", logs: logs, sub: sub}, nil + return &EigenPodManagerInitializedIterator{contract: _EigenPodManager.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// WatchBeaconOracleUpdated is a free log subscription operation binding the contract event 0x08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f6. +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event BeaconOracleUpdated(address indexed newOracleAddress) -func (_EigenPodManager *EigenPodManagerFilterer) WatchBeaconOracleUpdated(opts *bind.WatchOpts, sink chan<- *EigenPodManagerBeaconOracleUpdated, newOracleAddress []common.Address) (event.Subscription, error) { - - var newOracleAddressRule []interface{} - for _, newOracleAddressItem := range newOracleAddress { - newOracleAddressRule = append(newOracleAddressRule, newOracleAddressItem) - } +// Solidity: event Initialized(uint8 version) +func (_EigenPodManager *EigenPodManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *EigenPodManagerInitialized) (event.Subscription, error) { - logs, sub, err := _EigenPodManager.contract.WatchLogs(opts, "BeaconOracleUpdated", newOracleAddressRule) + logs, sub, err := _EigenPodManager.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } @@ -1479,8 +1334,8 @@ func (_EigenPodManager *EigenPodManagerFilterer) WatchBeaconOracleUpdated(opts * select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodManagerBeaconOracleUpdated) - if err := _EigenPodManager.contract.UnpackLog(event, "BeaconOracleUpdated", log); err != nil { + event := new(EigenPodManagerInitialized) + if err := _EigenPodManager.contract.UnpackLog(event, "Initialized", log); err != nil { return err } event.Raw = log @@ -1501,21 +1356,21 @@ func (_EigenPodManager *EigenPodManagerFilterer) WatchBeaconOracleUpdated(opts * }), nil } -// ParseBeaconOracleUpdated is a log parse operation binding the contract event 0x08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f6. +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event BeaconOracleUpdated(address indexed newOracleAddress) -func (_EigenPodManager *EigenPodManagerFilterer) ParseBeaconOracleUpdated(log types.Log) (*EigenPodManagerBeaconOracleUpdated, error) { - event := new(EigenPodManagerBeaconOracleUpdated) - if err := _EigenPodManager.contract.UnpackLog(event, "BeaconOracleUpdated", log); err != nil { +// Solidity: event Initialized(uint8 version) +func (_EigenPodManager *EigenPodManagerFilterer) ParseInitialized(log types.Log) (*EigenPodManagerInitialized, error) { + event := new(EigenPodManagerInitialized) + if err := _EigenPodManager.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } event.Raw = log return event, nil } -// EigenPodManagerDenebForkTimestampUpdatedIterator is returned from FilterDenebForkTimestampUpdated and is used to iterate over the raw logs and unpacked data for DenebForkTimestampUpdated events raised by the EigenPodManager contract. -type EigenPodManagerDenebForkTimestampUpdatedIterator struct { - Event *EigenPodManagerDenebForkTimestampUpdated // Event containing the contract specifics and raw log +// EigenPodManagerNewTotalSharesIterator is returned from FilterNewTotalShares and is used to iterate over the raw logs and unpacked data for NewTotalShares events raised by the EigenPodManager contract. +type EigenPodManagerNewTotalSharesIterator struct { + Event *EigenPodManagerNewTotalShares // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1529,7 +1384,7 @@ type EigenPodManagerDenebForkTimestampUpdatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodManagerDenebForkTimestampUpdatedIterator) Next() bool { +func (it *EigenPodManagerNewTotalSharesIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1538,7 +1393,7 @@ func (it *EigenPodManagerDenebForkTimestampUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodManagerDenebForkTimestampUpdated) + it.Event = new(EigenPodManagerNewTotalShares) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1553,7 +1408,7 @@ func (it *EigenPodManagerDenebForkTimestampUpdatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodManagerDenebForkTimestampUpdated) + it.Event = new(EigenPodManagerNewTotalShares) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1569,175 +1424,52 @@ func (it *EigenPodManagerDenebForkTimestampUpdatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodManagerDenebForkTimestampUpdatedIterator) Error() error { +func (it *EigenPodManagerNewTotalSharesIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodManagerDenebForkTimestampUpdatedIterator) Close() error { +func (it *EigenPodManagerNewTotalSharesIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodManagerDenebForkTimestampUpdated represents a DenebForkTimestampUpdated event raised by the EigenPodManager contract. -type EigenPodManagerDenebForkTimestampUpdated struct { - NewValue uint64 - Raw types.Log // Blockchain specific contextual infos +// EigenPodManagerNewTotalShares represents a NewTotalShares event raised by the EigenPodManager contract. +type EigenPodManagerNewTotalShares struct { + PodOwner common.Address + NewTotalShares *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterDenebForkTimestampUpdated is a free log retrieval operation binding the contract event 0x19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db. +// FilterNewTotalShares is a free log retrieval operation binding the contract event 0xd4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098. // -// Solidity: event DenebForkTimestampUpdated(uint64 newValue) -func (_EigenPodManager *EigenPodManagerFilterer) FilterDenebForkTimestampUpdated(opts *bind.FilterOpts) (*EigenPodManagerDenebForkTimestampUpdatedIterator, error) { +// Solidity: event NewTotalShares(address indexed podOwner, int256 newTotalShares) +func (_EigenPodManager *EigenPodManagerFilterer) FilterNewTotalShares(opts *bind.FilterOpts, podOwner []common.Address) (*EigenPodManagerNewTotalSharesIterator, error) { - logs, sub, err := _EigenPodManager.contract.FilterLogs(opts, "DenebForkTimestampUpdated") - if err != nil { - return nil, err + var podOwnerRule []interface{} + for _, podOwnerItem := range podOwner { + podOwnerRule = append(podOwnerRule, podOwnerItem) } - return &EigenPodManagerDenebForkTimestampUpdatedIterator{contract: _EigenPodManager.contract, event: "DenebForkTimestampUpdated", logs: logs, sub: sub}, nil -} - -// WatchDenebForkTimestampUpdated is a free log subscription operation binding the contract event 0x19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db. -// -// Solidity: event DenebForkTimestampUpdated(uint64 newValue) -func (_EigenPodManager *EigenPodManagerFilterer) WatchDenebForkTimestampUpdated(opts *bind.WatchOpts, sink chan<- *EigenPodManagerDenebForkTimestampUpdated) (event.Subscription, error) { - logs, sub, err := _EigenPodManager.contract.WatchLogs(opts, "DenebForkTimestampUpdated") + logs, sub, err := _EigenPodManager.contract.FilterLogs(opts, "NewTotalShares", podOwnerRule) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(EigenPodManagerDenebForkTimestampUpdated) - if err := _EigenPodManager.contract.UnpackLog(event, "DenebForkTimestampUpdated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseDenebForkTimestampUpdated is a log parse operation binding the contract event 0x19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db. -// -// Solidity: event DenebForkTimestampUpdated(uint64 newValue) -func (_EigenPodManager *EigenPodManagerFilterer) ParseDenebForkTimestampUpdated(log types.Log) (*EigenPodManagerDenebForkTimestampUpdated, error) { - event := new(EigenPodManagerDenebForkTimestampUpdated) - if err := _EigenPodManager.contract.UnpackLog(event, "DenebForkTimestampUpdated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// EigenPodManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the EigenPodManager contract. -type EigenPodManagerInitializedIterator struct { - Event *EigenPodManagerInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *EigenPodManagerInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(EigenPodManagerInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(EigenPodManagerInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodManagerInitializedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *EigenPodManagerInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil + return &EigenPodManagerNewTotalSharesIterator{contract: _EigenPodManager.contract, event: "NewTotalShares", logs: logs, sub: sub}, nil } -// EigenPodManagerInitialized represents a Initialized event raised by the EigenPodManager contract. -type EigenPodManagerInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchNewTotalShares is a free log subscription operation binding the contract event 0xd4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098. // -// Solidity: event Initialized(uint8 version) -func (_EigenPodManager *EigenPodManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*EigenPodManagerInitializedIterator, error) { +// Solidity: event NewTotalShares(address indexed podOwner, int256 newTotalShares) +func (_EigenPodManager *EigenPodManagerFilterer) WatchNewTotalShares(opts *bind.WatchOpts, sink chan<- *EigenPodManagerNewTotalShares, podOwner []common.Address) (event.Subscription, error) { - logs, sub, err := _EigenPodManager.contract.FilterLogs(opts, "Initialized") - if err != nil { - return nil, err + var podOwnerRule []interface{} + for _, podOwnerItem := range podOwner { + podOwnerRule = append(podOwnerRule, podOwnerItem) } - return &EigenPodManagerInitializedIterator{contract: _EigenPodManager.contract, event: "Initialized", logs: logs, sub: sub}, nil -} - -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_EigenPodManager *EigenPodManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *EigenPodManagerInitialized) (event.Subscription, error) { - logs, sub, err := _EigenPodManager.contract.WatchLogs(opts, "Initialized") + logs, sub, err := _EigenPodManager.contract.WatchLogs(opts, "NewTotalShares", podOwnerRule) if err != nil { return nil, err } @@ -1747,8 +1479,8 @@ func (_EigenPodManager *EigenPodManagerFilterer) WatchInitialized(opts *bind.Wat select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodManagerInitialized) - if err := _EigenPodManager.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(EigenPodManagerNewTotalShares) + if err := _EigenPodManager.contract.UnpackLog(event, "NewTotalShares", log); err != nil { return err } event.Raw = log @@ -1769,12 +1501,12 @@ func (_EigenPodManager *EigenPodManagerFilterer) WatchInitialized(opts *bind.Wat }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseNewTotalShares is a log parse operation binding the contract event 0xd4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098. // -// Solidity: event Initialized(uint8 version) -func (_EigenPodManager *EigenPodManagerFilterer) ParseInitialized(log types.Log) (*EigenPodManagerInitialized, error) { - event := new(EigenPodManagerInitialized) - if err := _EigenPodManager.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event NewTotalShares(address indexed podOwner, int256 newTotalShares) +func (_EigenPodManager *EigenPodManagerFilterer) ParseNewTotalShares(log types.Log) (*EigenPodManagerNewTotalShares, error) { + event := new(EigenPodManagerNewTotalShares) + if err := _EigenPodManager.contract.UnpackLog(event, "NewTotalShares", log); err != nil { return nil, err } event.Raw = log diff --git a/pkg/bindings/EigenPodManagerStorage/binding.go b/pkg/bindings/EigenPodManagerStorage/binding.go index 928919851..446bf1a74 100644 --- a/pkg/bindings/EigenPodManagerStorage/binding.go +++ b/pkg/bindings/EigenPodManagerStorage/binding.go @@ -31,7 +31,7 @@ var ( // EigenPodManagerStorageMetaData contains all meta data concerning the EigenPodManagerStorage contract. var EigenPodManagerStorageMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"function\",\"name\":\"addShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"beaconChainOracle\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeaconChainOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createPod\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegationManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"denebForkTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBlockRootAtTimestamp\",\"inputs\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"numPods\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerToPod\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwnerShares\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recordBeaconChainETHBalanceUpdate\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setDenebForkTimestamp\",\"inputs\":[{\"name\":\"newDenebForkTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slasher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISlasher\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateBeaconChainOracle\",\"inputs\":[{\"name\":\"newBeaconChainOracle\",\"type\":\"address\",\"internalType\":\"contractIBeaconChainOracle\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSharesAsTokens\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destination\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"BeaconChainETHDeposited\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainETHWithdrawalCompleted\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"nonce\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"delegatedAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconOracleUpdated\",\"inputs\":[{\"name\":\"newOracleAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DenebForkTimestampUpdated\",\"inputs\":[{\"name\":\"newValue\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodDeployed\",\"inputs\":[{\"name\":\"eigenPod\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodSharesUpdated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + ABI: "[{\"type\":\"function\",\"name\":\"addShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createPod\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegationManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"numPods\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerToPod\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwnerShares\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recordBeaconChainETHBalanceUpdate\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slasher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISlasher\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSharesAsTokens\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destination\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"BeaconChainETHDeposited\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainETHWithdrawalCompleted\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"nonce\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"delegatedAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NewTotalShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newTotalShares\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodDeployed\",\"inputs\":[{\"name\":\"eigenPod\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodSharesUpdated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", } // EigenPodManagerStorageABI is the input ABI used to generate the binding from. @@ -211,37 +211,6 @@ func (_EigenPodManagerStorage *EigenPodManagerStorageCallerSession) BeaconChainE return _EigenPodManagerStorage.Contract.BeaconChainETHStrategy(&_EigenPodManagerStorage.CallOpts) } -// BeaconChainOracle is a free data retrieval call binding the contract method 0xc052bd61. -// -// Solidity: function beaconChainOracle() view returns(address) -func (_EigenPodManagerStorage *EigenPodManagerStorageCaller) BeaconChainOracle(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _EigenPodManagerStorage.contract.Call(opts, &out, "beaconChainOracle") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// BeaconChainOracle is a free data retrieval call binding the contract method 0xc052bd61. -// -// Solidity: function beaconChainOracle() view returns(address) -func (_EigenPodManagerStorage *EigenPodManagerStorageSession) BeaconChainOracle() (common.Address, error) { - return _EigenPodManagerStorage.Contract.BeaconChainOracle(&_EigenPodManagerStorage.CallOpts) -} - -// BeaconChainOracle is a free data retrieval call binding the contract method 0xc052bd61. -// -// Solidity: function beaconChainOracle() view returns(address) -func (_EigenPodManagerStorage *EigenPodManagerStorageCallerSession) BeaconChainOracle() (common.Address, error) { - return _EigenPodManagerStorage.Contract.BeaconChainOracle(&_EigenPodManagerStorage.CallOpts) -} - // DelegationManager is a free data retrieval call binding the contract method 0xea4d3c9b. // // Solidity: function delegationManager() view returns(address) @@ -273,37 +242,6 @@ func (_EigenPodManagerStorage *EigenPodManagerStorageCallerSession) DelegationMa return _EigenPodManagerStorage.Contract.DelegationManager(&_EigenPodManagerStorage.CallOpts) } -// DenebForkTimestamp is a free data retrieval call binding the contract method 0x44e71c80. -// -// Solidity: function denebForkTimestamp() view returns(uint64) -func (_EigenPodManagerStorage *EigenPodManagerStorageCaller) DenebForkTimestamp(opts *bind.CallOpts) (uint64, error) { - var out []interface{} - err := _EigenPodManagerStorage.contract.Call(opts, &out, "denebForkTimestamp") - - if err != nil { - return *new(uint64), err - } - - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) - - return out0, err - -} - -// DenebForkTimestamp is a free data retrieval call binding the contract method 0x44e71c80. -// -// Solidity: function denebForkTimestamp() view returns(uint64) -func (_EigenPodManagerStorage *EigenPodManagerStorageSession) DenebForkTimestamp() (uint64, error) { - return _EigenPodManagerStorage.Contract.DenebForkTimestamp(&_EigenPodManagerStorage.CallOpts) -} - -// DenebForkTimestamp is a free data retrieval call binding the contract method 0x44e71c80. -// -// Solidity: function denebForkTimestamp() view returns(uint64) -func (_EigenPodManagerStorage *EigenPodManagerStorageCallerSession) DenebForkTimestamp() (uint64, error) { - return _EigenPodManagerStorage.Contract.DenebForkTimestamp(&_EigenPodManagerStorage.CallOpts) -} - // EigenPodBeacon is a free data retrieval call binding the contract method 0x292b7b2b. // // Solidity: function eigenPodBeacon() view returns(address) @@ -366,37 +304,6 @@ func (_EigenPodManagerStorage *EigenPodManagerStorageCallerSession) EthPOS() (co return _EigenPodManagerStorage.Contract.EthPOS(&_EigenPodManagerStorage.CallOpts) } -// GetBlockRootAtTimestamp is a free data retrieval call binding the contract method 0xd1c64cc9. -// -// Solidity: function getBlockRootAtTimestamp(uint64 timestamp) view returns(bytes32) -func (_EigenPodManagerStorage *EigenPodManagerStorageCaller) GetBlockRootAtTimestamp(opts *bind.CallOpts, timestamp uint64) ([32]byte, error) { - var out []interface{} - err := _EigenPodManagerStorage.contract.Call(opts, &out, "getBlockRootAtTimestamp", timestamp) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// GetBlockRootAtTimestamp is a free data retrieval call binding the contract method 0xd1c64cc9. -// -// Solidity: function getBlockRootAtTimestamp(uint64 timestamp) view returns(bytes32) -func (_EigenPodManagerStorage *EigenPodManagerStorageSession) GetBlockRootAtTimestamp(timestamp uint64) ([32]byte, error) { - return _EigenPodManagerStorage.Contract.GetBlockRootAtTimestamp(&_EigenPodManagerStorage.CallOpts, timestamp) -} - -// GetBlockRootAtTimestamp is a free data retrieval call binding the contract method 0xd1c64cc9. -// -// Solidity: function getBlockRootAtTimestamp(uint64 timestamp) view returns(bytes32) -func (_EigenPodManagerStorage *EigenPodManagerStorageCallerSession) GetBlockRootAtTimestamp(timestamp uint64) ([32]byte, error) { - return _EigenPodManagerStorage.Contract.GetBlockRootAtTimestamp(&_EigenPodManagerStorage.CallOpts, timestamp) -} - // GetPod is a free data retrieval call binding the contract method 0xa38406a3. // // Solidity: function getPod(address podOwner) view returns(address) @@ -833,27 +740,6 @@ func (_EigenPodManagerStorage *EigenPodManagerStorageTransactorSession) RemoveSh return _EigenPodManagerStorage.Contract.RemoveShares(&_EigenPodManagerStorage.TransactOpts, podOwner, shares) } -// SetDenebForkTimestamp is a paid mutator transaction binding the contract method 0x463db038. -// -// Solidity: function setDenebForkTimestamp(uint64 newDenebForkTimestamp) returns() -func (_EigenPodManagerStorage *EigenPodManagerStorageTransactor) SetDenebForkTimestamp(opts *bind.TransactOpts, newDenebForkTimestamp uint64) (*types.Transaction, error) { - return _EigenPodManagerStorage.contract.Transact(opts, "setDenebForkTimestamp", newDenebForkTimestamp) -} - -// SetDenebForkTimestamp is a paid mutator transaction binding the contract method 0x463db038. -// -// Solidity: function setDenebForkTimestamp(uint64 newDenebForkTimestamp) returns() -func (_EigenPodManagerStorage *EigenPodManagerStorageSession) SetDenebForkTimestamp(newDenebForkTimestamp uint64) (*types.Transaction, error) { - return _EigenPodManagerStorage.Contract.SetDenebForkTimestamp(&_EigenPodManagerStorage.TransactOpts, newDenebForkTimestamp) -} - -// SetDenebForkTimestamp is a paid mutator transaction binding the contract method 0x463db038. -// -// Solidity: function setDenebForkTimestamp(uint64 newDenebForkTimestamp) returns() -func (_EigenPodManagerStorage *EigenPodManagerStorageTransactorSession) SetDenebForkTimestamp(newDenebForkTimestamp uint64) (*types.Transaction, error) { - return _EigenPodManagerStorage.Contract.SetDenebForkTimestamp(&_EigenPodManagerStorage.TransactOpts, newDenebForkTimestamp) -} - // SetPauserRegistry is a paid mutator transaction binding the contract method 0x10d67a2f. // // Solidity: function setPauserRegistry(address newPauserRegistry) returns() @@ -917,27 +803,6 @@ func (_EigenPodManagerStorage *EigenPodManagerStorageTransactorSession) Unpause( return _EigenPodManagerStorage.Contract.Unpause(&_EigenPodManagerStorage.TransactOpts, newPausedStatus) } -// UpdateBeaconChainOracle is a paid mutator transaction binding the contract method 0xc1de3aef. -// -// Solidity: function updateBeaconChainOracle(address newBeaconChainOracle) returns() -func (_EigenPodManagerStorage *EigenPodManagerStorageTransactor) UpdateBeaconChainOracle(opts *bind.TransactOpts, newBeaconChainOracle common.Address) (*types.Transaction, error) { - return _EigenPodManagerStorage.contract.Transact(opts, "updateBeaconChainOracle", newBeaconChainOracle) -} - -// UpdateBeaconChainOracle is a paid mutator transaction binding the contract method 0xc1de3aef. -// -// Solidity: function updateBeaconChainOracle(address newBeaconChainOracle) returns() -func (_EigenPodManagerStorage *EigenPodManagerStorageSession) UpdateBeaconChainOracle(newBeaconChainOracle common.Address) (*types.Transaction, error) { - return _EigenPodManagerStorage.Contract.UpdateBeaconChainOracle(&_EigenPodManagerStorage.TransactOpts, newBeaconChainOracle) -} - -// UpdateBeaconChainOracle is a paid mutator transaction binding the contract method 0xc1de3aef. -// -// Solidity: function updateBeaconChainOracle(address newBeaconChainOracle) returns() -func (_EigenPodManagerStorage *EigenPodManagerStorageTransactorSession) UpdateBeaconChainOracle(newBeaconChainOracle common.Address) (*types.Transaction, error) { - return _EigenPodManagerStorage.Contract.UpdateBeaconChainOracle(&_EigenPodManagerStorage.TransactOpts, newBeaconChainOracle) -} - // WithdrawSharesAsTokens is a paid mutator transaction binding the contract method 0x387b1300. // // Solidity: function withdrawSharesAsTokens(address podOwner, address destination, uint256 shares) returns() @@ -1253,9 +1118,9 @@ func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) ParseBeaconChainE return event, nil } -// EigenPodManagerStorageBeaconOracleUpdatedIterator is returned from FilterBeaconOracleUpdated and is used to iterate over the raw logs and unpacked data for BeaconOracleUpdated events raised by the EigenPodManagerStorage contract. -type EigenPodManagerStorageBeaconOracleUpdatedIterator struct { - Event *EigenPodManagerStorageBeaconOracleUpdated // Event containing the contract specifics and raw log +// EigenPodManagerStorageNewTotalSharesIterator is returned from FilterNewTotalShares and is used to iterate over the raw logs and unpacked data for NewTotalShares events raised by the EigenPodManagerStorage contract. +type EigenPodManagerStorageNewTotalSharesIterator struct { + Event *EigenPodManagerStorageNewTotalShares // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1269,7 +1134,7 @@ type EigenPodManagerStorageBeaconOracleUpdatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *EigenPodManagerStorageBeaconOracleUpdatedIterator) Next() bool { +func (it *EigenPodManagerStorageNewTotalSharesIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1278,7 +1143,7 @@ func (it *EigenPodManagerStorageBeaconOracleUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EigenPodManagerStorageBeaconOracleUpdated) + it.Event = new(EigenPodManagerStorageNewTotalShares) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1293,7 +1158,7 @@ func (it *EigenPodManagerStorageBeaconOracleUpdatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(EigenPodManagerStorageBeaconOracleUpdated) + it.Event = new(EigenPodManagerStorageNewTotalShares) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1309,185 +1174,52 @@ func (it *EigenPodManagerStorageBeaconOracleUpdatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodManagerStorageBeaconOracleUpdatedIterator) Error() error { +func (it *EigenPodManagerStorageNewTotalSharesIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *EigenPodManagerStorageBeaconOracleUpdatedIterator) Close() error { +func (it *EigenPodManagerStorageNewTotalSharesIterator) Close() error { it.sub.Unsubscribe() return nil } -// EigenPodManagerStorageBeaconOracleUpdated represents a BeaconOracleUpdated event raised by the EigenPodManagerStorage contract. -type EigenPodManagerStorageBeaconOracleUpdated struct { - NewOracleAddress common.Address - Raw types.Log // Blockchain specific contextual infos +// EigenPodManagerStorageNewTotalShares represents a NewTotalShares event raised by the EigenPodManagerStorage contract. +type EigenPodManagerStorageNewTotalShares struct { + PodOwner common.Address + NewTotalShares *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterBeaconOracleUpdated is a free log retrieval operation binding the contract event 0x08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f6. +// FilterNewTotalShares is a free log retrieval operation binding the contract event 0xd4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098. // -// Solidity: event BeaconOracleUpdated(address indexed newOracleAddress) -func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) FilterBeaconOracleUpdated(opts *bind.FilterOpts, newOracleAddress []common.Address) (*EigenPodManagerStorageBeaconOracleUpdatedIterator, error) { +// Solidity: event NewTotalShares(address indexed podOwner, int256 newTotalShares) +func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) FilterNewTotalShares(opts *bind.FilterOpts, podOwner []common.Address) (*EigenPodManagerStorageNewTotalSharesIterator, error) { - var newOracleAddressRule []interface{} - for _, newOracleAddressItem := range newOracleAddress { - newOracleAddressRule = append(newOracleAddressRule, newOracleAddressItem) + var podOwnerRule []interface{} + for _, podOwnerItem := range podOwner { + podOwnerRule = append(podOwnerRule, podOwnerItem) } - logs, sub, err := _EigenPodManagerStorage.contract.FilterLogs(opts, "BeaconOracleUpdated", newOracleAddressRule) + logs, sub, err := _EigenPodManagerStorage.contract.FilterLogs(opts, "NewTotalShares", podOwnerRule) if err != nil { return nil, err } - return &EigenPodManagerStorageBeaconOracleUpdatedIterator{contract: _EigenPodManagerStorage.contract, event: "BeaconOracleUpdated", logs: logs, sub: sub}, nil + return &EigenPodManagerStorageNewTotalSharesIterator{contract: _EigenPodManagerStorage.contract, event: "NewTotalShares", logs: logs, sub: sub}, nil } -// WatchBeaconOracleUpdated is a free log subscription operation binding the contract event 0x08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f6. +// WatchNewTotalShares is a free log subscription operation binding the contract event 0xd4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098. // -// Solidity: event BeaconOracleUpdated(address indexed newOracleAddress) -func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) WatchBeaconOracleUpdated(opts *bind.WatchOpts, sink chan<- *EigenPodManagerStorageBeaconOracleUpdated, newOracleAddress []common.Address) (event.Subscription, error) { - - var newOracleAddressRule []interface{} - for _, newOracleAddressItem := range newOracleAddress { - newOracleAddressRule = append(newOracleAddressRule, newOracleAddressItem) - } +// Solidity: event NewTotalShares(address indexed podOwner, int256 newTotalShares) +func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) WatchNewTotalShares(opts *bind.WatchOpts, sink chan<- *EigenPodManagerStorageNewTotalShares, podOwner []common.Address) (event.Subscription, error) { - logs, sub, err := _EigenPodManagerStorage.contract.WatchLogs(opts, "BeaconOracleUpdated", newOracleAddressRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(EigenPodManagerStorageBeaconOracleUpdated) - if err := _EigenPodManagerStorage.contract.UnpackLog(event, "BeaconOracleUpdated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseBeaconOracleUpdated is a log parse operation binding the contract event 0x08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f6. -// -// Solidity: event BeaconOracleUpdated(address indexed newOracleAddress) -func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) ParseBeaconOracleUpdated(log types.Log) (*EigenPodManagerStorageBeaconOracleUpdated, error) { - event := new(EigenPodManagerStorageBeaconOracleUpdated) - if err := _EigenPodManagerStorage.contract.UnpackLog(event, "BeaconOracleUpdated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// EigenPodManagerStorageDenebForkTimestampUpdatedIterator is returned from FilterDenebForkTimestampUpdated and is used to iterate over the raw logs and unpacked data for DenebForkTimestampUpdated events raised by the EigenPodManagerStorage contract. -type EigenPodManagerStorageDenebForkTimestampUpdatedIterator struct { - Event *EigenPodManagerStorageDenebForkTimestampUpdated // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *EigenPodManagerStorageDenebForkTimestampUpdatedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(EigenPodManagerStorageDenebForkTimestampUpdated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(EigenPodManagerStorageDenebForkTimestampUpdated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *EigenPodManagerStorageDenebForkTimestampUpdatedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *EigenPodManagerStorageDenebForkTimestampUpdatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// EigenPodManagerStorageDenebForkTimestampUpdated represents a DenebForkTimestampUpdated event raised by the EigenPodManagerStorage contract. -type EigenPodManagerStorageDenebForkTimestampUpdated struct { - NewValue uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDenebForkTimestampUpdated is a free log retrieval operation binding the contract event 0x19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db. -// -// Solidity: event DenebForkTimestampUpdated(uint64 newValue) -func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) FilterDenebForkTimestampUpdated(opts *bind.FilterOpts) (*EigenPodManagerStorageDenebForkTimestampUpdatedIterator, error) { - - logs, sub, err := _EigenPodManagerStorage.contract.FilterLogs(opts, "DenebForkTimestampUpdated") - if err != nil { - return nil, err + var podOwnerRule []interface{} + for _, podOwnerItem := range podOwner { + podOwnerRule = append(podOwnerRule, podOwnerItem) } - return &EigenPodManagerStorageDenebForkTimestampUpdatedIterator{contract: _EigenPodManagerStorage.contract, event: "DenebForkTimestampUpdated", logs: logs, sub: sub}, nil -} - -// WatchDenebForkTimestampUpdated is a free log subscription operation binding the contract event 0x19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db. -// -// Solidity: event DenebForkTimestampUpdated(uint64 newValue) -func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) WatchDenebForkTimestampUpdated(opts *bind.WatchOpts, sink chan<- *EigenPodManagerStorageDenebForkTimestampUpdated) (event.Subscription, error) { - logs, sub, err := _EigenPodManagerStorage.contract.WatchLogs(opts, "DenebForkTimestampUpdated") + logs, sub, err := _EigenPodManagerStorage.contract.WatchLogs(opts, "NewTotalShares", podOwnerRule) if err != nil { return nil, err } @@ -1497,8 +1229,8 @@ func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) WatchDenebForkTim select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(EigenPodManagerStorageDenebForkTimestampUpdated) - if err := _EigenPodManagerStorage.contract.UnpackLog(event, "DenebForkTimestampUpdated", log); err != nil { + event := new(EigenPodManagerStorageNewTotalShares) + if err := _EigenPodManagerStorage.contract.UnpackLog(event, "NewTotalShares", log); err != nil { return err } event.Raw = log @@ -1519,12 +1251,12 @@ func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) WatchDenebForkTim }), nil } -// ParseDenebForkTimestampUpdated is a log parse operation binding the contract event 0x19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db. +// ParseNewTotalShares is a log parse operation binding the contract event 0xd4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098. // -// Solidity: event DenebForkTimestampUpdated(uint64 newValue) -func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) ParseDenebForkTimestampUpdated(log types.Log) (*EigenPodManagerStorageDenebForkTimestampUpdated, error) { - event := new(EigenPodManagerStorageDenebForkTimestampUpdated) - if err := _EigenPodManagerStorage.contract.UnpackLog(event, "DenebForkTimestampUpdated", log); err != nil { +// Solidity: event NewTotalShares(address indexed podOwner, int256 newTotalShares) +func (_EigenPodManagerStorage *EigenPodManagerStorageFilterer) ParseNewTotalShares(log types.Log) (*EigenPodManagerStorageNewTotalShares, error) { + event := new(EigenPodManagerStorageNewTotalShares) + if err := _EigenPodManagerStorage.contract.UnpackLog(event, "NewTotalShares", log); err != nil { return nil, err } event.Raw = log diff --git a/pkg/bindings/EigenPodStorage/binding.go b/pkg/bindings/EigenPodStorage/binding.go new file mode 100644 index 000000000..70640763e --- /dev/null +++ b/pkg/bindings/EigenPodStorage/binding.go @@ -0,0 +1,2268 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package EigenPodStorage + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// BeaconChainProofsBalanceContainerProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsBalanceContainerProof struct { + BalanceContainerRoot [32]byte + Proof []byte +} + +// BeaconChainProofsBalanceProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsBalanceProof struct { + PubkeyHash [32]byte + BalanceRoot [32]byte + Proof []byte +} + +// BeaconChainProofsStateRootProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsStateRootProof struct { + BeaconStateRoot [32]byte + Proof []byte +} + +// BeaconChainProofsValidatorProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsValidatorProof struct { + ValidatorFields [][32]byte + Proof []byte +} + +// IEigenPodCheckpoint is an auto generated low-level Go binding around an user-defined struct. +type IEigenPodCheckpoint struct { + BeaconBlockRoot [32]byte + ProofsRemaining *big.Int + PodBalanceGwei uint64 + BalanceDeltasGwei *big.Int +} + +// IEigenPodValidatorInfo is an auto generated low-level Go binding around an user-defined struct. +type IEigenPodValidatorInfo struct { + ValidatorIndex uint64 + RestakedBalanceGwei uint64 + LastCheckpointedAt uint64 + Status uint8 +} + +// EigenPodStorageMetaData contains all meta data concerning the EigenPodStorage contract. +var EigenPodStorageMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"activeValidatorCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkpointBalanceExitedGwei\",\"inputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"currentCheckpoint\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.Checkpoint\",\"components\":[{\"name\":\"beaconBlockRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proofsRemaining\",\"type\":\"uint24\",\"internalType\":\"uint24\"},{\"name\":\"podBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"balanceDeltasGwei\",\"type\":\"int128\",\"internalType\":\"int128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"currentCheckpointTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getParentBlockRoot\",\"inputs\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"lastCheckpointTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proofSubmitter\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recoverTokens\",\"inputs\":[{\"name\":\"tokenList\",\"type\":\"address[]\",\"internalType\":\"contractIERC20[]\"},{\"name\":\"amountsToWithdraw\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setProofSubmitter\",\"inputs\":[{\"name\":\"newProofSubmitter\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"startCheckpoint\",\"inputs\":[{\"name\":\"revertIfNoBalance\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"validatorPubkeyHashToInfo\",\"inputs\":[{\"name\":\"validatorPubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastCheckpointedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorPubkeyToInfo\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastCheckpointedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"pubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifyCheckpointProofs\",\"inputs\":[{\"name\":\"balanceContainerProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.BalanceContainerProof\",\"components\":[{\"name\":\"balanceContainerRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"proofs\",\"type\":\"tuple[]\",\"internalType\":\"structBeaconChainProofs.BalanceProof[]\",\"components\":[{\"name\":\"pubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"balanceRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyStaleBalance\",\"inputs\":[{\"name\":\"beaconTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"proof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.ValidatorProof\",\"components\":[{\"name\":\"validatorFields\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyWithdrawalCredentials\",\"inputs\":[{\"name\":\"beaconTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"validatorIndices\",\"type\":\"uint40[]\",\"internalType\":\"uint40[]\"},{\"name\":\"validatorFieldsProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"validatorFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawRestakedBeaconChainETH\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawableRestakedExecutionLayerGwei\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"CheckpointCreated\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"beaconBlockRoot\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validatorCount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CheckpointFinalized\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"totalShareDeltaWei\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EigenPodStaked\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NonBeaconChainETHReceived\",\"inputs\":[{\"name\":\"amountReceived\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProofSubmitterUpdated\",\"inputs\":[{\"name\":\"prevProofSubmitter\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newProofSubmitter\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RestakedBeaconChainETHWithdrawn\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorBalanceUpdated\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"},{\"name\":\"balanceTimestamp\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"newValidatorBalanceGwei\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorCheckpointed\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":true,\"internalType\":\"uint40\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRestaked\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorWithdrawn\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":true,\"internalType\":\"uint40\"}],\"anonymous\":false}]", +} + +// EigenPodStorageABI is the input ABI used to generate the binding from. +// Deprecated: Use EigenPodStorageMetaData.ABI instead. +var EigenPodStorageABI = EigenPodStorageMetaData.ABI + +// EigenPodStorage is an auto generated Go binding around an Ethereum contract. +type EigenPodStorage struct { + EigenPodStorageCaller // Read-only binding to the contract + EigenPodStorageTransactor // Write-only binding to the contract + EigenPodStorageFilterer // Log filterer for contract events +} + +// EigenPodStorageCaller is an auto generated read-only Go binding around an Ethereum contract. +type EigenPodStorageCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EigenPodStorageTransactor is an auto generated write-only Go binding around an Ethereum contract. +type EigenPodStorageTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EigenPodStorageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type EigenPodStorageFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EigenPodStorageSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type EigenPodStorageSession struct { + Contract *EigenPodStorage // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// EigenPodStorageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type EigenPodStorageCallerSession struct { + Contract *EigenPodStorageCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// EigenPodStorageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type EigenPodStorageTransactorSession struct { + Contract *EigenPodStorageTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// EigenPodStorageRaw is an auto generated low-level Go binding around an Ethereum contract. +type EigenPodStorageRaw struct { + Contract *EigenPodStorage // Generic contract binding to access the raw methods on +} + +// EigenPodStorageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type EigenPodStorageCallerRaw struct { + Contract *EigenPodStorageCaller // Generic read-only contract binding to access the raw methods on +} + +// EigenPodStorageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type EigenPodStorageTransactorRaw struct { + Contract *EigenPodStorageTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewEigenPodStorage creates a new instance of EigenPodStorage, bound to a specific deployed contract. +func NewEigenPodStorage(address common.Address, backend bind.ContractBackend) (*EigenPodStorage, error) { + contract, err := bindEigenPodStorage(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EigenPodStorage{EigenPodStorageCaller: EigenPodStorageCaller{contract: contract}, EigenPodStorageTransactor: EigenPodStorageTransactor{contract: contract}, EigenPodStorageFilterer: EigenPodStorageFilterer{contract: contract}}, nil +} + +// NewEigenPodStorageCaller creates a new read-only instance of EigenPodStorage, bound to a specific deployed contract. +func NewEigenPodStorageCaller(address common.Address, caller bind.ContractCaller) (*EigenPodStorageCaller, error) { + contract, err := bindEigenPodStorage(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EigenPodStorageCaller{contract: contract}, nil +} + +// NewEigenPodStorageTransactor creates a new write-only instance of EigenPodStorage, bound to a specific deployed contract. +func NewEigenPodStorageTransactor(address common.Address, transactor bind.ContractTransactor) (*EigenPodStorageTransactor, error) { + contract, err := bindEigenPodStorage(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EigenPodStorageTransactor{contract: contract}, nil +} + +// NewEigenPodStorageFilterer creates a new log filterer instance of EigenPodStorage, bound to a specific deployed contract. +func NewEigenPodStorageFilterer(address common.Address, filterer bind.ContractFilterer) (*EigenPodStorageFilterer, error) { + contract, err := bindEigenPodStorage(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EigenPodStorageFilterer{contract: contract}, nil +} + +// bindEigenPodStorage binds a generic wrapper to an already deployed contract. +func bindEigenPodStorage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EigenPodStorageMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EigenPodStorage *EigenPodStorageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EigenPodStorage.Contract.EigenPodStorageCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EigenPodStorage *EigenPodStorageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EigenPodStorage.Contract.EigenPodStorageTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_EigenPodStorage *EigenPodStorageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EigenPodStorage.Contract.EigenPodStorageTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EigenPodStorage *EigenPodStorageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EigenPodStorage.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EigenPodStorage *EigenPodStorageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EigenPodStorage.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_EigenPodStorage *EigenPodStorageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EigenPodStorage.Contract.contract.Transact(opts, method, params...) +} + +// ActiveValidatorCount is a free data retrieval call binding the contract method 0x2340e8d3. +// +// Solidity: function activeValidatorCount() view returns(uint256) +func (_EigenPodStorage *EigenPodStorageCaller) ActiveValidatorCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "activeValidatorCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ActiveValidatorCount is a free data retrieval call binding the contract method 0x2340e8d3. +// +// Solidity: function activeValidatorCount() view returns(uint256) +func (_EigenPodStorage *EigenPodStorageSession) ActiveValidatorCount() (*big.Int, error) { + return _EigenPodStorage.Contract.ActiveValidatorCount(&_EigenPodStorage.CallOpts) +} + +// ActiveValidatorCount is a free data retrieval call binding the contract method 0x2340e8d3. +// +// Solidity: function activeValidatorCount() view returns(uint256) +func (_EigenPodStorage *EigenPodStorageCallerSession) ActiveValidatorCount() (*big.Int, error) { + return _EigenPodStorage.Contract.ActiveValidatorCount(&_EigenPodStorage.CallOpts) +} + +// CheckpointBalanceExitedGwei is a free data retrieval call binding the contract method 0x52396a59. +// +// Solidity: function checkpointBalanceExitedGwei(uint64 ) view returns(uint64) +func (_EigenPodStorage *EigenPodStorageCaller) CheckpointBalanceExitedGwei(opts *bind.CallOpts, arg0 uint64) (uint64, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "checkpointBalanceExitedGwei", arg0) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// CheckpointBalanceExitedGwei is a free data retrieval call binding the contract method 0x52396a59. +// +// Solidity: function checkpointBalanceExitedGwei(uint64 ) view returns(uint64) +func (_EigenPodStorage *EigenPodStorageSession) CheckpointBalanceExitedGwei(arg0 uint64) (uint64, error) { + return _EigenPodStorage.Contract.CheckpointBalanceExitedGwei(&_EigenPodStorage.CallOpts, arg0) +} + +// CheckpointBalanceExitedGwei is a free data retrieval call binding the contract method 0x52396a59. +// +// Solidity: function checkpointBalanceExitedGwei(uint64 ) view returns(uint64) +func (_EigenPodStorage *EigenPodStorageCallerSession) CheckpointBalanceExitedGwei(arg0 uint64) (uint64, error) { + return _EigenPodStorage.Contract.CheckpointBalanceExitedGwei(&_EigenPodStorage.CallOpts, arg0) +} + +// CurrentCheckpoint is a free data retrieval call binding the contract method 0x47d28372. +// +// Solidity: function currentCheckpoint() view returns((bytes32,uint24,uint64,int128)) +func (_EigenPodStorage *EigenPodStorageCaller) CurrentCheckpoint(opts *bind.CallOpts) (IEigenPodCheckpoint, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "currentCheckpoint") + + if err != nil { + return *new(IEigenPodCheckpoint), err + } + + out0 := *abi.ConvertType(out[0], new(IEigenPodCheckpoint)).(*IEigenPodCheckpoint) + + return out0, err + +} + +// CurrentCheckpoint is a free data retrieval call binding the contract method 0x47d28372. +// +// Solidity: function currentCheckpoint() view returns((bytes32,uint24,uint64,int128)) +func (_EigenPodStorage *EigenPodStorageSession) CurrentCheckpoint() (IEigenPodCheckpoint, error) { + return _EigenPodStorage.Contract.CurrentCheckpoint(&_EigenPodStorage.CallOpts) +} + +// CurrentCheckpoint is a free data retrieval call binding the contract method 0x47d28372. +// +// Solidity: function currentCheckpoint() view returns((bytes32,uint24,uint64,int128)) +func (_EigenPodStorage *EigenPodStorageCallerSession) CurrentCheckpoint() (IEigenPodCheckpoint, error) { + return _EigenPodStorage.Contract.CurrentCheckpoint(&_EigenPodStorage.CallOpts) +} + +// CurrentCheckpointTimestamp is a free data retrieval call binding the contract method 0x42ecff2a. +// +// Solidity: function currentCheckpointTimestamp() view returns(uint64) +func (_EigenPodStorage *EigenPodStorageCaller) CurrentCheckpointTimestamp(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "currentCheckpointTimestamp") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// CurrentCheckpointTimestamp is a free data retrieval call binding the contract method 0x42ecff2a. +// +// Solidity: function currentCheckpointTimestamp() view returns(uint64) +func (_EigenPodStorage *EigenPodStorageSession) CurrentCheckpointTimestamp() (uint64, error) { + return _EigenPodStorage.Contract.CurrentCheckpointTimestamp(&_EigenPodStorage.CallOpts) +} + +// CurrentCheckpointTimestamp is a free data retrieval call binding the contract method 0x42ecff2a. +// +// Solidity: function currentCheckpointTimestamp() view returns(uint64) +func (_EigenPodStorage *EigenPodStorageCallerSession) CurrentCheckpointTimestamp() (uint64, error) { + return _EigenPodStorage.Contract.CurrentCheckpointTimestamp(&_EigenPodStorage.CallOpts) +} + +// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. +// +// Solidity: function eigenPodManager() view returns(address) +func (_EigenPodStorage *EigenPodStorageCaller) EigenPodManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "eigenPodManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. +// +// Solidity: function eigenPodManager() view returns(address) +func (_EigenPodStorage *EigenPodStorageSession) EigenPodManager() (common.Address, error) { + return _EigenPodStorage.Contract.EigenPodManager(&_EigenPodStorage.CallOpts) +} + +// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. +// +// Solidity: function eigenPodManager() view returns(address) +func (_EigenPodStorage *EigenPodStorageCallerSession) EigenPodManager() (common.Address, error) { + return _EigenPodStorage.Contract.EigenPodManager(&_EigenPodStorage.CallOpts) +} + +// GetParentBlockRoot is a free data retrieval call binding the contract method 0x6c0d2d5a. +// +// Solidity: function getParentBlockRoot(uint64 timestamp) view returns(bytes32) +func (_EigenPodStorage *EigenPodStorageCaller) GetParentBlockRoot(opts *bind.CallOpts, timestamp uint64) ([32]byte, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "getParentBlockRoot", timestamp) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetParentBlockRoot is a free data retrieval call binding the contract method 0x6c0d2d5a. +// +// Solidity: function getParentBlockRoot(uint64 timestamp) view returns(bytes32) +func (_EigenPodStorage *EigenPodStorageSession) GetParentBlockRoot(timestamp uint64) ([32]byte, error) { + return _EigenPodStorage.Contract.GetParentBlockRoot(&_EigenPodStorage.CallOpts, timestamp) +} + +// GetParentBlockRoot is a free data retrieval call binding the contract method 0x6c0d2d5a. +// +// Solidity: function getParentBlockRoot(uint64 timestamp) view returns(bytes32) +func (_EigenPodStorage *EigenPodStorageCallerSession) GetParentBlockRoot(timestamp uint64) ([32]byte, error) { + return _EigenPodStorage.Contract.GetParentBlockRoot(&_EigenPodStorage.CallOpts, timestamp) +} + +// LastCheckpointTimestamp is a free data retrieval call binding the contract method 0xee94d67c. +// +// Solidity: function lastCheckpointTimestamp() view returns(uint64) +func (_EigenPodStorage *EigenPodStorageCaller) LastCheckpointTimestamp(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "lastCheckpointTimestamp") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastCheckpointTimestamp is a free data retrieval call binding the contract method 0xee94d67c. +// +// Solidity: function lastCheckpointTimestamp() view returns(uint64) +func (_EigenPodStorage *EigenPodStorageSession) LastCheckpointTimestamp() (uint64, error) { + return _EigenPodStorage.Contract.LastCheckpointTimestamp(&_EigenPodStorage.CallOpts) +} + +// LastCheckpointTimestamp is a free data retrieval call binding the contract method 0xee94d67c. +// +// Solidity: function lastCheckpointTimestamp() view returns(uint64) +func (_EigenPodStorage *EigenPodStorageCallerSession) LastCheckpointTimestamp() (uint64, error) { + return _EigenPodStorage.Contract.LastCheckpointTimestamp(&_EigenPodStorage.CallOpts) +} + +// PodOwner is a free data retrieval call binding the contract method 0x0b18ff66. +// +// Solidity: function podOwner() view returns(address) +func (_EigenPodStorage *EigenPodStorageCaller) PodOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "podOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PodOwner is a free data retrieval call binding the contract method 0x0b18ff66. +// +// Solidity: function podOwner() view returns(address) +func (_EigenPodStorage *EigenPodStorageSession) PodOwner() (common.Address, error) { + return _EigenPodStorage.Contract.PodOwner(&_EigenPodStorage.CallOpts) +} + +// PodOwner is a free data retrieval call binding the contract method 0x0b18ff66. +// +// Solidity: function podOwner() view returns(address) +func (_EigenPodStorage *EigenPodStorageCallerSession) PodOwner() (common.Address, error) { + return _EigenPodStorage.Contract.PodOwner(&_EigenPodStorage.CallOpts) +} + +// ProofSubmitter is a free data retrieval call binding the contract method 0x58753357. +// +// Solidity: function proofSubmitter() view returns(address) +func (_EigenPodStorage *EigenPodStorageCaller) ProofSubmitter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "proofSubmitter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// ProofSubmitter is a free data retrieval call binding the contract method 0x58753357. +// +// Solidity: function proofSubmitter() view returns(address) +func (_EigenPodStorage *EigenPodStorageSession) ProofSubmitter() (common.Address, error) { + return _EigenPodStorage.Contract.ProofSubmitter(&_EigenPodStorage.CallOpts) +} + +// ProofSubmitter is a free data retrieval call binding the contract method 0x58753357. +// +// Solidity: function proofSubmitter() view returns(address) +func (_EigenPodStorage *EigenPodStorageCallerSession) ProofSubmitter() (common.Address, error) { + return _EigenPodStorage.Contract.ProofSubmitter(&_EigenPodStorage.CallOpts) +} + +// ValidatorPubkeyHashToInfo is a free data retrieval call binding the contract method 0x6fcd0e53. +// +// Solidity: function validatorPubkeyHashToInfo(bytes32 validatorPubkeyHash) view returns((uint64,uint64,uint64,uint8)) +func (_EigenPodStorage *EigenPodStorageCaller) ValidatorPubkeyHashToInfo(opts *bind.CallOpts, validatorPubkeyHash [32]byte) (IEigenPodValidatorInfo, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "validatorPubkeyHashToInfo", validatorPubkeyHash) + + if err != nil { + return *new(IEigenPodValidatorInfo), err + } + + out0 := *abi.ConvertType(out[0], new(IEigenPodValidatorInfo)).(*IEigenPodValidatorInfo) + + return out0, err + +} + +// ValidatorPubkeyHashToInfo is a free data retrieval call binding the contract method 0x6fcd0e53. +// +// Solidity: function validatorPubkeyHashToInfo(bytes32 validatorPubkeyHash) view returns((uint64,uint64,uint64,uint8)) +func (_EigenPodStorage *EigenPodStorageSession) ValidatorPubkeyHashToInfo(validatorPubkeyHash [32]byte) (IEigenPodValidatorInfo, error) { + return _EigenPodStorage.Contract.ValidatorPubkeyHashToInfo(&_EigenPodStorage.CallOpts, validatorPubkeyHash) +} + +// ValidatorPubkeyHashToInfo is a free data retrieval call binding the contract method 0x6fcd0e53. +// +// Solidity: function validatorPubkeyHashToInfo(bytes32 validatorPubkeyHash) view returns((uint64,uint64,uint64,uint8)) +func (_EigenPodStorage *EigenPodStorageCallerSession) ValidatorPubkeyHashToInfo(validatorPubkeyHash [32]byte) (IEigenPodValidatorInfo, error) { + return _EigenPodStorage.Contract.ValidatorPubkeyHashToInfo(&_EigenPodStorage.CallOpts, validatorPubkeyHash) +} + +// ValidatorPubkeyToInfo is a free data retrieval call binding the contract method 0xb522538a. +// +// Solidity: function validatorPubkeyToInfo(bytes validatorPubkey) view returns((uint64,uint64,uint64,uint8)) +func (_EigenPodStorage *EigenPodStorageCaller) ValidatorPubkeyToInfo(opts *bind.CallOpts, validatorPubkey []byte) (IEigenPodValidatorInfo, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "validatorPubkeyToInfo", validatorPubkey) + + if err != nil { + return *new(IEigenPodValidatorInfo), err + } + + out0 := *abi.ConvertType(out[0], new(IEigenPodValidatorInfo)).(*IEigenPodValidatorInfo) + + return out0, err + +} + +// ValidatorPubkeyToInfo is a free data retrieval call binding the contract method 0xb522538a. +// +// Solidity: function validatorPubkeyToInfo(bytes validatorPubkey) view returns((uint64,uint64,uint64,uint8)) +func (_EigenPodStorage *EigenPodStorageSession) ValidatorPubkeyToInfo(validatorPubkey []byte) (IEigenPodValidatorInfo, error) { + return _EigenPodStorage.Contract.ValidatorPubkeyToInfo(&_EigenPodStorage.CallOpts, validatorPubkey) +} + +// ValidatorPubkeyToInfo is a free data retrieval call binding the contract method 0xb522538a. +// +// Solidity: function validatorPubkeyToInfo(bytes validatorPubkey) view returns((uint64,uint64,uint64,uint8)) +func (_EigenPodStorage *EigenPodStorageCallerSession) ValidatorPubkeyToInfo(validatorPubkey []byte) (IEigenPodValidatorInfo, error) { + return _EigenPodStorage.Contract.ValidatorPubkeyToInfo(&_EigenPodStorage.CallOpts, validatorPubkey) +} + +// ValidatorStatus is a free data retrieval call binding the contract method 0x58eaee79. +// +// Solidity: function validatorStatus(bytes validatorPubkey) view returns(uint8) +func (_EigenPodStorage *EigenPodStorageCaller) ValidatorStatus(opts *bind.CallOpts, validatorPubkey []byte) (uint8, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "validatorStatus", validatorPubkey) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// ValidatorStatus is a free data retrieval call binding the contract method 0x58eaee79. +// +// Solidity: function validatorStatus(bytes validatorPubkey) view returns(uint8) +func (_EigenPodStorage *EigenPodStorageSession) ValidatorStatus(validatorPubkey []byte) (uint8, error) { + return _EigenPodStorage.Contract.ValidatorStatus(&_EigenPodStorage.CallOpts, validatorPubkey) +} + +// ValidatorStatus is a free data retrieval call binding the contract method 0x58eaee79. +// +// Solidity: function validatorStatus(bytes validatorPubkey) view returns(uint8) +func (_EigenPodStorage *EigenPodStorageCallerSession) ValidatorStatus(validatorPubkey []byte) (uint8, error) { + return _EigenPodStorage.Contract.ValidatorStatus(&_EigenPodStorage.CallOpts, validatorPubkey) +} + +// ValidatorStatus0 is a free data retrieval call binding the contract method 0x7439841f. +// +// Solidity: function validatorStatus(bytes32 pubkeyHash) view returns(uint8) +func (_EigenPodStorage *EigenPodStorageCaller) ValidatorStatus0(opts *bind.CallOpts, pubkeyHash [32]byte) (uint8, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "validatorStatus0", pubkeyHash) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// ValidatorStatus0 is a free data retrieval call binding the contract method 0x7439841f. +// +// Solidity: function validatorStatus(bytes32 pubkeyHash) view returns(uint8) +func (_EigenPodStorage *EigenPodStorageSession) ValidatorStatus0(pubkeyHash [32]byte) (uint8, error) { + return _EigenPodStorage.Contract.ValidatorStatus0(&_EigenPodStorage.CallOpts, pubkeyHash) +} + +// ValidatorStatus0 is a free data retrieval call binding the contract method 0x7439841f. +// +// Solidity: function validatorStatus(bytes32 pubkeyHash) view returns(uint8) +func (_EigenPodStorage *EigenPodStorageCallerSession) ValidatorStatus0(pubkeyHash [32]byte) (uint8, error) { + return _EigenPodStorage.Contract.ValidatorStatus0(&_EigenPodStorage.CallOpts, pubkeyHash) +} + +// WithdrawableRestakedExecutionLayerGwei is a free data retrieval call binding the contract method 0x3474aa16. +// +// Solidity: function withdrawableRestakedExecutionLayerGwei() view returns(uint64) +func (_EigenPodStorage *EigenPodStorageCaller) WithdrawableRestakedExecutionLayerGwei(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _EigenPodStorage.contract.Call(opts, &out, "withdrawableRestakedExecutionLayerGwei") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// WithdrawableRestakedExecutionLayerGwei is a free data retrieval call binding the contract method 0x3474aa16. +// +// Solidity: function withdrawableRestakedExecutionLayerGwei() view returns(uint64) +func (_EigenPodStorage *EigenPodStorageSession) WithdrawableRestakedExecutionLayerGwei() (uint64, error) { + return _EigenPodStorage.Contract.WithdrawableRestakedExecutionLayerGwei(&_EigenPodStorage.CallOpts) +} + +// WithdrawableRestakedExecutionLayerGwei is a free data retrieval call binding the contract method 0x3474aa16. +// +// Solidity: function withdrawableRestakedExecutionLayerGwei() view returns(uint64) +func (_EigenPodStorage *EigenPodStorageCallerSession) WithdrawableRestakedExecutionLayerGwei() (uint64, error) { + return _EigenPodStorage.Contract.WithdrawableRestakedExecutionLayerGwei(&_EigenPodStorage.CallOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address owner) returns() +func (_EigenPodStorage *EigenPodStorageTransactor) Initialize(opts *bind.TransactOpts, owner common.Address) (*types.Transaction, error) { + return _EigenPodStorage.contract.Transact(opts, "initialize", owner) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address owner) returns() +func (_EigenPodStorage *EigenPodStorageSession) Initialize(owner common.Address) (*types.Transaction, error) { + return _EigenPodStorage.Contract.Initialize(&_EigenPodStorage.TransactOpts, owner) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address owner) returns() +func (_EigenPodStorage *EigenPodStorageTransactorSession) Initialize(owner common.Address) (*types.Transaction, error) { + return _EigenPodStorage.Contract.Initialize(&_EigenPodStorage.TransactOpts, owner) +} + +// RecoverTokens is a paid mutator transaction binding the contract method 0xdda3346c. +// +// Solidity: function recoverTokens(address[] tokenList, uint256[] amountsToWithdraw, address recipient) returns() +func (_EigenPodStorage *EigenPodStorageTransactor) RecoverTokens(opts *bind.TransactOpts, tokenList []common.Address, amountsToWithdraw []*big.Int, recipient common.Address) (*types.Transaction, error) { + return _EigenPodStorage.contract.Transact(opts, "recoverTokens", tokenList, amountsToWithdraw, recipient) +} + +// RecoverTokens is a paid mutator transaction binding the contract method 0xdda3346c. +// +// Solidity: function recoverTokens(address[] tokenList, uint256[] amountsToWithdraw, address recipient) returns() +func (_EigenPodStorage *EigenPodStorageSession) RecoverTokens(tokenList []common.Address, amountsToWithdraw []*big.Int, recipient common.Address) (*types.Transaction, error) { + return _EigenPodStorage.Contract.RecoverTokens(&_EigenPodStorage.TransactOpts, tokenList, amountsToWithdraw, recipient) +} + +// RecoverTokens is a paid mutator transaction binding the contract method 0xdda3346c. +// +// Solidity: function recoverTokens(address[] tokenList, uint256[] amountsToWithdraw, address recipient) returns() +func (_EigenPodStorage *EigenPodStorageTransactorSession) RecoverTokens(tokenList []common.Address, amountsToWithdraw []*big.Int, recipient common.Address) (*types.Transaction, error) { + return _EigenPodStorage.Contract.RecoverTokens(&_EigenPodStorage.TransactOpts, tokenList, amountsToWithdraw, recipient) +} + +// SetProofSubmitter is a paid mutator transaction binding the contract method 0xd06d5587. +// +// Solidity: function setProofSubmitter(address newProofSubmitter) returns() +func (_EigenPodStorage *EigenPodStorageTransactor) SetProofSubmitter(opts *bind.TransactOpts, newProofSubmitter common.Address) (*types.Transaction, error) { + return _EigenPodStorage.contract.Transact(opts, "setProofSubmitter", newProofSubmitter) +} + +// SetProofSubmitter is a paid mutator transaction binding the contract method 0xd06d5587. +// +// Solidity: function setProofSubmitter(address newProofSubmitter) returns() +func (_EigenPodStorage *EigenPodStorageSession) SetProofSubmitter(newProofSubmitter common.Address) (*types.Transaction, error) { + return _EigenPodStorage.Contract.SetProofSubmitter(&_EigenPodStorage.TransactOpts, newProofSubmitter) +} + +// SetProofSubmitter is a paid mutator transaction binding the contract method 0xd06d5587. +// +// Solidity: function setProofSubmitter(address newProofSubmitter) returns() +func (_EigenPodStorage *EigenPodStorageTransactorSession) SetProofSubmitter(newProofSubmitter common.Address) (*types.Transaction, error) { + return _EigenPodStorage.Contract.SetProofSubmitter(&_EigenPodStorage.TransactOpts, newProofSubmitter) +} + +// Stake is a paid mutator transaction binding the contract method 0x9b4e4634. +// +// Solidity: function stake(bytes pubkey, bytes signature, bytes32 depositDataRoot) payable returns() +func (_EigenPodStorage *EigenPodStorageTransactor) Stake(opts *bind.TransactOpts, pubkey []byte, signature []byte, depositDataRoot [32]byte) (*types.Transaction, error) { + return _EigenPodStorage.contract.Transact(opts, "stake", pubkey, signature, depositDataRoot) +} + +// Stake is a paid mutator transaction binding the contract method 0x9b4e4634. +// +// Solidity: function stake(bytes pubkey, bytes signature, bytes32 depositDataRoot) payable returns() +func (_EigenPodStorage *EigenPodStorageSession) Stake(pubkey []byte, signature []byte, depositDataRoot [32]byte) (*types.Transaction, error) { + return _EigenPodStorage.Contract.Stake(&_EigenPodStorage.TransactOpts, pubkey, signature, depositDataRoot) +} + +// Stake is a paid mutator transaction binding the contract method 0x9b4e4634. +// +// Solidity: function stake(bytes pubkey, bytes signature, bytes32 depositDataRoot) payable returns() +func (_EigenPodStorage *EigenPodStorageTransactorSession) Stake(pubkey []byte, signature []byte, depositDataRoot [32]byte) (*types.Transaction, error) { + return _EigenPodStorage.Contract.Stake(&_EigenPodStorage.TransactOpts, pubkey, signature, depositDataRoot) +} + +// StartCheckpoint is a paid mutator transaction binding the contract method 0x88676cad. +// +// Solidity: function startCheckpoint(bool revertIfNoBalance) returns() +func (_EigenPodStorage *EigenPodStorageTransactor) StartCheckpoint(opts *bind.TransactOpts, revertIfNoBalance bool) (*types.Transaction, error) { + return _EigenPodStorage.contract.Transact(opts, "startCheckpoint", revertIfNoBalance) +} + +// StartCheckpoint is a paid mutator transaction binding the contract method 0x88676cad. +// +// Solidity: function startCheckpoint(bool revertIfNoBalance) returns() +func (_EigenPodStorage *EigenPodStorageSession) StartCheckpoint(revertIfNoBalance bool) (*types.Transaction, error) { + return _EigenPodStorage.Contract.StartCheckpoint(&_EigenPodStorage.TransactOpts, revertIfNoBalance) +} + +// StartCheckpoint is a paid mutator transaction binding the contract method 0x88676cad. +// +// Solidity: function startCheckpoint(bool revertIfNoBalance) returns() +func (_EigenPodStorage *EigenPodStorageTransactorSession) StartCheckpoint(revertIfNoBalance bool) (*types.Transaction, error) { + return _EigenPodStorage.Contract.StartCheckpoint(&_EigenPodStorage.TransactOpts, revertIfNoBalance) +} + +// VerifyCheckpointProofs is a paid mutator transaction binding the contract method 0xf074ba62. +// +// Solidity: function verifyCheckpointProofs((bytes32,bytes) balanceContainerProof, (bytes32,bytes32,bytes)[] proofs) returns() +func (_EigenPodStorage *EigenPodStorageTransactor) VerifyCheckpointProofs(opts *bind.TransactOpts, balanceContainerProof BeaconChainProofsBalanceContainerProof, proofs []BeaconChainProofsBalanceProof) (*types.Transaction, error) { + return _EigenPodStorage.contract.Transact(opts, "verifyCheckpointProofs", balanceContainerProof, proofs) +} + +// VerifyCheckpointProofs is a paid mutator transaction binding the contract method 0xf074ba62. +// +// Solidity: function verifyCheckpointProofs((bytes32,bytes) balanceContainerProof, (bytes32,bytes32,bytes)[] proofs) returns() +func (_EigenPodStorage *EigenPodStorageSession) VerifyCheckpointProofs(balanceContainerProof BeaconChainProofsBalanceContainerProof, proofs []BeaconChainProofsBalanceProof) (*types.Transaction, error) { + return _EigenPodStorage.Contract.VerifyCheckpointProofs(&_EigenPodStorage.TransactOpts, balanceContainerProof, proofs) +} + +// VerifyCheckpointProofs is a paid mutator transaction binding the contract method 0xf074ba62. +// +// Solidity: function verifyCheckpointProofs((bytes32,bytes) balanceContainerProof, (bytes32,bytes32,bytes)[] proofs) returns() +func (_EigenPodStorage *EigenPodStorageTransactorSession) VerifyCheckpointProofs(balanceContainerProof BeaconChainProofsBalanceContainerProof, proofs []BeaconChainProofsBalanceProof) (*types.Transaction, error) { + return _EigenPodStorage.Contract.VerifyCheckpointProofs(&_EigenPodStorage.TransactOpts, balanceContainerProof, proofs) +} + +// VerifyStaleBalance is a paid mutator transaction binding the contract method 0x039157d2. +// +// Solidity: function verifyStaleBalance(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, (bytes32[],bytes) proof) returns() +func (_EigenPodStorage *EigenPodStorageTransactor) VerifyStaleBalance(opts *bind.TransactOpts, beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, proof BeaconChainProofsValidatorProof) (*types.Transaction, error) { + return _EigenPodStorage.contract.Transact(opts, "verifyStaleBalance", beaconTimestamp, stateRootProof, proof) +} + +// VerifyStaleBalance is a paid mutator transaction binding the contract method 0x039157d2. +// +// Solidity: function verifyStaleBalance(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, (bytes32[],bytes) proof) returns() +func (_EigenPodStorage *EigenPodStorageSession) VerifyStaleBalance(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, proof BeaconChainProofsValidatorProof) (*types.Transaction, error) { + return _EigenPodStorage.Contract.VerifyStaleBalance(&_EigenPodStorage.TransactOpts, beaconTimestamp, stateRootProof, proof) +} + +// VerifyStaleBalance is a paid mutator transaction binding the contract method 0x039157d2. +// +// Solidity: function verifyStaleBalance(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, (bytes32[],bytes) proof) returns() +func (_EigenPodStorage *EigenPodStorageTransactorSession) VerifyStaleBalance(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, proof BeaconChainProofsValidatorProof) (*types.Transaction, error) { + return _EigenPodStorage.Contract.VerifyStaleBalance(&_EigenPodStorage.TransactOpts, beaconTimestamp, stateRootProof, proof) +} + +// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. +// +// Solidity: function verifyWithdrawalCredentials(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() +func (_EigenPodStorage *EigenPodStorageTransactor) VerifyWithdrawalCredentials(opts *bind.TransactOpts, beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { + return _EigenPodStorage.contract.Transact(opts, "verifyWithdrawalCredentials", beaconTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) +} + +// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. +// +// Solidity: function verifyWithdrawalCredentials(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() +func (_EigenPodStorage *EigenPodStorageSession) VerifyWithdrawalCredentials(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { + return _EigenPodStorage.Contract.VerifyWithdrawalCredentials(&_EigenPodStorage.TransactOpts, beaconTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) +} + +// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. +// +// Solidity: function verifyWithdrawalCredentials(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() +func (_EigenPodStorage *EigenPodStorageTransactorSession) VerifyWithdrawalCredentials(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { + return _EigenPodStorage.Contract.VerifyWithdrawalCredentials(&_EigenPodStorage.TransactOpts, beaconTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) +} + +// WithdrawRestakedBeaconChainETH is a paid mutator transaction binding the contract method 0xc4907442. +// +// Solidity: function withdrawRestakedBeaconChainETH(address recipient, uint256 amount) returns() +func (_EigenPodStorage *EigenPodStorageTransactor) WithdrawRestakedBeaconChainETH(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _EigenPodStorage.contract.Transact(opts, "withdrawRestakedBeaconChainETH", recipient, amount) +} + +// WithdrawRestakedBeaconChainETH is a paid mutator transaction binding the contract method 0xc4907442. +// +// Solidity: function withdrawRestakedBeaconChainETH(address recipient, uint256 amount) returns() +func (_EigenPodStorage *EigenPodStorageSession) WithdrawRestakedBeaconChainETH(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _EigenPodStorage.Contract.WithdrawRestakedBeaconChainETH(&_EigenPodStorage.TransactOpts, recipient, amount) +} + +// WithdrawRestakedBeaconChainETH is a paid mutator transaction binding the contract method 0xc4907442. +// +// Solidity: function withdrawRestakedBeaconChainETH(address recipient, uint256 amount) returns() +func (_EigenPodStorage *EigenPodStorageTransactorSession) WithdrawRestakedBeaconChainETH(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _EigenPodStorage.Contract.WithdrawRestakedBeaconChainETH(&_EigenPodStorage.TransactOpts, recipient, amount) +} + +// EigenPodStorageCheckpointCreatedIterator is returned from FilterCheckpointCreated and is used to iterate over the raw logs and unpacked data for CheckpointCreated events raised by the EigenPodStorage contract. +type EigenPodStorageCheckpointCreatedIterator struct { + Event *EigenPodStorageCheckpointCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageCheckpointCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageCheckpointCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageCheckpointCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageCheckpointCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageCheckpointCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageCheckpointCreated represents a CheckpointCreated event raised by the EigenPodStorage contract. +type EigenPodStorageCheckpointCreated struct { + CheckpointTimestamp uint64 + BeaconBlockRoot [32]byte + ValidatorCount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCheckpointCreated is a free log retrieval operation binding the contract event 0x575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076. +// +// Solidity: event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterCheckpointCreated(opts *bind.FilterOpts, checkpointTimestamp []uint64, beaconBlockRoot [][32]byte) (*EigenPodStorageCheckpointCreatedIterator, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var beaconBlockRootRule []interface{} + for _, beaconBlockRootItem := range beaconBlockRoot { + beaconBlockRootRule = append(beaconBlockRootRule, beaconBlockRootItem) + } + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "CheckpointCreated", checkpointTimestampRule, beaconBlockRootRule) + if err != nil { + return nil, err + } + return &EigenPodStorageCheckpointCreatedIterator{contract: _EigenPodStorage.contract, event: "CheckpointCreated", logs: logs, sub: sub}, nil +} + +// WatchCheckpointCreated is a free log subscription operation binding the contract event 0x575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076. +// +// Solidity: event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchCheckpointCreated(opts *bind.WatchOpts, sink chan<- *EigenPodStorageCheckpointCreated, checkpointTimestamp []uint64, beaconBlockRoot [][32]byte) (event.Subscription, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var beaconBlockRootRule []interface{} + for _, beaconBlockRootItem := range beaconBlockRoot { + beaconBlockRootRule = append(beaconBlockRootRule, beaconBlockRootItem) + } + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "CheckpointCreated", checkpointTimestampRule, beaconBlockRootRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageCheckpointCreated) + if err := _EigenPodStorage.contract.UnpackLog(event, "CheckpointCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCheckpointCreated is a log parse operation binding the contract event 0x575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076. +// +// Solidity: event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseCheckpointCreated(log types.Log) (*EigenPodStorageCheckpointCreated, error) { + event := new(EigenPodStorageCheckpointCreated) + if err := _EigenPodStorage.contract.UnpackLog(event, "CheckpointCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodStorageCheckpointFinalizedIterator is returned from FilterCheckpointFinalized and is used to iterate over the raw logs and unpacked data for CheckpointFinalized events raised by the EigenPodStorage contract. +type EigenPodStorageCheckpointFinalizedIterator struct { + Event *EigenPodStorageCheckpointFinalized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageCheckpointFinalizedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageCheckpointFinalized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageCheckpointFinalized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageCheckpointFinalizedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageCheckpointFinalizedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageCheckpointFinalized represents a CheckpointFinalized event raised by the EigenPodStorage contract. +type EigenPodStorageCheckpointFinalized struct { + CheckpointTimestamp uint64 + TotalShareDeltaWei *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCheckpointFinalized is a free log retrieval operation binding the contract event 0x525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44. +// +// Solidity: event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterCheckpointFinalized(opts *bind.FilterOpts, checkpointTimestamp []uint64) (*EigenPodStorageCheckpointFinalizedIterator, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "CheckpointFinalized", checkpointTimestampRule) + if err != nil { + return nil, err + } + return &EigenPodStorageCheckpointFinalizedIterator{contract: _EigenPodStorage.contract, event: "CheckpointFinalized", logs: logs, sub: sub}, nil +} + +// WatchCheckpointFinalized is a free log subscription operation binding the contract event 0x525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44. +// +// Solidity: event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchCheckpointFinalized(opts *bind.WatchOpts, sink chan<- *EigenPodStorageCheckpointFinalized, checkpointTimestamp []uint64) (event.Subscription, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "CheckpointFinalized", checkpointTimestampRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageCheckpointFinalized) + if err := _EigenPodStorage.contract.UnpackLog(event, "CheckpointFinalized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCheckpointFinalized is a log parse operation binding the contract event 0x525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44. +// +// Solidity: event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseCheckpointFinalized(log types.Log) (*EigenPodStorageCheckpointFinalized, error) { + event := new(EigenPodStorageCheckpointFinalized) + if err := _EigenPodStorage.contract.UnpackLog(event, "CheckpointFinalized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodStorageEigenPodStakedIterator is returned from FilterEigenPodStaked and is used to iterate over the raw logs and unpacked data for EigenPodStaked events raised by the EigenPodStorage contract. +type EigenPodStorageEigenPodStakedIterator struct { + Event *EigenPodStorageEigenPodStaked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageEigenPodStakedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageEigenPodStaked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageEigenPodStaked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageEigenPodStakedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageEigenPodStakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageEigenPodStaked represents a EigenPodStaked event raised by the EigenPodStorage contract. +type EigenPodStorageEigenPodStaked struct { + Pubkey []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEigenPodStaked is a free log retrieval operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// +// Solidity: event EigenPodStaked(bytes pubkey) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterEigenPodStaked(opts *bind.FilterOpts) (*EigenPodStorageEigenPodStakedIterator, error) { + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "EigenPodStaked") + if err != nil { + return nil, err + } + return &EigenPodStorageEigenPodStakedIterator{contract: _EigenPodStorage.contract, event: "EigenPodStaked", logs: logs, sub: sub}, nil +} + +// WatchEigenPodStaked is a free log subscription operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// +// Solidity: event EigenPodStaked(bytes pubkey) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchEigenPodStaked(opts *bind.WatchOpts, sink chan<- *EigenPodStorageEigenPodStaked) (event.Subscription, error) { + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "EigenPodStaked") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageEigenPodStaked) + if err := _EigenPodStorage.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseEigenPodStaked is a log parse operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// +// Solidity: event EigenPodStaked(bytes pubkey) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseEigenPodStaked(log types.Log) (*EigenPodStorageEigenPodStaked, error) { + event := new(EigenPodStorageEigenPodStaked) + if err := _EigenPodStorage.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodStorageNonBeaconChainETHReceivedIterator is returned from FilterNonBeaconChainETHReceived and is used to iterate over the raw logs and unpacked data for NonBeaconChainETHReceived events raised by the EigenPodStorage contract. +type EigenPodStorageNonBeaconChainETHReceivedIterator struct { + Event *EigenPodStorageNonBeaconChainETHReceived // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageNonBeaconChainETHReceivedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageNonBeaconChainETHReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageNonBeaconChainETHReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageNonBeaconChainETHReceivedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageNonBeaconChainETHReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageNonBeaconChainETHReceived represents a NonBeaconChainETHReceived event raised by the EigenPodStorage contract. +type EigenPodStorageNonBeaconChainETHReceived struct { + AmountReceived *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNonBeaconChainETHReceived is a free log retrieval operation binding the contract event 0x6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf49. +// +// Solidity: event NonBeaconChainETHReceived(uint256 amountReceived) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterNonBeaconChainETHReceived(opts *bind.FilterOpts) (*EigenPodStorageNonBeaconChainETHReceivedIterator, error) { + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "NonBeaconChainETHReceived") + if err != nil { + return nil, err + } + return &EigenPodStorageNonBeaconChainETHReceivedIterator{contract: _EigenPodStorage.contract, event: "NonBeaconChainETHReceived", logs: logs, sub: sub}, nil +} + +// WatchNonBeaconChainETHReceived is a free log subscription operation binding the contract event 0x6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf49. +// +// Solidity: event NonBeaconChainETHReceived(uint256 amountReceived) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchNonBeaconChainETHReceived(opts *bind.WatchOpts, sink chan<- *EigenPodStorageNonBeaconChainETHReceived) (event.Subscription, error) { + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "NonBeaconChainETHReceived") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageNonBeaconChainETHReceived) + if err := _EigenPodStorage.contract.UnpackLog(event, "NonBeaconChainETHReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNonBeaconChainETHReceived is a log parse operation binding the contract event 0x6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf49. +// +// Solidity: event NonBeaconChainETHReceived(uint256 amountReceived) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseNonBeaconChainETHReceived(log types.Log) (*EigenPodStorageNonBeaconChainETHReceived, error) { + event := new(EigenPodStorageNonBeaconChainETHReceived) + if err := _EigenPodStorage.contract.UnpackLog(event, "NonBeaconChainETHReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodStorageProofSubmitterUpdatedIterator is returned from FilterProofSubmitterUpdated and is used to iterate over the raw logs and unpacked data for ProofSubmitterUpdated events raised by the EigenPodStorage contract. +type EigenPodStorageProofSubmitterUpdatedIterator struct { + Event *EigenPodStorageProofSubmitterUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageProofSubmitterUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageProofSubmitterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageProofSubmitterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageProofSubmitterUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageProofSubmitterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageProofSubmitterUpdated represents a ProofSubmitterUpdated event raised by the EigenPodStorage contract. +type EigenPodStorageProofSubmitterUpdated struct { + PrevProofSubmitter common.Address + NewProofSubmitter common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterProofSubmitterUpdated is a free log retrieval operation binding the contract event 0xfb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac. +// +// Solidity: event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterProofSubmitterUpdated(opts *bind.FilterOpts) (*EigenPodStorageProofSubmitterUpdatedIterator, error) { + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "ProofSubmitterUpdated") + if err != nil { + return nil, err + } + return &EigenPodStorageProofSubmitterUpdatedIterator{contract: _EigenPodStorage.contract, event: "ProofSubmitterUpdated", logs: logs, sub: sub}, nil +} + +// WatchProofSubmitterUpdated is a free log subscription operation binding the contract event 0xfb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac. +// +// Solidity: event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchProofSubmitterUpdated(opts *bind.WatchOpts, sink chan<- *EigenPodStorageProofSubmitterUpdated) (event.Subscription, error) { + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "ProofSubmitterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageProofSubmitterUpdated) + if err := _EigenPodStorage.contract.UnpackLog(event, "ProofSubmitterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseProofSubmitterUpdated is a log parse operation binding the contract event 0xfb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac. +// +// Solidity: event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseProofSubmitterUpdated(log types.Log) (*EigenPodStorageProofSubmitterUpdated, error) { + event := new(EigenPodStorageProofSubmitterUpdated) + if err := _EigenPodStorage.contract.UnpackLog(event, "ProofSubmitterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodStorageRestakedBeaconChainETHWithdrawnIterator is returned from FilterRestakedBeaconChainETHWithdrawn and is used to iterate over the raw logs and unpacked data for RestakedBeaconChainETHWithdrawn events raised by the EigenPodStorage contract. +type EigenPodStorageRestakedBeaconChainETHWithdrawnIterator struct { + Event *EigenPodStorageRestakedBeaconChainETHWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageRestakedBeaconChainETHWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageRestakedBeaconChainETHWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageRestakedBeaconChainETHWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageRestakedBeaconChainETHWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageRestakedBeaconChainETHWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageRestakedBeaconChainETHWithdrawn represents a RestakedBeaconChainETHWithdrawn event raised by the EigenPodStorage contract. +type EigenPodStorageRestakedBeaconChainETHWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRestakedBeaconChainETHWithdrawn is a free log retrieval operation binding the contract event 0x8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e. +// +// Solidity: event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterRestakedBeaconChainETHWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*EigenPodStorageRestakedBeaconChainETHWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "RestakedBeaconChainETHWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &EigenPodStorageRestakedBeaconChainETHWithdrawnIterator{contract: _EigenPodStorage.contract, event: "RestakedBeaconChainETHWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchRestakedBeaconChainETHWithdrawn is a free log subscription operation binding the contract event 0x8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e. +// +// Solidity: event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchRestakedBeaconChainETHWithdrawn(opts *bind.WatchOpts, sink chan<- *EigenPodStorageRestakedBeaconChainETHWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "RestakedBeaconChainETHWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageRestakedBeaconChainETHWithdrawn) + if err := _EigenPodStorage.contract.UnpackLog(event, "RestakedBeaconChainETHWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRestakedBeaconChainETHWithdrawn is a log parse operation binding the contract event 0x8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e. +// +// Solidity: event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseRestakedBeaconChainETHWithdrawn(log types.Log) (*EigenPodStorageRestakedBeaconChainETHWithdrawn, error) { + event := new(EigenPodStorageRestakedBeaconChainETHWithdrawn) + if err := _EigenPodStorage.contract.UnpackLog(event, "RestakedBeaconChainETHWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodStorageValidatorBalanceUpdatedIterator is returned from FilterValidatorBalanceUpdated and is used to iterate over the raw logs and unpacked data for ValidatorBalanceUpdated events raised by the EigenPodStorage contract. +type EigenPodStorageValidatorBalanceUpdatedIterator struct { + Event *EigenPodStorageValidatorBalanceUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageValidatorBalanceUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageValidatorBalanceUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageValidatorBalanceUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageValidatorBalanceUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageValidatorBalanceUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageValidatorBalanceUpdated represents a ValidatorBalanceUpdated event raised by the EigenPodStorage contract. +type EigenPodStorageValidatorBalanceUpdated struct { + ValidatorIndex *big.Int + BalanceTimestamp uint64 + NewValidatorBalanceGwei uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorBalanceUpdated is a free log retrieval operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. +// +// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterValidatorBalanceUpdated(opts *bind.FilterOpts) (*EigenPodStorageValidatorBalanceUpdatedIterator, error) { + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "ValidatorBalanceUpdated") + if err != nil { + return nil, err + } + return &EigenPodStorageValidatorBalanceUpdatedIterator{contract: _EigenPodStorage.contract, event: "ValidatorBalanceUpdated", logs: logs, sub: sub}, nil +} + +// WatchValidatorBalanceUpdated is a free log subscription operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. +// +// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchValidatorBalanceUpdated(opts *bind.WatchOpts, sink chan<- *EigenPodStorageValidatorBalanceUpdated) (event.Subscription, error) { + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "ValidatorBalanceUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageValidatorBalanceUpdated) + if err := _EigenPodStorage.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorBalanceUpdated is a log parse operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. +// +// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseValidatorBalanceUpdated(log types.Log) (*EigenPodStorageValidatorBalanceUpdated, error) { + event := new(EigenPodStorageValidatorBalanceUpdated) + if err := _EigenPodStorage.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodStorageValidatorCheckpointedIterator is returned from FilterValidatorCheckpointed and is used to iterate over the raw logs and unpacked data for ValidatorCheckpointed events raised by the EigenPodStorage contract. +type EigenPodStorageValidatorCheckpointedIterator struct { + Event *EigenPodStorageValidatorCheckpointed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageValidatorCheckpointedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageValidatorCheckpointed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageValidatorCheckpointed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageValidatorCheckpointedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageValidatorCheckpointedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageValidatorCheckpointed represents a ValidatorCheckpointed event raised by the EigenPodStorage contract. +type EigenPodStorageValidatorCheckpointed struct { + CheckpointTimestamp uint64 + ValidatorIndex *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorCheckpointed is a free log retrieval operation binding the contract event 0xa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f. +// +// Solidity: event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterValidatorCheckpointed(opts *bind.FilterOpts, checkpointTimestamp []uint64, validatorIndex []*big.Int) (*EigenPodStorageValidatorCheckpointedIterator, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "ValidatorCheckpointed", checkpointTimestampRule, validatorIndexRule) + if err != nil { + return nil, err + } + return &EigenPodStorageValidatorCheckpointedIterator{contract: _EigenPodStorage.contract, event: "ValidatorCheckpointed", logs: logs, sub: sub}, nil +} + +// WatchValidatorCheckpointed is a free log subscription operation binding the contract event 0xa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f. +// +// Solidity: event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchValidatorCheckpointed(opts *bind.WatchOpts, sink chan<- *EigenPodStorageValidatorCheckpointed, checkpointTimestamp []uint64, validatorIndex []*big.Int) (event.Subscription, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "ValidatorCheckpointed", checkpointTimestampRule, validatorIndexRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageValidatorCheckpointed) + if err := _EigenPodStorage.contract.UnpackLog(event, "ValidatorCheckpointed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorCheckpointed is a log parse operation binding the contract event 0xa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f. +// +// Solidity: event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseValidatorCheckpointed(log types.Log) (*EigenPodStorageValidatorCheckpointed, error) { + event := new(EigenPodStorageValidatorCheckpointed) + if err := _EigenPodStorage.contract.UnpackLog(event, "ValidatorCheckpointed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodStorageValidatorRestakedIterator is returned from FilterValidatorRestaked and is used to iterate over the raw logs and unpacked data for ValidatorRestaked events raised by the EigenPodStorage contract. +type EigenPodStorageValidatorRestakedIterator struct { + Event *EigenPodStorageValidatorRestaked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageValidatorRestakedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageValidatorRestaked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageValidatorRestaked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageValidatorRestakedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageValidatorRestakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageValidatorRestaked represents a ValidatorRestaked event raised by the EigenPodStorage contract. +type EigenPodStorageValidatorRestaked struct { + ValidatorIndex *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRestaked is a free log retrieval operation binding the contract event 0x2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449. +// +// Solidity: event ValidatorRestaked(uint40 validatorIndex) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterValidatorRestaked(opts *bind.FilterOpts) (*EigenPodStorageValidatorRestakedIterator, error) { + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "ValidatorRestaked") + if err != nil { + return nil, err + } + return &EigenPodStorageValidatorRestakedIterator{contract: _EigenPodStorage.contract, event: "ValidatorRestaked", logs: logs, sub: sub}, nil +} + +// WatchValidatorRestaked is a free log subscription operation binding the contract event 0x2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449. +// +// Solidity: event ValidatorRestaked(uint40 validatorIndex) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchValidatorRestaked(opts *bind.WatchOpts, sink chan<- *EigenPodStorageValidatorRestaked) (event.Subscription, error) { + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "ValidatorRestaked") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageValidatorRestaked) + if err := _EigenPodStorage.contract.UnpackLog(event, "ValidatorRestaked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorRestaked is a log parse operation binding the contract event 0x2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449. +// +// Solidity: event ValidatorRestaked(uint40 validatorIndex) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseValidatorRestaked(log types.Log) (*EigenPodStorageValidatorRestaked, error) { + event := new(EigenPodStorageValidatorRestaked) + if err := _EigenPodStorage.contract.UnpackLog(event, "ValidatorRestaked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EigenPodStorageValidatorWithdrawnIterator is returned from FilterValidatorWithdrawn and is used to iterate over the raw logs and unpacked data for ValidatorWithdrawn events raised by the EigenPodStorage contract. +type EigenPodStorageValidatorWithdrawnIterator struct { + Event *EigenPodStorageValidatorWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EigenPodStorageValidatorWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageValidatorWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EigenPodStorageValidatorWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EigenPodStorageValidatorWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EigenPodStorageValidatorWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EigenPodStorageValidatorWithdrawn represents a ValidatorWithdrawn event raised by the EigenPodStorage contract. +type EigenPodStorageValidatorWithdrawn struct { + CheckpointTimestamp uint64 + ValidatorIndex *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorWithdrawn is a free log retrieval operation binding the contract event 0x2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a. +// +// Solidity: event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPodStorage *EigenPodStorageFilterer) FilterValidatorWithdrawn(opts *bind.FilterOpts, checkpointTimestamp []uint64, validatorIndex []*big.Int) (*EigenPodStorageValidatorWithdrawnIterator, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _EigenPodStorage.contract.FilterLogs(opts, "ValidatorWithdrawn", checkpointTimestampRule, validatorIndexRule) + if err != nil { + return nil, err + } + return &EigenPodStorageValidatorWithdrawnIterator{contract: _EigenPodStorage.contract, event: "ValidatorWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchValidatorWithdrawn is a free log subscription operation binding the contract event 0x2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a. +// +// Solidity: event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPodStorage *EigenPodStorageFilterer) WatchValidatorWithdrawn(opts *bind.WatchOpts, sink chan<- *EigenPodStorageValidatorWithdrawn, checkpointTimestamp []uint64, validatorIndex []*big.Int) (event.Subscription, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _EigenPodStorage.contract.WatchLogs(opts, "ValidatorWithdrawn", checkpointTimestampRule, validatorIndexRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EigenPodStorageValidatorWithdrawn) + if err := _EigenPodStorage.contract.UnpackLog(event, "ValidatorWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorWithdrawn is a log parse operation binding the contract event 0x2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a. +// +// Solidity: event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_EigenPodStorage *EigenPodStorageFilterer) ParseValidatorWithdrawn(log types.Log) (*EigenPodStorageValidatorWithdrawn, error) { + event := new(EigenPodStorageValidatorWithdrawn) + if err := _EigenPodStorage.contract.UnpackLog(event, "ValidatorWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/pkg/bindings/EigenStrategy/binding.go b/pkg/bindings/EigenStrategy/binding.go index f3cd14664..2070a2d17 100644 --- a/pkg/bindings/EigenStrategy/binding.go +++ b/pkg/bindings/EigenStrategy/binding.go @@ -32,7 +32,7 @@ var ( // EigenStrategyMetaData contains all meta data concerning the EigenStrategy contract. var EigenStrategyMetaData = &bind.MetaData{ ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_strategyManager\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"EIGEN\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigen\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"newShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"explanation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_underlyingToken\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_EIGEN\",\"type\":\"address\",\"internalType\":\"contractIEigen\"},{\"name\":\"_bEIGEN\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"shares\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"sharesToUnderlying\",\"inputs\":[{\"name\":\"amountShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"sharesToUnderlyingView\",\"inputs\":[{\"name\":\"amountShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalShares\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"underlyingToShares\",\"inputs\":[{\"name\":\"amountUnderlying\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"underlyingToSharesView\",\"inputs\":[{\"name\":\"amountUnderlying\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"underlyingToken\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"userUnderlying\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"userUnderlyingView\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amountShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"ExchangeRateEmitted\",\"inputs\":[{\"name\":\"rate\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StrategyTokenSet\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIERC20\"},{\"name\":\"decimals\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001dc338038062001dc3833981016040819052620000349162000116565b6001600160a01b038116608052806200004c62000054565b505062000148565b600054610100900460ff1615620000c15760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000114576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200012957600080fd5b81516001600160a01b03811681146200014157600080fd5b9392505050565b608051611c4a62000179600039600081816101af015281816105ac01528181610ad40152610b9f0152611c4a6000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80637a8b2637116100c3578063ce7c2ac21161007c578063ce7c2ac2146102da578063d9caed12146102ed578063e3dae51c14610300578063f3e7387514610313578063fabc1cbc14610326578063fdc371ce1461033957600080fd5b80637a8b263714610260578063886f1195146102735780638c8710191461028c5780638f6a62401461029f578063ab5921e1146102b2578063c0c53b8b146102c757600080fd5b806347e7ef241161011557806347e7ef24146101e8578063485cc955146101fb578063553ca5f81461020e578063595c6a67146102215780635ac86ab7146102295780635c975abb1461025857600080fd5b806310d67a2f14610152578063136439dd146101675780632495a5991461017a57806339b70e38146101aa5780633a98ef39146101d1575b600080fd5b61016561016036600461181e565b61034c565b005b61016561017536600461183b565b610408565b60325461018d906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61018d7f000000000000000000000000000000000000000000000000000000000000000081565b6101da60335481565b6040519081526020016101a1565b6101da6101f6366004611854565b61054c565b610165610209366004611880565b610790565b6101da61021c36600461181e565b61085e565b610165610872565b6102486102373660046118c8565b6001805460ff9092161b9081161490565b60405190151581526020016101a1565b6001546101da565b6101da61026e36600461183b565b61093e565b60005461018d906201000090046001600160a01b031681565b6101da61029a36600461183b565b610989565b6101da6102ad36600461181e565b610994565b6102ba6109a2565b6040516101a19190611911565b6101656102d5366004611944565b6109c2565b6101da6102e836600461181e565b610aac565b6101656102fb36600461198f565b610b41565b6101da61030e36600461183b565b610d27565b6101da61032136600461183b565b610d60565b61016561033436600461183b565b610d6b565b60645461018d906001600160a01b031681565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561039f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c391906119d0565b6001600160a01b0316336001600160a01b0316146103fc5760405162461bcd60e51b81526004016103f3906119ed565b60405180910390fd5b61040581610ec7565b50565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610455573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104799190611a37565b6104955760405162461bcd60e51b81526004016103f390611a59565b6001548181161461050e5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016103f3565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b600180546000918291811614156105a15760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016103f3565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106195760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e6167657260448201526064016103f3565b6106238484610fcc565b60335460006106346103e883611ab7565b905060006103e86106436110e0565b61064d9190611ab7565b9050600061065b8783611acf565b9050806106688489611ae6565b6106729190611b05565b9550856106d85760405162461bcd60e51b815260206004820152602e60248201527f5374726174656779426173652e6465706f7369743a206e65775368617265732060448201526d63616e6e6f74206265207a65726f60901b60648201526084016103f3565b6106e28685611ab7565b60338190556f4b3b4ca85a86c47a098a223fffffffff101561076c5760405162461bcd60e51b815260206004820152603c60248201527f5374726174656779426173652e6465706f7369743a20746f74616c536861726560448201527f73206578636565647320604d41585f544f54414c5f534841524553600000000060648201526084016103f3565b610785826103e86033546107809190611ab7565b611152565b505050505092915050565b600054610100900460ff16158080156107b05750600054600160ff909116105b806107ca5750303b1580156107ca575060005460ff166001145b6107e65760405162461bcd60e51b81526004016103f390611b27565b6000805460ff191660011790558015610809576000805461ff0019166101001790555b61081383836111a6565b8015610859576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061086c61026e83610aac565b92915050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa1580156108bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e39190611a37565b6108ff5760405162461bcd60e51b81526004016103f390611a59565b600019600181905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000806103e86033546109519190611ab7565b905060006103e86109606110e0565b61096a9190611ab7565b9050816109778583611ae6565b6109819190611b05565b949350505050565b600061086c82610d27565b600061086c61032183610aac565b60606040518060800160405280604d8152602001611bc8604d9139905090565b600054610100900460ff16158080156109e25750600054600160ff909116105b806109fc5750303b1580156109fc575060005460ff166001145b610a185760405162461bcd60e51b81526004016103f390611b27565b6000805460ff191660011790558015610a3b576000805461ff0019166101001790555b606480546001600160a01b0319166001600160a01b038616179055610a6083836111a6565b8015610aa6576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b604051633d3f06c960e11b81526001600160a01b0382811660048301523060248301526000917f000000000000000000000000000000000000000000000000000000000000000090911690637a7e0d9290604401602060405180830381865afa158015610b1d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086c9190611b75565b6001805460029081161415610b945760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016103f3565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c0c5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e6167657260448201526064016103f3565b610c178484846112f1565b60335480831115610ca65760405162461bcd60e51b815260206004820152604d60248201527f5374726174656779426173652e77697468647261773a20616d6f756e7453686160448201527f726573206d757374206265206c657373207468616e206f7220657175616c207460648201526c6f20746f74616c53686172657360981b608482015260a4016103f3565b6000610cb46103e883611ab7565b905060006103e8610cc36110e0565b610ccd9190611ab7565b9050600082610cdc8784611ae6565b610ce69190611b05565b9050610cf28685611acf565b603355610d12610d028284611acf565b6103e86033546107809190611ab7565b610d1d88888361138c565b5050505050505050565b6000806103e8603354610d3a9190611ab7565b905060006103e8610d496110e0565b610d539190611ab7565b9050806109778386611ae6565b600061086c8261093e565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de291906119d0565b6001600160a01b0316336001600160a01b031614610e125760405162461bcd60e51b81526004016103f3906119ed565b600154198119600154191614610e905760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016103f3565b600181905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610541565b6001600160a01b038116610f555760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016103f3565b600054604080516001600160a01b03620100009093048316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6032546001600160a01b0383811691161480610ff557506064546001600160a01b038381169116145b6110675760405162461bcd60e51b815260206004820152603760248201527f456967656e53747261746567792e6465706f7369743a2043616e206f6e6c792060448201527f6465706f7369742062454947454e206f7220454947454e00000000000000000060648201526084016103f3565b6064546001600160a01b03838116911614156110dc57606454604051636f074d1f60e11b8152600481018390526001600160a01b039091169063de0e9a3e90602401600060405180830381600087803b1580156110c357600080fd5b505af11580156110d7573d6000803e3d6000fd5b505050505b5050565b6032546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611129573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114d9190611b75565b905090565b7fd2494f3479e5da49d386657c292c610b5b01df313d07c62eb0cfa49924a31be88161118684670de0b6b3a7640000611ae6565b6111909190611b05565b6040519081526020015b60405180910390a15050565b600054610100900460ff166112115760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016103f3565b603280546001600160a01b0319166001600160a01b03841617905561123781600061148d565b7f1c540707b00eb5427b6b774fc799d756516a54aee108b64b327acc55af557507603260009054906101000a90046001600160a01b0316836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d09190611b8e565b604080516001600160a01b03909316835260ff90911660208301520161119a565b6032546001600160a01b038381169116148061131a57506064546001600160a01b038381169116145b6108595760405162461bcd60e51b815260206004820152603960248201527f456967656e53747261746567792e77697468647261773a2043616e206f6e6c7960448201527f2077697468647261772062454947454e206f7220454947454e0000000000000060648201526084016103f3565b6064546001600160a01b03838116911614156114795760325460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044016020604051808303816000875af11580156113f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114199190611a37565b50606454604051630ea598cb60e41b8152600481018390526001600160a01b039091169063ea598cb090602401600060405180830381600087803b15801561146057600080fd5b505af1158015611474573d6000803e3d6000fd5b505050505b6108596001600160a01b0383168483611579565b6000546201000090046001600160a01b03161580156114b457506001600160a01b03821615155b6115365760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016103f3565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26110dc82610ec7565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649084015261085992869291600091611609918516908490611686565b80519091501561085957808060200190518101906116279190611a37565b6108595760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103f3565b6060611695848460008561169f565b90505b9392505050565b6060824710156117005760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103f3565b6001600160a01b0385163b6117575760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103f3565b600080866001600160a01b031685876040516117739190611bab565b60006040518083038185875af1925050503d80600081146117b0576040519150601f19603f3d011682016040523d82523d6000602084013e6117b5565b606091505b50915091506117c58282866117d0565b979650505050505050565b606083156117df575081611698565b8251156117ef5782518084602001fd5b8160405162461bcd60e51b81526004016103f39190611911565b6001600160a01b038116811461040557600080fd5b60006020828403121561183057600080fd5b813561169881611809565b60006020828403121561184d57600080fd5b5035919050565b6000806040838503121561186757600080fd5b823561187281611809565b946020939093013593505050565b6000806040838503121561189357600080fd5b823561189e81611809565b915060208301356118ae81611809565b809150509250929050565b60ff8116811461040557600080fd5b6000602082840312156118da57600080fd5b8135611698816118b9565b60005b838110156119005781810151838201526020016118e8565b83811115610aa65750506000910152565b60208152600082518060208401526119308160408501602087016118e5565b601f01601f19169190910160400192915050565b60008060006060848603121561195957600080fd5b833561196481611809565b9250602084013561197481611809565b9150604084013561198481611809565b809150509250925092565b6000806000606084860312156119a457600080fd5b83356119af81611809565b925060208401356119bf81611809565b929592945050506040919091013590565b6000602082840312156119e257600080fd5b815161169881611809565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611a4957600080fd5b8151801515811461169857600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115611aca57611aca611aa1565b500190565b600082821015611ae157611ae1611aa1565b500390565b6000816000190483118215151615611b0057611b00611aa1565b500290565b600082611b2257634e487b7160e01b600052601260045260246000fd5b500490565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b600060208284031215611b8757600080fd5b5051919050565b600060208284031215611ba057600080fd5b8151611698816118b9565b60008251611bbd8184602087016118e5565b919091019291505056fe4261736520537472617465677920696d706c656d656e746174696f6e20746f20696e68657269742066726f6d20666f72206d6f726520636f6d706c657820696d706c656d656e746174696f6e73a26469706673582212202074643e1c48de2f1cf7fdbbfb7ef480d5862d718f96ac97960980c6ddc2381864736f6c634300080c0033", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001dc338038062001dc3833981016040819052620000349162000116565b6001600160a01b038116608052806200004c62000054565b505062000148565b600054610100900460ff1615620000c15760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000114576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200012957600080fd5b81516001600160a01b03811681146200014157600080fd5b9392505050565b608051611c4a62000179600039600081816101af015281816105ac01528181610ad40152610b9f0152611c4a6000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80637a8b2637116100c3578063ce7c2ac21161007c578063ce7c2ac2146102da578063d9caed12146102ed578063e3dae51c14610300578063f3e7387514610313578063fabc1cbc14610326578063fdc371ce1461033957600080fd5b80637a8b263714610260578063886f1195146102735780638c8710191461028c5780638f6a62401461029f578063ab5921e1146102b2578063c0c53b8b146102c757600080fd5b806347e7ef241161011557806347e7ef24146101e8578063485cc955146101fb578063553ca5f81461020e578063595c6a67146102215780635ac86ab7146102295780635c975abb1461025857600080fd5b806310d67a2f14610152578063136439dd146101675780632495a5991461017a57806339b70e38146101aa5780633a98ef39146101d1575b600080fd5b61016561016036600461181e565b61034c565b005b61016561017536600461183b565b610408565b60325461018d906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61018d7f000000000000000000000000000000000000000000000000000000000000000081565b6101da60335481565b6040519081526020016101a1565b6101da6101f6366004611854565b61054c565b610165610209366004611880565b610790565b6101da61021c36600461181e565b61085e565b610165610872565b6102486102373660046118c8565b6001805460ff9092161b9081161490565b60405190151581526020016101a1565b6001546101da565b6101da61026e36600461183b565b61093e565b60005461018d906201000090046001600160a01b031681565b6101da61029a36600461183b565b610989565b6101da6102ad36600461181e565b610994565b6102ba6109a2565b6040516101a19190611911565b6101656102d5366004611944565b6109c2565b6101da6102e836600461181e565b610aac565b6101656102fb36600461198f565b610b41565b6101da61030e36600461183b565b610d27565b6101da61032136600461183b565b610d60565b61016561033436600461183b565b610d6b565b60645461018d906001600160a01b031681565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561039f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c391906119d0565b6001600160a01b0316336001600160a01b0316146103fc5760405162461bcd60e51b81526004016103f3906119ed565b60405180910390fd5b61040581610ec7565b50565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610455573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104799190611a37565b6104955760405162461bcd60e51b81526004016103f390611a59565b6001548181161461050e5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016103f3565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b600180546000918291811614156105a15760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016103f3565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106195760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e6167657260448201526064016103f3565b6106238484610fcc565b60335460006106346103e883611ab7565b905060006103e86106436110e0565b61064d9190611ab7565b9050600061065b8783611acf565b9050806106688489611ae6565b6106729190611b05565b9550856106d85760405162461bcd60e51b815260206004820152602e60248201527f5374726174656779426173652e6465706f7369743a206e65775368617265732060448201526d63616e6e6f74206265207a65726f60901b60648201526084016103f3565b6106e28685611ab7565b60338190556f4b3b4ca85a86c47a098a223fffffffff101561076c5760405162461bcd60e51b815260206004820152603c60248201527f5374726174656779426173652e6465706f7369743a20746f74616c536861726560448201527f73206578636565647320604d41585f544f54414c5f534841524553600000000060648201526084016103f3565b610785826103e86033546107809190611ab7565b611152565b505050505092915050565b600054610100900460ff16158080156107b05750600054600160ff909116105b806107ca5750303b1580156107ca575060005460ff166001145b6107e65760405162461bcd60e51b81526004016103f390611b27565b6000805460ff191660011790558015610809576000805461ff0019166101001790555b61081383836111a6565b8015610859576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061086c61026e83610aac565b92915050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa1580156108bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e39190611a37565b6108ff5760405162461bcd60e51b81526004016103f390611a59565b600019600181905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000806103e86033546109519190611ab7565b905060006103e86109606110e0565b61096a9190611ab7565b9050816109778583611ae6565b6109819190611b05565b949350505050565b600061086c82610d27565b600061086c61032183610aac565b60606040518060800160405280604d8152602001611bc8604d9139905090565b600054610100900460ff16158080156109e25750600054600160ff909116105b806109fc5750303b1580156109fc575060005460ff166001145b610a185760405162461bcd60e51b81526004016103f390611b27565b6000805460ff191660011790558015610a3b576000805461ff0019166101001790555b606480546001600160a01b0319166001600160a01b038616179055610a6083836111a6565b8015610aa6576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b604051633d3f06c960e11b81526001600160a01b0382811660048301523060248301526000917f000000000000000000000000000000000000000000000000000000000000000090911690637a7e0d9290604401602060405180830381865afa158015610b1d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086c9190611b75565b6001805460029081161415610b945760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016103f3565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c0c5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e6167657260448201526064016103f3565b610c178484846112f1565b60335480831115610ca65760405162461bcd60e51b815260206004820152604d60248201527f5374726174656779426173652e77697468647261773a20616d6f756e7453686160448201527f726573206d757374206265206c657373207468616e206f7220657175616c207460648201526c6f20746f74616c53686172657360981b608482015260a4016103f3565b6000610cb46103e883611ab7565b905060006103e8610cc36110e0565b610ccd9190611ab7565b9050600082610cdc8784611ae6565b610ce69190611b05565b9050610cf28685611acf565b603355610d12610d028284611acf565b6103e86033546107809190611ab7565b610d1d88888361138c565b5050505050505050565b6000806103e8603354610d3a9190611ab7565b905060006103e8610d496110e0565b610d539190611ab7565b9050806109778386611ae6565b600061086c8261093e565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de291906119d0565b6001600160a01b0316336001600160a01b031614610e125760405162461bcd60e51b81526004016103f3906119ed565b600154198119600154191614610e905760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016103f3565b600181905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610541565b6001600160a01b038116610f555760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016103f3565b600054604080516001600160a01b03620100009093048316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6032546001600160a01b0383811691161480610ff557506064546001600160a01b038381169116145b6110675760405162461bcd60e51b815260206004820152603760248201527f456967656e53747261746567792e6465706f7369743a2043616e206f6e6c792060448201527f6465706f7369742062454947454e206f7220454947454e00000000000000000060648201526084016103f3565b6064546001600160a01b03838116911614156110dc57606454604051636f074d1f60e11b8152600481018390526001600160a01b039091169063de0e9a3e90602401600060405180830381600087803b1580156110c357600080fd5b505af11580156110d7573d6000803e3d6000fd5b505050505b5050565b6032546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611129573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114d9190611b75565b905090565b7fd2494f3479e5da49d386657c292c610b5b01df313d07c62eb0cfa49924a31be88161118684670de0b6b3a7640000611ae6565b6111909190611b05565b6040519081526020015b60405180910390a15050565b600054610100900460ff166112115760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016103f3565b603280546001600160a01b0319166001600160a01b03841617905561123781600061148d565b7f1c540707b00eb5427b6b774fc799d756516a54aee108b64b327acc55af557507603260009054906101000a90046001600160a01b0316836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d09190611b8e565b604080516001600160a01b03909316835260ff90911660208301520161119a565b6032546001600160a01b038381169116148061131a57506064546001600160a01b038381169116145b6108595760405162461bcd60e51b815260206004820152603960248201527f456967656e53747261746567792e77697468647261773a2043616e206f6e6c7960448201527f2077697468647261772062454947454e206f7220454947454e0000000000000060648201526084016103f3565b6064546001600160a01b03838116911614156114795760325460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044016020604051808303816000875af11580156113f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114199190611a37565b50606454604051630ea598cb60e41b8152600481018390526001600160a01b039091169063ea598cb090602401600060405180830381600087803b15801561146057600080fd5b505af1158015611474573d6000803e3d6000fd5b505050505b6108596001600160a01b0383168483611579565b6000546201000090046001600160a01b03161580156114b457506001600160a01b03821615155b6115365760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016103f3565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26110dc82610ec7565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649084015261085992869291600091611609918516908490611686565b80519091501561085957808060200190518101906116279190611a37565b6108595760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103f3565b6060611695848460008561169f565b90505b9392505050565b6060824710156117005760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103f3565b6001600160a01b0385163b6117575760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103f3565b600080866001600160a01b031685876040516117739190611bab565b60006040518083038185875af1925050503d80600081146117b0576040519150601f19603f3d011682016040523d82523d6000602084013e6117b5565b606091505b50915091506117c58282866117d0565b979650505050505050565b606083156117df575081611698565b8251156117ef5782518084602001fd5b8160405162461bcd60e51b81526004016103f39190611911565b6001600160a01b038116811461040557600080fd5b60006020828403121561183057600080fd5b813561169881611809565b60006020828403121561184d57600080fd5b5035919050565b6000806040838503121561186757600080fd5b823561187281611809565b946020939093013593505050565b6000806040838503121561189357600080fd5b823561189e81611809565b915060208301356118ae81611809565b809150509250929050565b60ff8116811461040557600080fd5b6000602082840312156118da57600080fd5b8135611698816118b9565b60005b838110156119005781810151838201526020016118e8565b83811115610aa65750506000910152565b60208152600082518060208401526119308160408501602087016118e5565b601f01601f19169190910160400192915050565b60008060006060848603121561195957600080fd5b833561196481611809565b9250602084013561197481611809565b9150604084013561198481611809565b809150509250925092565b6000806000606084860312156119a457600080fd5b83356119af81611809565b925060208401356119bf81611809565b929592945050506040919091013590565b6000602082840312156119e257600080fd5b815161169881611809565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611a4957600080fd5b8151801515811461169857600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115611aca57611aca611aa1565b500190565b600082821015611ae157611ae1611aa1565b500390565b6000816000190483118215151615611b0057611b00611aa1565b500290565b600082611b2257634e487b7160e01b600052601260045260246000fd5b500490565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b600060208284031215611b8757600080fd5b5051919050565b600060208284031215611ba057600080fd5b8151611698816118b9565b60008251611bbd8184602087016118e5565b919091019291505056fe4261736520537472617465677920696d706c656d656e746174696f6e20746f20696e68657269742066726f6d20666f72206d6f726520636f6d706c657820696d706c656d656e746174696f6e73a26469706673582212209f0a5f3b361d82437f0c321794900a7aead1b85f77f12d7038cbafbf9ebeb3f164736f6c634300080c0033", } // EigenStrategyABI is the input ABI used to generate the binding from. diff --git a/pkg/bindings/IBeaconChainOracle/binding.go b/pkg/bindings/IBeaconChainOracle/binding.go deleted file mode 100644 index f46878adf..000000000 --- a/pkg/bindings/IBeaconChainOracle/binding.go +++ /dev/null @@ -1,212 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package IBeaconChainOracle - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// IBeaconChainOracleMetaData contains all meta data concerning the IBeaconChainOracle contract. -var IBeaconChainOracleMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"function\",\"name\":\"timestampToBlockRoot\",\"inputs\":[{\"name\":\"timestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"}]", -} - -// IBeaconChainOracleABI is the input ABI used to generate the binding from. -// Deprecated: Use IBeaconChainOracleMetaData.ABI instead. -var IBeaconChainOracleABI = IBeaconChainOracleMetaData.ABI - -// IBeaconChainOracle is an auto generated Go binding around an Ethereum contract. -type IBeaconChainOracle struct { - IBeaconChainOracleCaller // Read-only binding to the contract - IBeaconChainOracleTransactor // Write-only binding to the contract - IBeaconChainOracleFilterer // Log filterer for contract events -} - -// IBeaconChainOracleCaller is an auto generated read-only Go binding around an Ethereum contract. -type IBeaconChainOracleCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// IBeaconChainOracleTransactor is an auto generated write-only Go binding around an Ethereum contract. -type IBeaconChainOracleTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// IBeaconChainOracleFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type IBeaconChainOracleFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// IBeaconChainOracleSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type IBeaconChainOracleSession struct { - Contract *IBeaconChainOracle // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// IBeaconChainOracleCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type IBeaconChainOracleCallerSession struct { - Contract *IBeaconChainOracleCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// IBeaconChainOracleTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type IBeaconChainOracleTransactorSession struct { - Contract *IBeaconChainOracleTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// IBeaconChainOracleRaw is an auto generated low-level Go binding around an Ethereum contract. -type IBeaconChainOracleRaw struct { - Contract *IBeaconChainOracle // Generic contract binding to access the raw methods on -} - -// IBeaconChainOracleCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type IBeaconChainOracleCallerRaw struct { - Contract *IBeaconChainOracleCaller // Generic read-only contract binding to access the raw methods on -} - -// IBeaconChainOracleTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type IBeaconChainOracleTransactorRaw struct { - Contract *IBeaconChainOracleTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewIBeaconChainOracle creates a new instance of IBeaconChainOracle, bound to a specific deployed contract. -func NewIBeaconChainOracle(address common.Address, backend bind.ContractBackend) (*IBeaconChainOracle, error) { - contract, err := bindIBeaconChainOracle(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &IBeaconChainOracle{IBeaconChainOracleCaller: IBeaconChainOracleCaller{contract: contract}, IBeaconChainOracleTransactor: IBeaconChainOracleTransactor{contract: contract}, IBeaconChainOracleFilterer: IBeaconChainOracleFilterer{contract: contract}}, nil -} - -// NewIBeaconChainOracleCaller creates a new read-only instance of IBeaconChainOracle, bound to a specific deployed contract. -func NewIBeaconChainOracleCaller(address common.Address, caller bind.ContractCaller) (*IBeaconChainOracleCaller, error) { - contract, err := bindIBeaconChainOracle(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &IBeaconChainOracleCaller{contract: contract}, nil -} - -// NewIBeaconChainOracleTransactor creates a new write-only instance of IBeaconChainOracle, bound to a specific deployed contract. -func NewIBeaconChainOracleTransactor(address common.Address, transactor bind.ContractTransactor) (*IBeaconChainOracleTransactor, error) { - contract, err := bindIBeaconChainOracle(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &IBeaconChainOracleTransactor{contract: contract}, nil -} - -// NewIBeaconChainOracleFilterer creates a new log filterer instance of IBeaconChainOracle, bound to a specific deployed contract. -func NewIBeaconChainOracleFilterer(address common.Address, filterer bind.ContractFilterer) (*IBeaconChainOracleFilterer, error) { - contract, err := bindIBeaconChainOracle(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &IBeaconChainOracleFilterer{contract: contract}, nil -} - -// bindIBeaconChainOracle binds a generic wrapper to an already deployed contract. -func bindIBeaconChainOracle(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := IBeaconChainOracleMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_IBeaconChainOracle *IBeaconChainOracleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IBeaconChainOracle.Contract.IBeaconChainOracleCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_IBeaconChainOracle *IBeaconChainOracleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IBeaconChainOracle.Contract.IBeaconChainOracleTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_IBeaconChainOracle *IBeaconChainOracleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IBeaconChainOracle.Contract.IBeaconChainOracleTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_IBeaconChainOracle *IBeaconChainOracleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IBeaconChainOracle.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_IBeaconChainOracle *IBeaconChainOracleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IBeaconChainOracle.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_IBeaconChainOracle *IBeaconChainOracleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IBeaconChainOracle.Contract.contract.Transact(opts, method, params...) -} - -// TimestampToBlockRoot is a free data retrieval call binding the contract method 0x643599f2. -// -// Solidity: function timestampToBlockRoot(uint256 timestamp) view returns(bytes32) -func (_IBeaconChainOracle *IBeaconChainOracleCaller) TimestampToBlockRoot(opts *bind.CallOpts, timestamp *big.Int) ([32]byte, error) { - var out []interface{} - err := _IBeaconChainOracle.contract.Call(opts, &out, "timestampToBlockRoot", timestamp) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// TimestampToBlockRoot is a free data retrieval call binding the contract method 0x643599f2. -// -// Solidity: function timestampToBlockRoot(uint256 timestamp) view returns(bytes32) -func (_IBeaconChainOracle *IBeaconChainOracleSession) TimestampToBlockRoot(timestamp *big.Int) ([32]byte, error) { - return _IBeaconChainOracle.Contract.TimestampToBlockRoot(&_IBeaconChainOracle.CallOpts, timestamp) -} - -// TimestampToBlockRoot is a free data retrieval call binding the contract method 0x643599f2. -// -// Solidity: function timestampToBlockRoot(uint256 timestamp) view returns(bytes32) -func (_IBeaconChainOracle *IBeaconChainOracleCallerSession) TimestampToBlockRoot(timestamp *big.Int) ([32]byte, error) { - return _IBeaconChainOracle.Contract.TimestampToBlockRoot(&_IBeaconChainOracle.CallOpts, timestamp) -} diff --git a/pkg/bindings/IDelayedWithdrawalRouter/binding.go b/pkg/bindings/IDelayedWithdrawalRouter/binding.go deleted file mode 100644 index 86d4473b4..000000000 --- a/pkg/bindings/IDelayedWithdrawalRouter/binding.go +++ /dev/null @@ -1,902 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package IDelayedWithdrawalRouter - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// IDelayedWithdrawalRouterDelayedWithdrawal is an auto generated low-level Go binding around an user-defined struct. -type IDelayedWithdrawalRouterDelayedWithdrawal struct { - Amount *big.Int - BlockCreated uint32 -} - -// IDelayedWithdrawalRouterUserDelayedWithdrawals is an auto generated low-level Go binding around an user-defined struct. -type IDelayedWithdrawalRouterUserDelayedWithdrawals struct { - DelayedWithdrawalsCompleted *big.Int - DelayedWithdrawals []IDelayedWithdrawalRouterDelayedWithdrawal -} - -// IDelayedWithdrawalRouterMetaData contains all meta data concerning the IDelayedWithdrawalRouter contract. -var IDelayedWithdrawalRouterMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"function\",\"name\":\"canClaimDelayedWithdrawal\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDelayedWithdrawals\",\"inputs\":[{\"name\":\"maxNumberOfWithdrawalsToClaim\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"claimDelayedWithdrawals\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"maxNumberOfWithdrawalsToClaim\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createDelayedWithdrawal\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getClaimableUserDelayedWithdrawals\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"structIDelayedWithdrawalRouter.DelayedWithdrawal[]\",\"components\":[{\"name\":\"amount\",\"type\":\"uint224\",\"internalType\":\"uint224\"},{\"name\":\"blockCreated\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getUserDelayedWithdrawals\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"structIDelayedWithdrawalRouter.DelayedWithdrawal[]\",\"components\":[{\"name\":\"amount\",\"type\":\"uint224\",\"internalType\":\"uint224\"},{\"name\":\"blockCreated\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setWithdrawalDelayBlocks\",\"inputs\":[{\"name\":\"newValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"userDelayedWithdrawalByIndex\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIDelayedWithdrawalRouter.DelayedWithdrawal\",\"components\":[{\"name\":\"amount\",\"type\":\"uint224\",\"internalType\":\"uint224\"},{\"name\":\"blockCreated\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"userWithdrawals\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIDelayedWithdrawalRouter.UserDelayedWithdrawals\",\"components\":[{\"name\":\"delayedWithdrawalsCompleted\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"delayedWithdrawals\",\"type\":\"tuple[]\",\"internalType\":\"structIDelayedWithdrawalRouter.DelayedWithdrawal[]\",\"components\":[{\"name\":\"amount\",\"type\":\"uint224\",\"internalType\":\"uint224\"},{\"name\":\"blockCreated\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"userWithdrawalsLength\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdrawalDelayBlocks\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"DelayedWithdrawalCreated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelayedWithdrawalsClaimed\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amountClaimed\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"delayedWithdrawalsCompleted\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalDelayBlocksSet\",\"inputs\":[{\"name\":\"previousValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", -} - -// IDelayedWithdrawalRouterABI is the input ABI used to generate the binding from. -// Deprecated: Use IDelayedWithdrawalRouterMetaData.ABI instead. -var IDelayedWithdrawalRouterABI = IDelayedWithdrawalRouterMetaData.ABI - -// IDelayedWithdrawalRouter is an auto generated Go binding around an Ethereum contract. -type IDelayedWithdrawalRouter struct { - IDelayedWithdrawalRouterCaller // Read-only binding to the contract - IDelayedWithdrawalRouterTransactor // Write-only binding to the contract - IDelayedWithdrawalRouterFilterer // Log filterer for contract events -} - -// IDelayedWithdrawalRouterCaller is an auto generated read-only Go binding around an Ethereum contract. -type IDelayedWithdrawalRouterCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// IDelayedWithdrawalRouterTransactor is an auto generated write-only Go binding around an Ethereum contract. -type IDelayedWithdrawalRouterTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// IDelayedWithdrawalRouterFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type IDelayedWithdrawalRouterFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// IDelayedWithdrawalRouterSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type IDelayedWithdrawalRouterSession struct { - Contract *IDelayedWithdrawalRouter // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// IDelayedWithdrawalRouterCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type IDelayedWithdrawalRouterCallerSession struct { - Contract *IDelayedWithdrawalRouterCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// IDelayedWithdrawalRouterTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type IDelayedWithdrawalRouterTransactorSession struct { - Contract *IDelayedWithdrawalRouterTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// IDelayedWithdrawalRouterRaw is an auto generated low-level Go binding around an Ethereum contract. -type IDelayedWithdrawalRouterRaw struct { - Contract *IDelayedWithdrawalRouter // Generic contract binding to access the raw methods on -} - -// IDelayedWithdrawalRouterCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type IDelayedWithdrawalRouterCallerRaw struct { - Contract *IDelayedWithdrawalRouterCaller // Generic read-only contract binding to access the raw methods on -} - -// IDelayedWithdrawalRouterTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type IDelayedWithdrawalRouterTransactorRaw struct { - Contract *IDelayedWithdrawalRouterTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewIDelayedWithdrawalRouter creates a new instance of IDelayedWithdrawalRouter, bound to a specific deployed contract. -func NewIDelayedWithdrawalRouter(address common.Address, backend bind.ContractBackend) (*IDelayedWithdrawalRouter, error) { - contract, err := bindIDelayedWithdrawalRouter(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &IDelayedWithdrawalRouter{IDelayedWithdrawalRouterCaller: IDelayedWithdrawalRouterCaller{contract: contract}, IDelayedWithdrawalRouterTransactor: IDelayedWithdrawalRouterTransactor{contract: contract}, IDelayedWithdrawalRouterFilterer: IDelayedWithdrawalRouterFilterer{contract: contract}}, nil -} - -// NewIDelayedWithdrawalRouterCaller creates a new read-only instance of IDelayedWithdrawalRouter, bound to a specific deployed contract. -func NewIDelayedWithdrawalRouterCaller(address common.Address, caller bind.ContractCaller) (*IDelayedWithdrawalRouterCaller, error) { - contract, err := bindIDelayedWithdrawalRouter(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &IDelayedWithdrawalRouterCaller{contract: contract}, nil -} - -// NewIDelayedWithdrawalRouterTransactor creates a new write-only instance of IDelayedWithdrawalRouter, bound to a specific deployed contract. -func NewIDelayedWithdrawalRouterTransactor(address common.Address, transactor bind.ContractTransactor) (*IDelayedWithdrawalRouterTransactor, error) { - contract, err := bindIDelayedWithdrawalRouter(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &IDelayedWithdrawalRouterTransactor{contract: contract}, nil -} - -// NewIDelayedWithdrawalRouterFilterer creates a new log filterer instance of IDelayedWithdrawalRouter, bound to a specific deployed contract. -func NewIDelayedWithdrawalRouterFilterer(address common.Address, filterer bind.ContractFilterer) (*IDelayedWithdrawalRouterFilterer, error) { - contract, err := bindIDelayedWithdrawalRouter(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &IDelayedWithdrawalRouterFilterer{contract: contract}, nil -} - -// bindIDelayedWithdrawalRouter binds a generic wrapper to an already deployed contract. -func bindIDelayedWithdrawalRouter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := IDelayedWithdrawalRouterMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IDelayedWithdrawalRouter.Contract.IDelayedWithdrawalRouterCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.IDelayedWithdrawalRouterTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.IDelayedWithdrawalRouterTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IDelayedWithdrawalRouter.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.contract.Transact(opts, method, params...) -} - -// CanClaimDelayedWithdrawal is a free data retrieval call binding the contract method 0x75608896. -// -// Solidity: function canClaimDelayedWithdrawal(address user, uint256 index) view returns(bool) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCaller) CanClaimDelayedWithdrawal(opts *bind.CallOpts, user common.Address, index *big.Int) (bool, error) { - var out []interface{} - err := _IDelayedWithdrawalRouter.contract.Call(opts, &out, "canClaimDelayedWithdrawal", user, index) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// CanClaimDelayedWithdrawal is a free data retrieval call binding the contract method 0x75608896. -// -// Solidity: function canClaimDelayedWithdrawal(address user, uint256 index) view returns(bool) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) CanClaimDelayedWithdrawal(user common.Address, index *big.Int) (bool, error) { - return _IDelayedWithdrawalRouter.Contract.CanClaimDelayedWithdrawal(&_IDelayedWithdrawalRouter.CallOpts, user, index) -} - -// CanClaimDelayedWithdrawal is a free data retrieval call binding the contract method 0x75608896. -// -// Solidity: function canClaimDelayedWithdrawal(address user, uint256 index) view returns(bool) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCallerSession) CanClaimDelayedWithdrawal(user common.Address, index *big.Int) (bool, error) { - return _IDelayedWithdrawalRouter.Contract.CanClaimDelayedWithdrawal(&_IDelayedWithdrawalRouter.CallOpts, user, index) -} - -// GetClaimableUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x1f39d87f. -// -// Solidity: function getClaimableUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCaller) GetClaimableUserDelayedWithdrawals(opts *bind.CallOpts, user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - var out []interface{} - err := _IDelayedWithdrawalRouter.contract.Call(opts, &out, "getClaimableUserDelayedWithdrawals", user) - - if err != nil { - return *new([]IDelayedWithdrawalRouterDelayedWithdrawal), err - } - - out0 := *abi.ConvertType(out[0], new([]IDelayedWithdrawalRouterDelayedWithdrawal)).(*[]IDelayedWithdrawalRouterDelayedWithdrawal) - - return out0, err - -} - -// GetClaimableUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x1f39d87f. -// -// Solidity: function getClaimableUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) GetClaimableUserDelayedWithdrawals(user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _IDelayedWithdrawalRouter.Contract.GetClaimableUserDelayedWithdrawals(&_IDelayedWithdrawalRouter.CallOpts, user) -} - -// GetClaimableUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x1f39d87f. -// -// Solidity: function getClaimableUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCallerSession) GetClaimableUserDelayedWithdrawals(user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _IDelayedWithdrawalRouter.Contract.GetClaimableUserDelayedWithdrawals(&_IDelayedWithdrawalRouter.CallOpts, user) -} - -// GetUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x3e1de008. -// -// Solidity: function getUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCaller) GetUserDelayedWithdrawals(opts *bind.CallOpts, user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - var out []interface{} - err := _IDelayedWithdrawalRouter.contract.Call(opts, &out, "getUserDelayedWithdrawals", user) - - if err != nil { - return *new([]IDelayedWithdrawalRouterDelayedWithdrawal), err - } - - out0 := *abi.ConvertType(out[0], new([]IDelayedWithdrawalRouterDelayedWithdrawal)).(*[]IDelayedWithdrawalRouterDelayedWithdrawal) - - return out0, err - -} - -// GetUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x3e1de008. -// -// Solidity: function getUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) GetUserDelayedWithdrawals(user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _IDelayedWithdrawalRouter.Contract.GetUserDelayedWithdrawals(&_IDelayedWithdrawalRouter.CallOpts, user) -} - -// GetUserDelayedWithdrawals is a free data retrieval call binding the contract method 0x3e1de008. -// -// Solidity: function getUserDelayedWithdrawals(address user) view returns((uint224,uint32)[]) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCallerSession) GetUserDelayedWithdrawals(user common.Address) ([]IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _IDelayedWithdrawalRouter.Contract.GetUserDelayedWithdrawals(&_IDelayedWithdrawalRouter.CallOpts, user) -} - -// UserDelayedWithdrawalByIndex is a free data retrieval call binding the contract method 0x85594e58. -// -// Solidity: function userDelayedWithdrawalByIndex(address user, uint256 index) view returns((uint224,uint32)) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCaller) UserDelayedWithdrawalByIndex(opts *bind.CallOpts, user common.Address, index *big.Int) (IDelayedWithdrawalRouterDelayedWithdrawal, error) { - var out []interface{} - err := _IDelayedWithdrawalRouter.contract.Call(opts, &out, "userDelayedWithdrawalByIndex", user, index) - - if err != nil { - return *new(IDelayedWithdrawalRouterDelayedWithdrawal), err - } - - out0 := *abi.ConvertType(out[0], new(IDelayedWithdrawalRouterDelayedWithdrawal)).(*IDelayedWithdrawalRouterDelayedWithdrawal) - - return out0, err - -} - -// UserDelayedWithdrawalByIndex is a free data retrieval call binding the contract method 0x85594e58. -// -// Solidity: function userDelayedWithdrawalByIndex(address user, uint256 index) view returns((uint224,uint32)) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) UserDelayedWithdrawalByIndex(user common.Address, index *big.Int) (IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _IDelayedWithdrawalRouter.Contract.UserDelayedWithdrawalByIndex(&_IDelayedWithdrawalRouter.CallOpts, user, index) -} - -// UserDelayedWithdrawalByIndex is a free data retrieval call binding the contract method 0x85594e58. -// -// Solidity: function userDelayedWithdrawalByIndex(address user, uint256 index) view returns((uint224,uint32)) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCallerSession) UserDelayedWithdrawalByIndex(user common.Address, index *big.Int) (IDelayedWithdrawalRouterDelayedWithdrawal, error) { - return _IDelayedWithdrawalRouter.Contract.UserDelayedWithdrawalByIndex(&_IDelayedWithdrawalRouter.CallOpts, user, index) -} - -// UserWithdrawals is a free data retrieval call binding the contract method 0xecb7cb1b. -// -// Solidity: function userWithdrawals(address user) view returns((uint256,(uint224,uint32)[])) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCaller) UserWithdrawals(opts *bind.CallOpts, user common.Address) (IDelayedWithdrawalRouterUserDelayedWithdrawals, error) { - var out []interface{} - err := _IDelayedWithdrawalRouter.contract.Call(opts, &out, "userWithdrawals", user) - - if err != nil { - return *new(IDelayedWithdrawalRouterUserDelayedWithdrawals), err - } - - out0 := *abi.ConvertType(out[0], new(IDelayedWithdrawalRouterUserDelayedWithdrawals)).(*IDelayedWithdrawalRouterUserDelayedWithdrawals) - - return out0, err - -} - -// UserWithdrawals is a free data retrieval call binding the contract method 0xecb7cb1b. -// -// Solidity: function userWithdrawals(address user) view returns((uint256,(uint224,uint32)[])) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) UserWithdrawals(user common.Address) (IDelayedWithdrawalRouterUserDelayedWithdrawals, error) { - return _IDelayedWithdrawalRouter.Contract.UserWithdrawals(&_IDelayedWithdrawalRouter.CallOpts, user) -} - -// UserWithdrawals is a free data retrieval call binding the contract method 0xecb7cb1b. -// -// Solidity: function userWithdrawals(address user) view returns((uint256,(uint224,uint32)[])) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCallerSession) UserWithdrawals(user common.Address) (IDelayedWithdrawalRouterUserDelayedWithdrawals, error) { - return _IDelayedWithdrawalRouter.Contract.UserWithdrawals(&_IDelayedWithdrawalRouter.CallOpts, user) -} - -// UserWithdrawalsLength is a free data retrieval call binding the contract method 0xe4f4f887. -// -// Solidity: function userWithdrawalsLength(address user) view returns(uint256) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCaller) UserWithdrawalsLength(opts *bind.CallOpts, user common.Address) (*big.Int, error) { - var out []interface{} - err := _IDelayedWithdrawalRouter.contract.Call(opts, &out, "userWithdrawalsLength", user) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// UserWithdrawalsLength is a free data retrieval call binding the contract method 0xe4f4f887. -// -// Solidity: function userWithdrawalsLength(address user) view returns(uint256) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) UserWithdrawalsLength(user common.Address) (*big.Int, error) { - return _IDelayedWithdrawalRouter.Contract.UserWithdrawalsLength(&_IDelayedWithdrawalRouter.CallOpts, user) -} - -// UserWithdrawalsLength is a free data retrieval call binding the contract method 0xe4f4f887. -// -// Solidity: function userWithdrawalsLength(address user) view returns(uint256) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCallerSession) UserWithdrawalsLength(user common.Address) (*big.Int, error) { - return _IDelayedWithdrawalRouter.Contract.UserWithdrawalsLength(&_IDelayedWithdrawalRouter.CallOpts, user) -} - -// WithdrawalDelayBlocks is a free data retrieval call binding the contract method 0x50f73e7c. -// -// Solidity: function withdrawalDelayBlocks() view returns(uint256) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCaller) WithdrawalDelayBlocks(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _IDelayedWithdrawalRouter.contract.Call(opts, &out, "withdrawalDelayBlocks") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// WithdrawalDelayBlocks is a free data retrieval call binding the contract method 0x50f73e7c. -// -// Solidity: function withdrawalDelayBlocks() view returns(uint256) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) WithdrawalDelayBlocks() (*big.Int, error) { - return _IDelayedWithdrawalRouter.Contract.WithdrawalDelayBlocks(&_IDelayedWithdrawalRouter.CallOpts) -} - -// WithdrawalDelayBlocks is a free data retrieval call binding the contract method 0x50f73e7c. -// -// Solidity: function withdrawalDelayBlocks() view returns(uint256) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterCallerSession) WithdrawalDelayBlocks() (*big.Int, error) { - return _IDelayedWithdrawalRouter.Contract.WithdrawalDelayBlocks(&_IDelayedWithdrawalRouter.CallOpts) -} - -// ClaimDelayedWithdrawals is a paid mutator transaction binding the contract method 0xd44e1b76. -// -// Solidity: function claimDelayedWithdrawals(uint256 maxNumberOfWithdrawalsToClaim) returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactor) ClaimDelayedWithdrawals(opts *bind.TransactOpts, maxNumberOfWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.contract.Transact(opts, "claimDelayedWithdrawals", maxNumberOfWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals is a paid mutator transaction binding the contract method 0xd44e1b76. -// -// Solidity: function claimDelayedWithdrawals(uint256 maxNumberOfWithdrawalsToClaim) returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) ClaimDelayedWithdrawals(maxNumberOfWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.ClaimDelayedWithdrawals(&_IDelayedWithdrawalRouter.TransactOpts, maxNumberOfWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals is a paid mutator transaction binding the contract method 0xd44e1b76. -// -// Solidity: function claimDelayedWithdrawals(uint256 maxNumberOfWithdrawalsToClaim) returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactorSession) ClaimDelayedWithdrawals(maxNumberOfWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.ClaimDelayedWithdrawals(&_IDelayedWithdrawalRouter.TransactOpts, maxNumberOfWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals0 is a paid mutator transaction binding the contract method 0xe5db06c0. -// -// Solidity: function claimDelayedWithdrawals(address recipient, uint256 maxNumberOfWithdrawalsToClaim) returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactor) ClaimDelayedWithdrawals0(opts *bind.TransactOpts, recipient common.Address, maxNumberOfWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.contract.Transact(opts, "claimDelayedWithdrawals0", recipient, maxNumberOfWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals0 is a paid mutator transaction binding the contract method 0xe5db06c0. -// -// Solidity: function claimDelayedWithdrawals(address recipient, uint256 maxNumberOfWithdrawalsToClaim) returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) ClaimDelayedWithdrawals0(recipient common.Address, maxNumberOfWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.ClaimDelayedWithdrawals0(&_IDelayedWithdrawalRouter.TransactOpts, recipient, maxNumberOfWithdrawalsToClaim) -} - -// ClaimDelayedWithdrawals0 is a paid mutator transaction binding the contract method 0xe5db06c0. -// -// Solidity: function claimDelayedWithdrawals(address recipient, uint256 maxNumberOfWithdrawalsToClaim) returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactorSession) ClaimDelayedWithdrawals0(recipient common.Address, maxNumberOfWithdrawalsToClaim *big.Int) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.ClaimDelayedWithdrawals0(&_IDelayedWithdrawalRouter.TransactOpts, recipient, maxNumberOfWithdrawalsToClaim) -} - -// CreateDelayedWithdrawal is a paid mutator transaction binding the contract method 0xc0db354c. -// -// Solidity: function createDelayedWithdrawal(address podOwner, address recipient) payable returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactor) CreateDelayedWithdrawal(opts *bind.TransactOpts, podOwner common.Address, recipient common.Address) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.contract.Transact(opts, "createDelayedWithdrawal", podOwner, recipient) -} - -// CreateDelayedWithdrawal is a paid mutator transaction binding the contract method 0xc0db354c. -// -// Solidity: function createDelayedWithdrawal(address podOwner, address recipient) payable returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) CreateDelayedWithdrawal(podOwner common.Address, recipient common.Address) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.CreateDelayedWithdrawal(&_IDelayedWithdrawalRouter.TransactOpts, podOwner, recipient) -} - -// CreateDelayedWithdrawal is a paid mutator transaction binding the contract method 0xc0db354c. -// -// Solidity: function createDelayedWithdrawal(address podOwner, address recipient) payable returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactorSession) CreateDelayedWithdrawal(podOwner common.Address, recipient common.Address) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.CreateDelayedWithdrawal(&_IDelayedWithdrawalRouter.TransactOpts, podOwner, recipient) -} - -// SetWithdrawalDelayBlocks is a paid mutator transaction binding the contract method 0x4d50f9a4. -// -// Solidity: function setWithdrawalDelayBlocks(uint256 newValue) returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactor) SetWithdrawalDelayBlocks(opts *bind.TransactOpts, newValue *big.Int) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.contract.Transact(opts, "setWithdrawalDelayBlocks", newValue) -} - -// SetWithdrawalDelayBlocks is a paid mutator transaction binding the contract method 0x4d50f9a4. -// -// Solidity: function setWithdrawalDelayBlocks(uint256 newValue) returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterSession) SetWithdrawalDelayBlocks(newValue *big.Int) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.SetWithdrawalDelayBlocks(&_IDelayedWithdrawalRouter.TransactOpts, newValue) -} - -// SetWithdrawalDelayBlocks is a paid mutator transaction binding the contract method 0x4d50f9a4. -// -// Solidity: function setWithdrawalDelayBlocks(uint256 newValue) returns() -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterTransactorSession) SetWithdrawalDelayBlocks(newValue *big.Int) (*types.Transaction, error) { - return _IDelayedWithdrawalRouter.Contract.SetWithdrawalDelayBlocks(&_IDelayedWithdrawalRouter.TransactOpts, newValue) -} - -// IDelayedWithdrawalRouterDelayedWithdrawalCreatedIterator is returned from FilterDelayedWithdrawalCreated and is used to iterate over the raw logs and unpacked data for DelayedWithdrawalCreated events raised by the IDelayedWithdrawalRouter contract. -type IDelayedWithdrawalRouterDelayedWithdrawalCreatedIterator struct { - Event *IDelayedWithdrawalRouterDelayedWithdrawalCreated // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *IDelayedWithdrawalRouterDelayedWithdrawalCreatedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(IDelayedWithdrawalRouterDelayedWithdrawalCreated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(IDelayedWithdrawalRouterDelayedWithdrawalCreated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *IDelayedWithdrawalRouterDelayedWithdrawalCreatedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *IDelayedWithdrawalRouterDelayedWithdrawalCreatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// IDelayedWithdrawalRouterDelayedWithdrawalCreated represents a DelayedWithdrawalCreated event raised by the IDelayedWithdrawalRouter contract. -type IDelayedWithdrawalRouterDelayedWithdrawalCreated struct { - PodOwner common.Address - Recipient common.Address - Amount *big.Int - Index *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDelayedWithdrawalCreated is a free log retrieval operation binding the contract event 0xb8f1b14c7caf74150801dcc9bc18d575cbeaf5b421943497e409df92c92e0f59. -// -// Solidity: event DelayedWithdrawalCreated(address podOwner, address recipient, uint256 amount, uint256 index) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterFilterer) FilterDelayedWithdrawalCreated(opts *bind.FilterOpts) (*IDelayedWithdrawalRouterDelayedWithdrawalCreatedIterator, error) { - - logs, sub, err := _IDelayedWithdrawalRouter.contract.FilterLogs(opts, "DelayedWithdrawalCreated") - if err != nil { - return nil, err - } - return &IDelayedWithdrawalRouterDelayedWithdrawalCreatedIterator{contract: _IDelayedWithdrawalRouter.contract, event: "DelayedWithdrawalCreated", logs: logs, sub: sub}, nil -} - -// WatchDelayedWithdrawalCreated is a free log subscription operation binding the contract event 0xb8f1b14c7caf74150801dcc9bc18d575cbeaf5b421943497e409df92c92e0f59. -// -// Solidity: event DelayedWithdrawalCreated(address podOwner, address recipient, uint256 amount, uint256 index) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterFilterer) WatchDelayedWithdrawalCreated(opts *bind.WatchOpts, sink chan<- *IDelayedWithdrawalRouterDelayedWithdrawalCreated) (event.Subscription, error) { - - logs, sub, err := _IDelayedWithdrawalRouter.contract.WatchLogs(opts, "DelayedWithdrawalCreated") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(IDelayedWithdrawalRouterDelayedWithdrawalCreated) - if err := _IDelayedWithdrawalRouter.contract.UnpackLog(event, "DelayedWithdrawalCreated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseDelayedWithdrawalCreated is a log parse operation binding the contract event 0xb8f1b14c7caf74150801dcc9bc18d575cbeaf5b421943497e409df92c92e0f59. -// -// Solidity: event DelayedWithdrawalCreated(address podOwner, address recipient, uint256 amount, uint256 index) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterFilterer) ParseDelayedWithdrawalCreated(log types.Log) (*IDelayedWithdrawalRouterDelayedWithdrawalCreated, error) { - event := new(IDelayedWithdrawalRouterDelayedWithdrawalCreated) - if err := _IDelayedWithdrawalRouter.contract.UnpackLog(event, "DelayedWithdrawalCreated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// IDelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator is returned from FilterDelayedWithdrawalsClaimed and is used to iterate over the raw logs and unpacked data for DelayedWithdrawalsClaimed events raised by the IDelayedWithdrawalRouter contract. -type IDelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator struct { - Event *IDelayedWithdrawalRouterDelayedWithdrawalsClaimed // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *IDelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(IDelayedWithdrawalRouterDelayedWithdrawalsClaimed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(IDelayedWithdrawalRouterDelayedWithdrawalsClaimed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *IDelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *IDelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// IDelayedWithdrawalRouterDelayedWithdrawalsClaimed represents a DelayedWithdrawalsClaimed event raised by the IDelayedWithdrawalRouter contract. -type IDelayedWithdrawalRouterDelayedWithdrawalsClaimed struct { - Recipient common.Address - AmountClaimed *big.Int - DelayedWithdrawalsCompleted *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDelayedWithdrawalsClaimed is a free log retrieval operation binding the contract event 0x6b7151500bd0b5cc211bcc47b3029831b769004df4549e8e1c9a69da05bb0943. -// -// Solidity: event DelayedWithdrawalsClaimed(address recipient, uint256 amountClaimed, uint256 delayedWithdrawalsCompleted) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterFilterer) FilterDelayedWithdrawalsClaimed(opts *bind.FilterOpts) (*IDelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator, error) { - - logs, sub, err := _IDelayedWithdrawalRouter.contract.FilterLogs(opts, "DelayedWithdrawalsClaimed") - if err != nil { - return nil, err - } - return &IDelayedWithdrawalRouterDelayedWithdrawalsClaimedIterator{contract: _IDelayedWithdrawalRouter.contract, event: "DelayedWithdrawalsClaimed", logs: logs, sub: sub}, nil -} - -// WatchDelayedWithdrawalsClaimed is a free log subscription operation binding the contract event 0x6b7151500bd0b5cc211bcc47b3029831b769004df4549e8e1c9a69da05bb0943. -// -// Solidity: event DelayedWithdrawalsClaimed(address recipient, uint256 amountClaimed, uint256 delayedWithdrawalsCompleted) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterFilterer) WatchDelayedWithdrawalsClaimed(opts *bind.WatchOpts, sink chan<- *IDelayedWithdrawalRouterDelayedWithdrawalsClaimed) (event.Subscription, error) { - - logs, sub, err := _IDelayedWithdrawalRouter.contract.WatchLogs(opts, "DelayedWithdrawalsClaimed") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(IDelayedWithdrawalRouterDelayedWithdrawalsClaimed) - if err := _IDelayedWithdrawalRouter.contract.UnpackLog(event, "DelayedWithdrawalsClaimed", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseDelayedWithdrawalsClaimed is a log parse operation binding the contract event 0x6b7151500bd0b5cc211bcc47b3029831b769004df4549e8e1c9a69da05bb0943. -// -// Solidity: event DelayedWithdrawalsClaimed(address recipient, uint256 amountClaimed, uint256 delayedWithdrawalsCompleted) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterFilterer) ParseDelayedWithdrawalsClaimed(log types.Log) (*IDelayedWithdrawalRouterDelayedWithdrawalsClaimed, error) { - event := new(IDelayedWithdrawalRouterDelayedWithdrawalsClaimed) - if err := _IDelayedWithdrawalRouter.contract.UnpackLog(event, "DelayedWithdrawalsClaimed", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// IDelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator is returned from FilterWithdrawalDelayBlocksSet and is used to iterate over the raw logs and unpacked data for WithdrawalDelayBlocksSet events raised by the IDelayedWithdrawalRouter contract. -type IDelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator struct { - Event *IDelayedWithdrawalRouterWithdrawalDelayBlocksSet // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *IDelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(IDelayedWithdrawalRouterWithdrawalDelayBlocksSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(IDelayedWithdrawalRouterWithdrawalDelayBlocksSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *IDelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *IDelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// IDelayedWithdrawalRouterWithdrawalDelayBlocksSet represents a WithdrawalDelayBlocksSet event raised by the IDelayedWithdrawalRouter contract. -type IDelayedWithdrawalRouterWithdrawalDelayBlocksSet struct { - PreviousValue *big.Int - NewValue *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterWithdrawalDelayBlocksSet is a free log retrieval operation binding the contract event 0x4ffb00400574147429ee377a5633386321e66d45d8b14676014b5fa393e61e9e. -// -// Solidity: event WithdrawalDelayBlocksSet(uint256 previousValue, uint256 newValue) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterFilterer) FilterWithdrawalDelayBlocksSet(opts *bind.FilterOpts) (*IDelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator, error) { - - logs, sub, err := _IDelayedWithdrawalRouter.contract.FilterLogs(opts, "WithdrawalDelayBlocksSet") - if err != nil { - return nil, err - } - return &IDelayedWithdrawalRouterWithdrawalDelayBlocksSetIterator{contract: _IDelayedWithdrawalRouter.contract, event: "WithdrawalDelayBlocksSet", logs: logs, sub: sub}, nil -} - -// WatchWithdrawalDelayBlocksSet is a free log subscription operation binding the contract event 0x4ffb00400574147429ee377a5633386321e66d45d8b14676014b5fa393e61e9e. -// -// Solidity: event WithdrawalDelayBlocksSet(uint256 previousValue, uint256 newValue) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterFilterer) WatchWithdrawalDelayBlocksSet(opts *bind.WatchOpts, sink chan<- *IDelayedWithdrawalRouterWithdrawalDelayBlocksSet) (event.Subscription, error) { - - logs, sub, err := _IDelayedWithdrawalRouter.contract.WatchLogs(opts, "WithdrawalDelayBlocksSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(IDelayedWithdrawalRouterWithdrawalDelayBlocksSet) - if err := _IDelayedWithdrawalRouter.contract.UnpackLog(event, "WithdrawalDelayBlocksSet", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseWithdrawalDelayBlocksSet is a log parse operation binding the contract event 0x4ffb00400574147429ee377a5633386321e66d45d8b14676014b5fa393e61e9e. -// -// Solidity: event WithdrawalDelayBlocksSet(uint256 previousValue, uint256 newValue) -func (_IDelayedWithdrawalRouter *IDelayedWithdrawalRouterFilterer) ParseWithdrawalDelayBlocksSet(log types.Log) (*IDelayedWithdrawalRouterWithdrawalDelayBlocksSet, error) { - event := new(IDelayedWithdrawalRouterWithdrawalDelayBlocksSet) - if err := _IDelayedWithdrawalRouter.contract.UnpackLog(event, "WithdrawalDelayBlocksSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/pkg/bindings/IEigenPod/binding.go b/pkg/bindings/IEigenPod/binding.go index d99c5eae3..a07b03980 100644 --- a/pkg/bindings/IEigenPod/binding.go +++ b/pkg/bindings/IEigenPod/binding.go @@ -29,39 +29,50 @@ var ( _ = abi.ConvertType ) +// BeaconChainProofsBalanceContainerProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsBalanceContainerProof struct { + BalanceContainerRoot [32]byte + Proof []byte +} + +// BeaconChainProofsBalanceProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsBalanceProof struct { + PubkeyHash [32]byte + BalanceRoot [32]byte + Proof []byte +} + // BeaconChainProofsStateRootProof is an auto generated low-level Go binding around an user-defined struct. type BeaconChainProofsStateRootProof struct { BeaconStateRoot [32]byte Proof []byte } -// BeaconChainProofsWithdrawalProof is an auto generated low-level Go binding around an user-defined struct. -type BeaconChainProofsWithdrawalProof struct { - WithdrawalProof []byte - SlotProof []byte - ExecutionPayloadProof []byte - TimestampProof []byte - HistoricalSummaryBlockRootProof []byte - BlockRootIndex uint64 - HistoricalSummaryIndex uint64 - WithdrawalIndex uint64 - BlockRoot [32]byte - SlotRoot [32]byte - TimestampRoot [32]byte - ExecutionPayloadRoot [32]byte +// BeaconChainProofsValidatorProof is an auto generated low-level Go binding around an user-defined struct. +type BeaconChainProofsValidatorProof struct { + ValidatorFields [][32]byte + Proof []byte +} + +// IEigenPodCheckpoint is an auto generated low-level Go binding around an user-defined struct. +type IEigenPodCheckpoint struct { + BeaconBlockRoot [32]byte + ProofsRemaining *big.Int + PodBalanceGwei uint64 + BalanceDeltasGwei *big.Int } // IEigenPodValidatorInfo is an auto generated low-level Go binding around an user-defined struct. type IEigenPodValidatorInfo struct { - ValidatorIndex uint64 - RestakedBalanceGwei uint64 - MostRecentBalanceUpdateTimestamp uint64 - Status uint8 + ValidatorIndex uint64 + RestakedBalanceGwei uint64 + LastCheckpointedAt uint64 + Status uint8 } // IEigenPodMetaData contains all meta data concerning the IEigenPod contract. var IEigenPodMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"function\",\"name\":\"MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"activateRestaking\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"eigenPodManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasRestaked\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"mostRecentWithdrawalTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nonBeaconChainETHBalanceWei\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"provenWithdrawal\",\"inputs\":[{\"name\":\"validatorPubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"slot\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recoverTokens\",\"inputs\":[{\"name\":\"tokenList\",\"type\":\"address[]\",\"internalType\":\"contractIERC20[]\"},{\"name\":\"amountsToWithdraw\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"validatorPubkeyHashToInfo\",\"inputs\":[{\"name\":\"validatorPubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"mostRecentBalanceUpdateTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorPubkeyToInfo\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"mostRecentBalanceUpdateTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"pubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifyAndProcessWithdrawals\",\"inputs\":[{\"name\":\"oracleTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"withdrawalProofs\",\"type\":\"tuple[]\",\"internalType\":\"structBeaconChainProofs.WithdrawalProof[]\",\"components\":[{\"name\":\"withdrawalProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"slotProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"executionPayloadProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"timestampProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"historicalSummaryBlockRootProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"blockRootIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"historicalSummaryIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"withdrawalIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blockRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"slotRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"timestampRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"executionPayloadRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"validatorFieldsProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"validatorFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"},{\"name\":\"withdrawalFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyBalanceUpdates\",\"inputs\":[{\"name\":\"oracleTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"validatorIndices\",\"type\":\"uint40[]\",\"internalType\":\"uint40[]\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"validatorFieldsProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"validatorFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyWithdrawalCredentials\",\"inputs\":[{\"name\":\"oracleTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"validatorIndices\",\"type\":\"uint40[]\",\"internalType\":\"uint40[]\"},{\"name\":\"withdrawalCredentialProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"validatorFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawBeforeRestaking\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawNonBeaconChainETHBalanceWei\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amountToWithdraw\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawRestakedBeaconChainETH\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawableRestakedExecutionLayerGwei\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"EigenPodStaked\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FullWithdrawalRedeemed\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"},{\"name\":\"withdrawalTimestamp\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"withdrawalAmountGwei\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NonBeaconChainETHReceived\",\"inputs\":[{\"name\":\"amountReceived\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NonBeaconChainETHWithdrawn\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amountWithdrawn\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PartialWithdrawalRedeemed\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"},{\"name\":\"withdrawalTimestamp\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"partialWithdrawalAmountGwei\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RestakedBeaconChainETHWithdrawn\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RestakingActivated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorBalanceUpdated\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"},{\"name\":\"balanceTimestamp\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"newValidatorBalanceGwei\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRestaked\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"}],\"anonymous\":false}]", + ABI: "[{\"type\":\"function\",\"name\":\"activeValidatorCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkpointBalanceExitedGwei\",\"inputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"currentCheckpoint\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.Checkpoint\",\"components\":[{\"name\":\"beaconBlockRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proofsRemaining\",\"type\":\"uint24\",\"internalType\":\"uint24\"},{\"name\":\"podBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"balanceDeltasGwei\",\"type\":\"int128\",\"internalType\":\"int128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"currentCheckpointTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getParentBlockRoot\",\"inputs\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"lastCheckpointTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proofSubmitter\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recoverTokens\",\"inputs\":[{\"name\":\"tokenList\",\"type\":\"address[]\",\"internalType\":\"contractIERC20[]\"},{\"name\":\"amountsToWithdraw\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setProofSubmitter\",\"inputs\":[{\"name\":\"newProofSubmitter\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"startCheckpoint\",\"inputs\":[{\"name\":\"revertIfNoBalance\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"validatorPubkeyHashToInfo\",\"inputs\":[{\"name\":\"validatorPubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastCheckpointedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorPubkeyToInfo\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIEigenPod.ValidatorInfo\",\"components\":[{\"name\":\"validatorIndex\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"restakedBalanceGwei\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastCheckpointedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"validatorPubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validatorStatus\",\"inputs\":[{\"name\":\"pubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIEigenPod.VALIDATOR_STATUS\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifyCheckpointProofs\",\"inputs\":[{\"name\":\"balanceContainerProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.BalanceContainerProof\",\"components\":[{\"name\":\"balanceContainerRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"proofs\",\"type\":\"tuple[]\",\"internalType\":\"structBeaconChainProofs.BalanceProof[]\",\"components\":[{\"name\":\"pubkeyHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"balanceRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyStaleBalance\",\"inputs\":[{\"name\":\"beaconTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"proof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.ValidatorProof\",\"components\":[{\"name\":\"validatorFields\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyWithdrawalCredentials\",\"inputs\":[{\"name\":\"beaconTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stateRootProof\",\"type\":\"tuple\",\"internalType\":\"structBeaconChainProofs.StateRootProof\",\"components\":[{\"name\":\"beaconStateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"validatorIndices\",\"type\":\"uint40[]\",\"internalType\":\"uint40[]\"},{\"name\":\"validatorFieldsProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"validatorFields\",\"type\":\"bytes32[][]\",\"internalType\":\"bytes32[][]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawRestakedBeaconChainETH\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawableRestakedExecutionLayerGwei\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"CheckpointCreated\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"beaconBlockRoot\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validatorCount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CheckpointFinalized\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"totalShareDeltaWei\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EigenPodStaked\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NonBeaconChainETHReceived\",\"inputs\":[{\"name\":\"amountReceived\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProofSubmitterUpdated\",\"inputs\":[{\"name\":\"prevProofSubmitter\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newProofSubmitter\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RestakedBeaconChainETHWithdrawn\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorBalanceUpdated\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"},{\"name\":\"balanceTimestamp\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"newValidatorBalanceGwei\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorCheckpointed\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":true,\"internalType\":\"uint40\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRestaked\",\"inputs\":[{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":false,\"internalType\":\"uint40\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorWithdrawn\",\"inputs\":[{\"name\":\"checkpointTimestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"validatorIndex\",\"type\":\"uint40\",\"indexed\":true,\"internalType\":\"uint40\"}],\"anonymous\":false}]", } // IEigenPodABI is the input ABI used to generate the binding from. @@ -210,105 +221,105 @@ func (_IEigenPod *IEigenPodTransactorRaw) Transact(opts *bind.TransactOpts, meth return _IEigenPod.Contract.contract.Transact(opts, method, params...) } -// MAXRESTAKEDBALANCEGWEIPERVALIDATOR is a free data retrieval call binding the contract method 0x1d905d5c. +// ActiveValidatorCount is a free data retrieval call binding the contract method 0x2340e8d3. // -// Solidity: function MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() view returns(uint64) -func (_IEigenPod *IEigenPodCaller) MAXRESTAKEDBALANCEGWEIPERVALIDATOR(opts *bind.CallOpts) (uint64, error) { +// Solidity: function activeValidatorCount() view returns(uint256) +func (_IEigenPod *IEigenPodCaller) ActiveValidatorCount(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _IEigenPod.contract.Call(opts, &out, "MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR") + err := _IEigenPod.contract.Call(opts, &out, "activeValidatorCount") if err != nil { - return *new(uint64), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -// MAXRESTAKEDBALANCEGWEIPERVALIDATOR is a free data retrieval call binding the contract method 0x1d905d5c. +// ActiveValidatorCount is a free data retrieval call binding the contract method 0x2340e8d3. // -// Solidity: function MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() view returns(uint64) -func (_IEigenPod *IEigenPodSession) MAXRESTAKEDBALANCEGWEIPERVALIDATOR() (uint64, error) { - return _IEigenPod.Contract.MAXRESTAKEDBALANCEGWEIPERVALIDATOR(&_IEigenPod.CallOpts) +// Solidity: function activeValidatorCount() view returns(uint256) +func (_IEigenPod *IEigenPodSession) ActiveValidatorCount() (*big.Int, error) { + return _IEigenPod.Contract.ActiveValidatorCount(&_IEigenPod.CallOpts) } -// MAXRESTAKEDBALANCEGWEIPERVALIDATOR is a free data retrieval call binding the contract method 0x1d905d5c. +// ActiveValidatorCount is a free data retrieval call binding the contract method 0x2340e8d3. // -// Solidity: function MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() view returns(uint64) -func (_IEigenPod *IEigenPodCallerSession) MAXRESTAKEDBALANCEGWEIPERVALIDATOR() (uint64, error) { - return _IEigenPod.Contract.MAXRESTAKEDBALANCEGWEIPERVALIDATOR(&_IEigenPod.CallOpts) +// Solidity: function activeValidatorCount() view returns(uint256) +func (_IEigenPod *IEigenPodCallerSession) ActiveValidatorCount() (*big.Int, error) { + return _IEigenPod.Contract.ActiveValidatorCount(&_IEigenPod.CallOpts) } -// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. +// CheckpointBalanceExitedGwei is a free data retrieval call binding the contract method 0x52396a59. // -// Solidity: function eigenPodManager() view returns(address) -func (_IEigenPod *IEigenPodCaller) EigenPodManager(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function checkpointBalanceExitedGwei(uint64 ) view returns(uint64) +func (_IEigenPod *IEigenPodCaller) CheckpointBalanceExitedGwei(opts *bind.CallOpts, arg0 uint64) (uint64, error) { var out []interface{} - err := _IEigenPod.contract.Call(opts, &out, "eigenPodManager") + err := _IEigenPod.contract.Call(opts, &out, "checkpointBalanceExitedGwei", arg0) if err != nil { - return *new(common.Address), err + return *new(uint64), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) return out0, err } -// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. +// CheckpointBalanceExitedGwei is a free data retrieval call binding the contract method 0x52396a59. // -// Solidity: function eigenPodManager() view returns(address) -func (_IEigenPod *IEigenPodSession) EigenPodManager() (common.Address, error) { - return _IEigenPod.Contract.EigenPodManager(&_IEigenPod.CallOpts) +// Solidity: function checkpointBalanceExitedGwei(uint64 ) view returns(uint64) +func (_IEigenPod *IEigenPodSession) CheckpointBalanceExitedGwei(arg0 uint64) (uint64, error) { + return _IEigenPod.Contract.CheckpointBalanceExitedGwei(&_IEigenPod.CallOpts, arg0) } -// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. +// CheckpointBalanceExitedGwei is a free data retrieval call binding the contract method 0x52396a59. // -// Solidity: function eigenPodManager() view returns(address) -func (_IEigenPod *IEigenPodCallerSession) EigenPodManager() (common.Address, error) { - return _IEigenPod.Contract.EigenPodManager(&_IEigenPod.CallOpts) +// Solidity: function checkpointBalanceExitedGwei(uint64 ) view returns(uint64) +func (_IEigenPod *IEigenPodCallerSession) CheckpointBalanceExitedGwei(arg0 uint64) (uint64, error) { + return _IEigenPod.Contract.CheckpointBalanceExitedGwei(&_IEigenPod.CallOpts, arg0) } -// HasRestaked is a free data retrieval call binding the contract method 0x3106ab53. +// CurrentCheckpoint is a free data retrieval call binding the contract method 0x47d28372. // -// Solidity: function hasRestaked() view returns(bool) -func (_IEigenPod *IEigenPodCaller) HasRestaked(opts *bind.CallOpts) (bool, error) { +// Solidity: function currentCheckpoint() view returns((bytes32,uint24,uint64,int128)) +func (_IEigenPod *IEigenPodCaller) CurrentCheckpoint(opts *bind.CallOpts) (IEigenPodCheckpoint, error) { var out []interface{} - err := _IEigenPod.contract.Call(opts, &out, "hasRestaked") + err := _IEigenPod.contract.Call(opts, &out, "currentCheckpoint") if err != nil { - return *new(bool), err + return *new(IEigenPodCheckpoint), err } - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out0 := *abi.ConvertType(out[0], new(IEigenPodCheckpoint)).(*IEigenPodCheckpoint) return out0, err } -// HasRestaked is a free data retrieval call binding the contract method 0x3106ab53. +// CurrentCheckpoint is a free data retrieval call binding the contract method 0x47d28372. // -// Solidity: function hasRestaked() view returns(bool) -func (_IEigenPod *IEigenPodSession) HasRestaked() (bool, error) { - return _IEigenPod.Contract.HasRestaked(&_IEigenPod.CallOpts) +// Solidity: function currentCheckpoint() view returns((bytes32,uint24,uint64,int128)) +func (_IEigenPod *IEigenPodSession) CurrentCheckpoint() (IEigenPodCheckpoint, error) { + return _IEigenPod.Contract.CurrentCheckpoint(&_IEigenPod.CallOpts) } -// HasRestaked is a free data retrieval call binding the contract method 0x3106ab53. +// CurrentCheckpoint is a free data retrieval call binding the contract method 0x47d28372. // -// Solidity: function hasRestaked() view returns(bool) -func (_IEigenPod *IEigenPodCallerSession) HasRestaked() (bool, error) { - return _IEigenPod.Contract.HasRestaked(&_IEigenPod.CallOpts) +// Solidity: function currentCheckpoint() view returns((bytes32,uint24,uint64,int128)) +func (_IEigenPod *IEigenPodCallerSession) CurrentCheckpoint() (IEigenPodCheckpoint, error) { + return _IEigenPod.Contract.CurrentCheckpoint(&_IEigenPod.CallOpts) } -// MostRecentWithdrawalTimestamp is a free data retrieval call binding the contract method 0x87e0d289. +// CurrentCheckpointTimestamp is a free data retrieval call binding the contract method 0x42ecff2a. // -// Solidity: function mostRecentWithdrawalTimestamp() view returns(uint64) -func (_IEigenPod *IEigenPodCaller) MostRecentWithdrawalTimestamp(opts *bind.CallOpts) (uint64, error) { +// Solidity: function currentCheckpointTimestamp() view returns(uint64) +func (_IEigenPod *IEigenPodCaller) CurrentCheckpointTimestamp(opts *bind.CallOpts) (uint64, error) { var out []interface{} - err := _IEigenPod.contract.Call(opts, &out, "mostRecentWithdrawalTimestamp") + err := _IEigenPod.contract.Call(opts, &out, "currentCheckpointTimestamp") if err != nil { return *new(uint64), err @@ -320,49 +331,111 @@ func (_IEigenPod *IEigenPodCaller) MostRecentWithdrawalTimestamp(opts *bind.Call } -// MostRecentWithdrawalTimestamp is a free data retrieval call binding the contract method 0x87e0d289. +// CurrentCheckpointTimestamp is a free data retrieval call binding the contract method 0x42ecff2a. // -// Solidity: function mostRecentWithdrawalTimestamp() view returns(uint64) -func (_IEigenPod *IEigenPodSession) MostRecentWithdrawalTimestamp() (uint64, error) { - return _IEigenPod.Contract.MostRecentWithdrawalTimestamp(&_IEigenPod.CallOpts) +// Solidity: function currentCheckpointTimestamp() view returns(uint64) +func (_IEigenPod *IEigenPodSession) CurrentCheckpointTimestamp() (uint64, error) { + return _IEigenPod.Contract.CurrentCheckpointTimestamp(&_IEigenPod.CallOpts) } -// MostRecentWithdrawalTimestamp is a free data retrieval call binding the contract method 0x87e0d289. +// CurrentCheckpointTimestamp is a free data retrieval call binding the contract method 0x42ecff2a. // -// Solidity: function mostRecentWithdrawalTimestamp() view returns(uint64) -func (_IEigenPod *IEigenPodCallerSession) MostRecentWithdrawalTimestamp() (uint64, error) { - return _IEigenPod.Contract.MostRecentWithdrawalTimestamp(&_IEigenPod.CallOpts) +// Solidity: function currentCheckpointTimestamp() view returns(uint64) +func (_IEigenPod *IEigenPodCallerSession) CurrentCheckpointTimestamp() (uint64, error) { + return _IEigenPod.Contract.CurrentCheckpointTimestamp(&_IEigenPod.CallOpts) } -// NonBeaconChainETHBalanceWei is a free data retrieval call binding the contract method 0xfe80b087. +// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. // -// Solidity: function nonBeaconChainETHBalanceWei() view returns(uint256) -func (_IEigenPod *IEigenPodCaller) NonBeaconChainETHBalanceWei(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function eigenPodManager() view returns(address) +func (_IEigenPod *IEigenPodCaller) EigenPodManager(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _IEigenPod.contract.Call(opts, &out, "nonBeaconChainETHBalanceWei") + err := _IEigenPod.contract.Call(opts, &out, "eigenPodManager") if err != nil { - return *new(*big.Int), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. +// +// Solidity: function eigenPodManager() view returns(address) +func (_IEigenPod *IEigenPodSession) EigenPodManager() (common.Address, error) { + return _IEigenPod.Contract.EigenPodManager(&_IEigenPod.CallOpts) +} + +// EigenPodManager is a free data retrieval call binding the contract method 0x4665bcda. +// +// Solidity: function eigenPodManager() view returns(address) +func (_IEigenPod *IEigenPodCallerSession) EigenPodManager() (common.Address, error) { + return _IEigenPod.Contract.EigenPodManager(&_IEigenPod.CallOpts) +} + +// GetParentBlockRoot is a free data retrieval call binding the contract method 0x6c0d2d5a. +// +// Solidity: function getParentBlockRoot(uint64 timestamp) view returns(bytes32) +func (_IEigenPod *IEigenPodCaller) GetParentBlockRoot(opts *bind.CallOpts, timestamp uint64) ([32]byte, error) { + var out []interface{} + err := _IEigenPod.contract.Call(opts, &out, "getParentBlockRoot", timestamp) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetParentBlockRoot is a free data retrieval call binding the contract method 0x6c0d2d5a. +// +// Solidity: function getParentBlockRoot(uint64 timestamp) view returns(bytes32) +func (_IEigenPod *IEigenPodSession) GetParentBlockRoot(timestamp uint64) ([32]byte, error) { + return _IEigenPod.Contract.GetParentBlockRoot(&_IEigenPod.CallOpts, timestamp) +} + +// GetParentBlockRoot is a free data retrieval call binding the contract method 0x6c0d2d5a. +// +// Solidity: function getParentBlockRoot(uint64 timestamp) view returns(bytes32) +func (_IEigenPod *IEigenPodCallerSession) GetParentBlockRoot(timestamp uint64) ([32]byte, error) { + return _IEigenPod.Contract.GetParentBlockRoot(&_IEigenPod.CallOpts, timestamp) +} + +// LastCheckpointTimestamp is a free data retrieval call binding the contract method 0xee94d67c. +// +// Solidity: function lastCheckpointTimestamp() view returns(uint64) +func (_IEigenPod *IEigenPodCaller) LastCheckpointTimestamp(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _IEigenPod.contract.Call(opts, &out, "lastCheckpointTimestamp") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) return out0, err } -// NonBeaconChainETHBalanceWei is a free data retrieval call binding the contract method 0xfe80b087. +// LastCheckpointTimestamp is a free data retrieval call binding the contract method 0xee94d67c. // -// Solidity: function nonBeaconChainETHBalanceWei() view returns(uint256) -func (_IEigenPod *IEigenPodSession) NonBeaconChainETHBalanceWei() (*big.Int, error) { - return _IEigenPod.Contract.NonBeaconChainETHBalanceWei(&_IEigenPod.CallOpts) +// Solidity: function lastCheckpointTimestamp() view returns(uint64) +func (_IEigenPod *IEigenPodSession) LastCheckpointTimestamp() (uint64, error) { + return _IEigenPod.Contract.LastCheckpointTimestamp(&_IEigenPod.CallOpts) } -// NonBeaconChainETHBalanceWei is a free data retrieval call binding the contract method 0xfe80b087. +// LastCheckpointTimestamp is a free data retrieval call binding the contract method 0xee94d67c. // -// Solidity: function nonBeaconChainETHBalanceWei() view returns(uint256) -func (_IEigenPod *IEigenPodCallerSession) NonBeaconChainETHBalanceWei() (*big.Int, error) { - return _IEigenPod.Contract.NonBeaconChainETHBalanceWei(&_IEigenPod.CallOpts) +// Solidity: function lastCheckpointTimestamp() view returns(uint64) +func (_IEigenPod *IEigenPodCallerSession) LastCheckpointTimestamp() (uint64, error) { + return _IEigenPod.Contract.LastCheckpointTimestamp(&_IEigenPod.CallOpts) } // PodOwner is a free data retrieval call binding the contract method 0x0b18ff66. @@ -396,35 +469,35 @@ func (_IEigenPod *IEigenPodCallerSession) PodOwner() (common.Address, error) { return _IEigenPod.Contract.PodOwner(&_IEigenPod.CallOpts) } -// ProvenWithdrawal is a free data retrieval call binding the contract method 0x34bea20a. +// ProofSubmitter is a free data retrieval call binding the contract method 0x58753357. // -// Solidity: function provenWithdrawal(bytes32 validatorPubkeyHash, uint64 slot) view returns(bool) -func (_IEigenPod *IEigenPodCaller) ProvenWithdrawal(opts *bind.CallOpts, validatorPubkeyHash [32]byte, slot uint64) (bool, error) { +// Solidity: function proofSubmitter() view returns(address) +func (_IEigenPod *IEigenPodCaller) ProofSubmitter(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _IEigenPod.contract.Call(opts, &out, "provenWithdrawal", validatorPubkeyHash, slot) + err := _IEigenPod.contract.Call(opts, &out, "proofSubmitter") if err != nil { - return *new(bool), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// ProvenWithdrawal is a free data retrieval call binding the contract method 0x34bea20a. +// ProofSubmitter is a free data retrieval call binding the contract method 0x58753357. // -// Solidity: function provenWithdrawal(bytes32 validatorPubkeyHash, uint64 slot) view returns(bool) -func (_IEigenPod *IEigenPodSession) ProvenWithdrawal(validatorPubkeyHash [32]byte, slot uint64) (bool, error) { - return _IEigenPod.Contract.ProvenWithdrawal(&_IEigenPod.CallOpts, validatorPubkeyHash, slot) +// Solidity: function proofSubmitter() view returns(address) +func (_IEigenPod *IEigenPodSession) ProofSubmitter() (common.Address, error) { + return _IEigenPod.Contract.ProofSubmitter(&_IEigenPod.CallOpts) } -// ProvenWithdrawal is a free data retrieval call binding the contract method 0x34bea20a. +// ProofSubmitter is a free data retrieval call binding the contract method 0x58753357. // -// Solidity: function provenWithdrawal(bytes32 validatorPubkeyHash, uint64 slot) view returns(bool) -func (_IEigenPod *IEigenPodCallerSession) ProvenWithdrawal(validatorPubkeyHash [32]byte, slot uint64) (bool, error) { - return _IEigenPod.Contract.ProvenWithdrawal(&_IEigenPod.CallOpts, validatorPubkeyHash, slot) +// Solidity: function proofSubmitter() view returns(address) +func (_IEigenPod *IEigenPodCallerSession) ProofSubmitter() (common.Address, error) { + return _IEigenPod.Contract.ProofSubmitter(&_IEigenPod.CallOpts) } // ValidatorPubkeyHashToInfo is a free data retrieval call binding the contract method 0x6fcd0e53. @@ -582,27 +655,6 @@ func (_IEigenPod *IEigenPodCallerSession) WithdrawableRestakedExecutionLayerGwei return _IEigenPod.Contract.WithdrawableRestakedExecutionLayerGwei(&_IEigenPod.CallOpts) } -// ActivateRestaking is a paid mutator transaction binding the contract method 0x0cd4649e. -// -// Solidity: function activateRestaking() returns() -func (_IEigenPod *IEigenPodTransactor) ActivateRestaking(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IEigenPod.contract.Transact(opts, "activateRestaking") -} - -// ActivateRestaking is a paid mutator transaction binding the contract method 0x0cd4649e. -// -// Solidity: function activateRestaking() returns() -func (_IEigenPod *IEigenPodSession) ActivateRestaking() (*types.Transaction, error) { - return _IEigenPod.Contract.ActivateRestaking(&_IEigenPod.TransactOpts) -} - -// ActivateRestaking is a paid mutator transaction binding the contract method 0x0cd4649e. -// -// Solidity: function activateRestaking() returns() -func (_IEigenPod *IEigenPodTransactorSession) ActivateRestaking() (*types.Transaction, error) { - return _IEigenPod.Contract.ActivateRestaking(&_IEigenPod.TransactOpts) -} - // Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // // Solidity: function initialize(address owner) returns() @@ -645,6 +697,27 @@ func (_IEigenPod *IEigenPodTransactorSession) RecoverTokens(tokenList []common.A return _IEigenPod.Contract.RecoverTokens(&_IEigenPod.TransactOpts, tokenList, amountsToWithdraw, recipient) } +// SetProofSubmitter is a paid mutator transaction binding the contract method 0xd06d5587. +// +// Solidity: function setProofSubmitter(address newProofSubmitter) returns() +func (_IEigenPod *IEigenPodTransactor) SetProofSubmitter(opts *bind.TransactOpts, newProofSubmitter common.Address) (*types.Transaction, error) { + return _IEigenPod.contract.Transact(opts, "setProofSubmitter", newProofSubmitter) +} + +// SetProofSubmitter is a paid mutator transaction binding the contract method 0xd06d5587. +// +// Solidity: function setProofSubmitter(address newProofSubmitter) returns() +func (_IEigenPod *IEigenPodSession) SetProofSubmitter(newProofSubmitter common.Address) (*types.Transaction, error) { + return _IEigenPod.Contract.SetProofSubmitter(&_IEigenPod.TransactOpts, newProofSubmitter) +} + +// SetProofSubmitter is a paid mutator transaction binding the contract method 0xd06d5587. +// +// Solidity: function setProofSubmitter(address newProofSubmitter) returns() +func (_IEigenPod *IEigenPodTransactorSession) SetProofSubmitter(newProofSubmitter common.Address) (*types.Transaction, error) { + return _IEigenPod.Contract.SetProofSubmitter(&_IEigenPod.TransactOpts, newProofSubmitter) +} + // Stake is a paid mutator transaction binding the contract method 0x9b4e4634. // // Solidity: function stake(bytes pubkey, bytes signature, bytes32 depositDataRoot) payable returns() @@ -666,109 +739,88 @@ func (_IEigenPod *IEigenPodTransactorSession) Stake(pubkey []byte, signature []b return _IEigenPod.Contract.Stake(&_IEigenPod.TransactOpts, pubkey, signature, depositDataRoot) } -// VerifyAndProcessWithdrawals is a paid mutator transaction binding the contract method 0xe251ef52. +// StartCheckpoint is a paid mutator transaction binding the contract method 0x88676cad. // -// Solidity: function verifyAndProcessWithdrawals(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, (bytes,bytes,bytes,bytes,bytes,uint64,uint64,uint64,bytes32,bytes32,bytes32,bytes32)[] withdrawalProofs, bytes[] validatorFieldsProofs, bytes32[][] validatorFields, bytes32[][] withdrawalFields) returns() -func (_IEigenPod *IEigenPodTransactor) VerifyAndProcessWithdrawals(opts *bind.TransactOpts, oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, withdrawalProofs []BeaconChainProofsWithdrawalProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte, withdrawalFields [][][32]byte) (*types.Transaction, error) { - return _IEigenPod.contract.Transact(opts, "verifyAndProcessWithdrawals", oracleTimestamp, stateRootProof, withdrawalProofs, validatorFieldsProofs, validatorFields, withdrawalFields) +// Solidity: function startCheckpoint(bool revertIfNoBalance) returns() +func (_IEigenPod *IEigenPodTransactor) StartCheckpoint(opts *bind.TransactOpts, revertIfNoBalance bool) (*types.Transaction, error) { + return _IEigenPod.contract.Transact(opts, "startCheckpoint", revertIfNoBalance) } -// VerifyAndProcessWithdrawals is a paid mutator transaction binding the contract method 0xe251ef52. +// StartCheckpoint is a paid mutator transaction binding the contract method 0x88676cad. // -// Solidity: function verifyAndProcessWithdrawals(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, (bytes,bytes,bytes,bytes,bytes,uint64,uint64,uint64,bytes32,bytes32,bytes32,bytes32)[] withdrawalProofs, bytes[] validatorFieldsProofs, bytes32[][] validatorFields, bytes32[][] withdrawalFields) returns() -func (_IEigenPod *IEigenPodSession) VerifyAndProcessWithdrawals(oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, withdrawalProofs []BeaconChainProofsWithdrawalProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte, withdrawalFields [][][32]byte) (*types.Transaction, error) { - return _IEigenPod.Contract.VerifyAndProcessWithdrawals(&_IEigenPod.TransactOpts, oracleTimestamp, stateRootProof, withdrawalProofs, validatorFieldsProofs, validatorFields, withdrawalFields) +// Solidity: function startCheckpoint(bool revertIfNoBalance) returns() +func (_IEigenPod *IEigenPodSession) StartCheckpoint(revertIfNoBalance bool) (*types.Transaction, error) { + return _IEigenPod.Contract.StartCheckpoint(&_IEigenPod.TransactOpts, revertIfNoBalance) } -// VerifyAndProcessWithdrawals is a paid mutator transaction binding the contract method 0xe251ef52. +// StartCheckpoint is a paid mutator transaction binding the contract method 0x88676cad. // -// Solidity: function verifyAndProcessWithdrawals(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, (bytes,bytes,bytes,bytes,bytes,uint64,uint64,uint64,bytes32,bytes32,bytes32,bytes32)[] withdrawalProofs, bytes[] validatorFieldsProofs, bytes32[][] validatorFields, bytes32[][] withdrawalFields) returns() -func (_IEigenPod *IEigenPodTransactorSession) VerifyAndProcessWithdrawals(oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, withdrawalProofs []BeaconChainProofsWithdrawalProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte, withdrawalFields [][][32]byte) (*types.Transaction, error) { - return _IEigenPod.Contract.VerifyAndProcessWithdrawals(&_IEigenPod.TransactOpts, oracleTimestamp, stateRootProof, withdrawalProofs, validatorFieldsProofs, validatorFields, withdrawalFields) +// Solidity: function startCheckpoint(bool revertIfNoBalance) returns() +func (_IEigenPod *IEigenPodTransactorSession) StartCheckpoint(revertIfNoBalance bool) (*types.Transaction, error) { + return _IEigenPod.Contract.StartCheckpoint(&_IEigenPod.TransactOpts, revertIfNoBalance) } -// VerifyBalanceUpdates is a paid mutator transaction binding the contract method 0xa50600f4. +// VerifyCheckpointProofs is a paid mutator transaction binding the contract method 0xf074ba62. // -// Solidity: function verifyBalanceUpdates(uint64 oracleTimestamp, uint40[] validatorIndices, (bytes32,bytes) stateRootProof, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() -func (_IEigenPod *IEigenPodTransactor) VerifyBalanceUpdates(opts *bind.TransactOpts, oracleTimestamp uint64, validatorIndices []*big.Int, stateRootProof BeaconChainProofsStateRootProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _IEigenPod.contract.Transact(opts, "verifyBalanceUpdates", oracleTimestamp, validatorIndices, stateRootProof, validatorFieldsProofs, validatorFields) +// Solidity: function verifyCheckpointProofs((bytes32,bytes) balanceContainerProof, (bytes32,bytes32,bytes)[] proofs) returns() +func (_IEigenPod *IEigenPodTransactor) VerifyCheckpointProofs(opts *bind.TransactOpts, balanceContainerProof BeaconChainProofsBalanceContainerProof, proofs []BeaconChainProofsBalanceProof) (*types.Transaction, error) { + return _IEigenPod.contract.Transact(opts, "verifyCheckpointProofs", balanceContainerProof, proofs) } -// VerifyBalanceUpdates is a paid mutator transaction binding the contract method 0xa50600f4. -// -// Solidity: function verifyBalanceUpdates(uint64 oracleTimestamp, uint40[] validatorIndices, (bytes32,bytes) stateRootProof, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() -func (_IEigenPod *IEigenPodSession) VerifyBalanceUpdates(oracleTimestamp uint64, validatorIndices []*big.Int, stateRootProof BeaconChainProofsStateRootProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _IEigenPod.Contract.VerifyBalanceUpdates(&_IEigenPod.TransactOpts, oracleTimestamp, validatorIndices, stateRootProof, validatorFieldsProofs, validatorFields) -} - -// VerifyBalanceUpdates is a paid mutator transaction binding the contract method 0xa50600f4. -// -// Solidity: function verifyBalanceUpdates(uint64 oracleTimestamp, uint40[] validatorIndices, (bytes32,bytes) stateRootProof, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() -func (_IEigenPod *IEigenPodTransactorSession) VerifyBalanceUpdates(oracleTimestamp uint64, validatorIndices []*big.Int, stateRootProof BeaconChainProofsStateRootProof, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _IEigenPod.Contract.VerifyBalanceUpdates(&_IEigenPod.TransactOpts, oracleTimestamp, validatorIndices, stateRootProof, validatorFieldsProofs, validatorFields) -} - -// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. -// -// Solidity: function verifyWithdrawalCredentials(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] withdrawalCredentialProofs, bytes32[][] validatorFields) returns() -func (_IEigenPod *IEigenPodTransactor) VerifyWithdrawalCredentials(opts *bind.TransactOpts, oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, withdrawalCredentialProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _IEigenPod.contract.Transact(opts, "verifyWithdrawalCredentials", oracleTimestamp, stateRootProof, validatorIndices, withdrawalCredentialProofs, validatorFields) -} - -// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. +// VerifyCheckpointProofs is a paid mutator transaction binding the contract method 0xf074ba62. // -// Solidity: function verifyWithdrawalCredentials(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] withdrawalCredentialProofs, bytes32[][] validatorFields) returns() -func (_IEigenPod *IEigenPodSession) VerifyWithdrawalCredentials(oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, withdrawalCredentialProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _IEigenPod.Contract.VerifyWithdrawalCredentials(&_IEigenPod.TransactOpts, oracleTimestamp, stateRootProof, validatorIndices, withdrawalCredentialProofs, validatorFields) +// Solidity: function verifyCheckpointProofs((bytes32,bytes) balanceContainerProof, (bytes32,bytes32,bytes)[] proofs) returns() +func (_IEigenPod *IEigenPodSession) VerifyCheckpointProofs(balanceContainerProof BeaconChainProofsBalanceContainerProof, proofs []BeaconChainProofsBalanceProof) (*types.Transaction, error) { + return _IEigenPod.Contract.VerifyCheckpointProofs(&_IEigenPod.TransactOpts, balanceContainerProof, proofs) } -// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. +// VerifyCheckpointProofs is a paid mutator transaction binding the contract method 0xf074ba62. // -// Solidity: function verifyWithdrawalCredentials(uint64 oracleTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] withdrawalCredentialProofs, bytes32[][] validatorFields) returns() -func (_IEigenPod *IEigenPodTransactorSession) VerifyWithdrawalCredentials(oracleTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, withdrawalCredentialProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { - return _IEigenPod.Contract.VerifyWithdrawalCredentials(&_IEigenPod.TransactOpts, oracleTimestamp, stateRootProof, validatorIndices, withdrawalCredentialProofs, validatorFields) +// Solidity: function verifyCheckpointProofs((bytes32,bytes) balanceContainerProof, (bytes32,bytes32,bytes)[] proofs) returns() +func (_IEigenPod *IEigenPodTransactorSession) VerifyCheckpointProofs(balanceContainerProof BeaconChainProofsBalanceContainerProof, proofs []BeaconChainProofsBalanceProof) (*types.Transaction, error) { + return _IEigenPod.Contract.VerifyCheckpointProofs(&_IEigenPod.TransactOpts, balanceContainerProof, proofs) } -// WithdrawBeforeRestaking is a paid mutator transaction binding the contract method 0xbaa7145a. +// VerifyStaleBalance is a paid mutator transaction binding the contract method 0x039157d2. // -// Solidity: function withdrawBeforeRestaking() returns() -func (_IEigenPod *IEigenPodTransactor) WithdrawBeforeRestaking(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IEigenPod.contract.Transact(opts, "withdrawBeforeRestaking") +// Solidity: function verifyStaleBalance(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, (bytes32[],bytes) proof) returns() +func (_IEigenPod *IEigenPodTransactor) VerifyStaleBalance(opts *bind.TransactOpts, beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, proof BeaconChainProofsValidatorProof) (*types.Transaction, error) { + return _IEigenPod.contract.Transact(opts, "verifyStaleBalance", beaconTimestamp, stateRootProof, proof) } -// WithdrawBeforeRestaking is a paid mutator transaction binding the contract method 0xbaa7145a. +// VerifyStaleBalance is a paid mutator transaction binding the contract method 0x039157d2. // -// Solidity: function withdrawBeforeRestaking() returns() -func (_IEigenPod *IEigenPodSession) WithdrawBeforeRestaking() (*types.Transaction, error) { - return _IEigenPod.Contract.WithdrawBeforeRestaking(&_IEigenPod.TransactOpts) +// Solidity: function verifyStaleBalance(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, (bytes32[],bytes) proof) returns() +func (_IEigenPod *IEigenPodSession) VerifyStaleBalance(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, proof BeaconChainProofsValidatorProof) (*types.Transaction, error) { + return _IEigenPod.Contract.VerifyStaleBalance(&_IEigenPod.TransactOpts, beaconTimestamp, stateRootProof, proof) } -// WithdrawBeforeRestaking is a paid mutator transaction binding the contract method 0xbaa7145a. +// VerifyStaleBalance is a paid mutator transaction binding the contract method 0x039157d2. // -// Solidity: function withdrawBeforeRestaking() returns() -func (_IEigenPod *IEigenPodTransactorSession) WithdrawBeforeRestaking() (*types.Transaction, error) { - return _IEigenPod.Contract.WithdrawBeforeRestaking(&_IEigenPod.TransactOpts) +// Solidity: function verifyStaleBalance(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, (bytes32[],bytes) proof) returns() +func (_IEigenPod *IEigenPodTransactorSession) VerifyStaleBalance(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, proof BeaconChainProofsValidatorProof) (*types.Transaction, error) { + return _IEigenPod.Contract.VerifyStaleBalance(&_IEigenPod.TransactOpts, beaconTimestamp, stateRootProof, proof) } -// WithdrawNonBeaconChainETHBalanceWei is a paid mutator transaction binding the contract method 0xe2c83445. +// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. // -// Solidity: function withdrawNonBeaconChainETHBalanceWei(address recipient, uint256 amountToWithdraw) returns() -func (_IEigenPod *IEigenPodTransactor) WithdrawNonBeaconChainETHBalanceWei(opts *bind.TransactOpts, recipient common.Address, amountToWithdraw *big.Int) (*types.Transaction, error) { - return _IEigenPod.contract.Transact(opts, "withdrawNonBeaconChainETHBalanceWei", recipient, amountToWithdraw) +// Solidity: function verifyWithdrawalCredentials(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() +func (_IEigenPod *IEigenPodTransactor) VerifyWithdrawalCredentials(opts *bind.TransactOpts, beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { + return _IEigenPod.contract.Transact(opts, "verifyWithdrawalCredentials", beaconTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) } -// WithdrawNonBeaconChainETHBalanceWei is a paid mutator transaction binding the contract method 0xe2c83445. +// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. // -// Solidity: function withdrawNonBeaconChainETHBalanceWei(address recipient, uint256 amountToWithdraw) returns() -func (_IEigenPod *IEigenPodSession) WithdrawNonBeaconChainETHBalanceWei(recipient common.Address, amountToWithdraw *big.Int) (*types.Transaction, error) { - return _IEigenPod.Contract.WithdrawNonBeaconChainETHBalanceWei(&_IEigenPod.TransactOpts, recipient, amountToWithdraw) +// Solidity: function verifyWithdrawalCredentials(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() +func (_IEigenPod *IEigenPodSession) VerifyWithdrawalCredentials(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { + return _IEigenPod.Contract.VerifyWithdrawalCredentials(&_IEigenPod.TransactOpts, beaconTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) } -// WithdrawNonBeaconChainETHBalanceWei is a paid mutator transaction binding the contract method 0xe2c83445. +// VerifyWithdrawalCredentials is a paid mutator transaction binding the contract method 0x3f65cf19. // -// Solidity: function withdrawNonBeaconChainETHBalanceWei(address recipient, uint256 amountToWithdraw) returns() -func (_IEigenPod *IEigenPodTransactorSession) WithdrawNonBeaconChainETHBalanceWei(recipient common.Address, amountToWithdraw *big.Int) (*types.Transaction, error) { - return _IEigenPod.Contract.WithdrawNonBeaconChainETHBalanceWei(&_IEigenPod.TransactOpts, recipient, amountToWithdraw) +// Solidity: function verifyWithdrawalCredentials(uint64 beaconTimestamp, (bytes32,bytes) stateRootProof, uint40[] validatorIndices, bytes[] validatorFieldsProofs, bytes32[][] validatorFields) returns() +func (_IEigenPod *IEigenPodTransactorSession) VerifyWithdrawalCredentials(beaconTimestamp uint64, stateRootProof BeaconChainProofsStateRootProof, validatorIndices []*big.Int, validatorFieldsProofs [][]byte, validatorFields [][][32]byte) (*types.Transaction, error) { + return _IEigenPod.Contract.VerifyWithdrawalCredentials(&_IEigenPod.TransactOpts, beaconTimestamp, stateRootProof, validatorIndices, validatorFieldsProofs, validatorFields) } // WithdrawRestakedBeaconChainETH is a paid mutator transaction binding the contract method 0xc4907442. @@ -792,9 +844,9 @@ func (_IEigenPod *IEigenPodTransactorSession) WithdrawRestakedBeaconChainETH(rec return _IEigenPod.Contract.WithdrawRestakedBeaconChainETH(&_IEigenPod.TransactOpts, recipient, amount) } -// IEigenPodEigenPodStakedIterator is returned from FilterEigenPodStaked and is used to iterate over the raw logs and unpacked data for EigenPodStaked events raised by the IEigenPod contract. -type IEigenPodEigenPodStakedIterator struct { - Event *IEigenPodEigenPodStaked // Event containing the contract specifics and raw log +// IEigenPodCheckpointCreatedIterator is returned from FilterCheckpointCreated and is used to iterate over the raw logs and unpacked data for CheckpointCreated events raised by the IEigenPod contract. +type IEigenPodCheckpointCreatedIterator struct { + Event *IEigenPodCheckpointCreated // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -808,7 +860,7 @@ type IEigenPodEigenPodStakedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *IEigenPodEigenPodStakedIterator) Next() bool { +func (it *IEigenPodCheckpointCreatedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -817,7 +869,7 @@ func (it *IEigenPodEigenPodStakedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(IEigenPodEigenPodStaked) + it.Event = new(IEigenPodCheckpointCreated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -832,7 +884,7 @@ func (it *IEigenPodEigenPodStakedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(IEigenPodEigenPodStaked) + it.Event = new(IEigenPodCheckpointCreated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -848,41 +900,61 @@ func (it *IEigenPodEigenPodStakedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *IEigenPodEigenPodStakedIterator) Error() error { +func (it *IEigenPodCheckpointCreatedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *IEigenPodEigenPodStakedIterator) Close() error { +func (it *IEigenPodCheckpointCreatedIterator) Close() error { it.sub.Unsubscribe() return nil } -// IEigenPodEigenPodStaked represents a EigenPodStaked event raised by the IEigenPod contract. -type IEigenPodEigenPodStaked struct { - Pubkey []byte - Raw types.Log // Blockchain specific contextual infos +// IEigenPodCheckpointCreated represents a CheckpointCreated event raised by the IEigenPod contract. +type IEigenPodCheckpointCreated struct { + CheckpointTimestamp uint64 + BeaconBlockRoot [32]byte + ValidatorCount *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterEigenPodStaked is a free log retrieval operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// FilterCheckpointCreated is a free log retrieval operation binding the contract event 0x575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076. // -// Solidity: event EigenPodStaked(bytes pubkey) -func (_IEigenPod *IEigenPodFilterer) FilterEigenPodStaked(opts *bind.FilterOpts) (*IEigenPodEigenPodStakedIterator, error) { +// Solidity: event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount) +func (_IEigenPod *IEigenPodFilterer) FilterCheckpointCreated(opts *bind.FilterOpts, checkpointTimestamp []uint64, beaconBlockRoot [][32]byte) (*IEigenPodCheckpointCreatedIterator, error) { - logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "EigenPodStaked") + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var beaconBlockRootRule []interface{} + for _, beaconBlockRootItem := range beaconBlockRoot { + beaconBlockRootRule = append(beaconBlockRootRule, beaconBlockRootItem) + } + + logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "CheckpointCreated", checkpointTimestampRule, beaconBlockRootRule) if err != nil { return nil, err } - return &IEigenPodEigenPodStakedIterator{contract: _IEigenPod.contract, event: "EigenPodStaked", logs: logs, sub: sub}, nil + return &IEigenPodCheckpointCreatedIterator{contract: _IEigenPod.contract, event: "CheckpointCreated", logs: logs, sub: sub}, nil } -// WatchEigenPodStaked is a free log subscription operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// WatchCheckpointCreated is a free log subscription operation binding the contract event 0x575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076. // -// Solidity: event EigenPodStaked(bytes pubkey) -func (_IEigenPod *IEigenPodFilterer) WatchEigenPodStaked(opts *bind.WatchOpts, sink chan<- *IEigenPodEigenPodStaked) (event.Subscription, error) { +// Solidity: event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount) +func (_IEigenPod *IEigenPodFilterer) WatchCheckpointCreated(opts *bind.WatchOpts, sink chan<- *IEigenPodCheckpointCreated, checkpointTimestamp []uint64, beaconBlockRoot [][32]byte) (event.Subscription, error) { - logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "EigenPodStaked") + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var beaconBlockRootRule []interface{} + for _, beaconBlockRootItem := range beaconBlockRoot { + beaconBlockRootRule = append(beaconBlockRootRule, beaconBlockRootItem) + } + + logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "CheckpointCreated", checkpointTimestampRule, beaconBlockRootRule) if err != nil { return nil, err } @@ -892,8 +964,8 @@ func (_IEigenPod *IEigenPodFilterer) WatchEigenPodStaked(opts *bind.WatchOpts, s select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(IEigenPodEigenPodStaked) - if err := _IEigenPod.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { + event := new(IEigenPodCheckpointCreated) + if err := _IEigenPod.contract.UnpackLog(event, "CheckpointCreated", log); err != nil { return err } event.Raw = log @@ -914,21 +986,21 @@ func (_IEigenPod *IEigenPodFilterer) WatchEigenPodStaked(opts *bind.WatchOpts, s }), nil } -// ParseEigenPodStaked is a log parse operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. +// ParseCheckpointCreated is a log parse operation binding the contract event 0x575796133bbed337e5b39aa49a30dc2556a91e0c6c2af4b7b886ae77ebef1076. // -// Solidity: event EigenPodStaked(bytes pubkey) -func (_IEigenPod *IEigenPodFilterer) ParseEigenPodStaked(log types.Log) (*IEigenPodEigenPodStaked, error) { - event := new(IEigenPodEigenPodStaked) - if err := _IEigenPod.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { +// Solidity: event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount) +func (_IEigenPod *IEigenPodFilterer) ParseCheckpointCreated(log types.Log) (*IEigenPodCheckpointCreated, error) { + event := new(IEigenPodCheckpointCreated) + if err := _IEigenPod.contract.UnpackLog(event, "CheckpointCreated", log); err != nil { return nil, err } event.Raw = log return event, nil } -// IEigenPodFullWithdrawalRedeemedIterator is returned from FilterFullWithdrawalRedeemed and is used to iterate over the raw logs and unpacked data for FullWithdrawalRedeemed events raised by the IEigenPod contract. -type IEigenPodFullWithdrawalRedeemedIterator struct { - Event *IEigenPodFullWithdrawalRedeemed // Event containing the contract specifics and raw log +// IEigenPodCheckpointFinalizedIterator is returned from FilterCheckpointFinalized and is used to iterate over the raw logs and unpacked data for CheckpointFinalized events raised by the IEigenPod contract. +type IEigenPodCheckpointFinalizedIterator struct { + Event *IEigenPodCheckpointFinalized // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -942,7 +1014,7 @@ type IEigenPodFullWithdrawalRedeemedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *IEigenPodFullWithdrawalRedeemedIterator) Next() bool { +func (it *IEigenPodCheckpointFinalizedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -951,7 +1023,7 @@ func (it *IEigenPodFullWithdrawalRedeemedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(IEigenPodFullWithdrawalRedeemed) + it.Event = new(IEigenPodCheckpointFinalized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -966,7 +1038,7 @@ func (it *IEigenPodFullWithdrawalRedeemedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(IEigenPodFullWithdrawalRedeemed) + it.Event = new(IEigenPodCheckpointFinalized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -982,54 +1054,52 @@ func (it *IEigenPodFullWithdrawalRedeemedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *IEigenPodFullWithdrawalRedeemedIterator) Error() error { +func (it *IEigenPodCheckpointFinalizedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *IEigenPodFullWithdrawalRedeemedIterator) Close() error { +func (it *IEigenPodCheckpointFinalizedIterator) Close() error { it.sub.Unsubscribe() return nil } -// IEigenPodFullWithdrawalRedeemed represents a FullWithdrawalRedeemed event raised by the IEigenPod contract. -type IEigenPodFullWithdrawalRedeemed struct { - ValidatorIndex *big.Int - WithdrawalTimestamp uint64 - Recipient common.Address - WithdrawalAmountGwei uint64 - Raw types.Log // Blockchain specific contextual infos +// IEigenPodCheckpointFinalized represents a CheckpointFinalized event raised by the IEigenPod contract. +type IEigenPodCheckpointFinalized struct { + CheckpointTimestamp uint64 + TotalShareDeltaWei *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterFullWithdrawalRedeemed is a free log retrieval operation binding the contract event 0xb76a93bb649ece524688f1a01d184e0bbebcda58eae80c28a898bec3fb5a0963. +// FilterCheckpointFinalized is a free log retrieval operation binding the contract event 0x525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44. // -// Solidity: event FullWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 withdrawalAmountGwei) -func (_IEigenPod *IEigenPodFilterer) FilterFullWithdrawalRedeemed(opts *bind.FilterOpts, recipient []common.Address) (*IEigenPodFullWithdrawalRedeemedIterator, error) { +// Solidity: event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei) +func (_IEigenPod *IEigenPodFilterer) FilterCheckpointFinalized(opts *bind.FilterOpts, checkpointTimestamp []uint64) (*IEigenPodCheckpointFinalizedIterator, error) { - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) } - logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "FullWithdrawalRedeemed", recipientRule) + logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "CheckpointFinalized", checkpointTimestampRule) if err != nil { return nil, err } - return &IEigenPodFullWithdrawalRedeemedIterator{contract: _IEigenPod.contract, event: "FullWithdrawalRedeemed", logs: logs, sub: sub}, nil + return &IEigenPodCheckpointFinalizedIterator{contract: _IEigenPod.contract, event: "CheckpointFinalized", logs: logs, sub: sub}, nil } -// WatchFullWithdrawalRedeemed is a free log subscription operation binding the contract event 0xb76a93bb649ece524688f1a01d184e0bbebcda58eae80c28a898bec3fb5a0963. +// WatchCheckpointFinalized is a free log subscription operation binding the contract event 0x525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44. // -// Solidity: event FullWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 withdrawalAmountGwei) -func (_IEigenPod *IEigenPodFilterer) WatchFullWithdrawalRedeemed(opts *bind.WatchOpts, sink chan<- *IEigenPodFullWithdrawalRedeemed, recipient []common.Address) (event.Subscription, error) { +// Solidity: event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei) +func (_IEigenPod *IEigenPodFilterer) WatchCheckpointFinalized(opts *bind.WatchOpts, sink chan<- *IEigenPodCheckpointFinalized, checkpointTimestamp []uint64) (event.Subscription, error) { - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) } - logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "FullWithdrawalRedeemed", recipientRule) + logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "CheckpointFinalized", checkpointTimestampRule) if err != nil { return nil, err } @@ -1039,8 +1109,8 @@ func (_IEigenPod *IEigenPodFilterer) WatchFullWithdrawalRedeemed(opts *bind.Watc select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(IEigenPodFullWithdrawalRedeemed) - if err := _IEigenPod.contract.UnpackLog(event, "FullWithdrawalRedeemed", log); err != nil { + event := new(IEigenPodCheckpointFinalized) + if err := _IEigenPod.contract.UnpackLog(event, "CheckpointFinalized", log); err != nil { return err } event.Raw = log @@ -1061,21 +1131,21 @@ func (_IEigenPod *IEigenPodFilterer) WatchFullWithdrawalRedeemed(opts *bind.Watc }), nil } -// ParseFullWithdrawalRedeemed is a log parse operation binding the contract event 0xb76a93bb649ece524688f1a01d184e0bbebcda58eae80c28a898bec3fb5a0963. +// ParseCheckpointFinalized is a log parse operation binding the contract event 0x525408c201bc1576eb44116f6478f1c2a54775b19a043bcfdc708364f74f8e44. // -// Solidity: event FullWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 withdrawalAmountGwei) -func (_IEigenPod *IEigenPodFilterer) ParseFullWithdrawalRedeemed(log types.Log) (*IEigenPodFullWithdrawalRedeemed, error) { - event := new(IEigenPodFullWithdrawalRedeemed) - if err := _IEigenPod.contract.UnpackLog(event, "FullWithdrawalRedeemed", log); err != nil { +// Solidity: event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei) +func (_IEigenPod *IEigenPodFilterer) ParseCheckpointFinalized(log types.Log) (*IEigenPodCheckpointFinalized, error) { + event := new(IEigenPodCheckpointFinalized) + if err := _IEigenPod.contract.UnpackLog(event, "CheckpointFinalized", log); err != nil { return nil, err } event.Raw = log return event, nil } -// IEigenPodNonBeaconChainETHReceivedIterator is returned from FilterNonBeaconChainETHReceived and is used to iterate over the raw logs and unpacked data for NonBeaconChainETHReceived events raised by the IEigenPod contract. -type IEigenPodNonBeaconChainETHReceivedIterator struct { - Event *IEigenPodNonBeaconChainETHReceived // Event containing the contract specifics and raw log +// IEigenPodEigenPodStakedIterator is returned from FilterEigenPodStaked and is used to iterate over the raw logs and unpacked data for EigenPodStaked events raised by the IEigenPod contract. +type IEigenPodEigenPodStakedIterator struct { + Event *IEigenPodEigenPodStaked // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1089,7 +1159,7 @@ type IEigenPodNonBeaconChainETHReceivedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *IEigenPodNonBeaconChainETHReceivedIterator) Next() bool { +func (it *IEigenPodEigenPodStakedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1098,7 +1168,7 @@ func (it *IEigenPodNonBeaconChainETHReceivedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(IEigenPodNonBeaconChainETHReceived) + it.Event = new(IEigenPodEigenPodStaked) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1113,7 +1183,7 @@ func (it *IEigenPodNonBeaconChainETHReceivedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(IEigenPodNonBeaconChainETHReceived) + it.Event = new(IEigenPodEigenPodStaked) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1129,41 +1199,41 @@ func (it *IEigenPodNonBeaconChainETHReceivedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *IEigenPodNonBeaconChainETHReceivedIterator) Error() error { +func (it *IEigenPodEigenPodStakedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *IEigenPodNonBeaconChainETHReceivedIterator) Close() error { +func (it *IEigenPodEigenPodStakedIterator) Close() error { it.sub.Unsubscribe() return nil } -// IEigenPodNonBeaconChainETHReceived represents a NonBeaconChainETHReceived event raised by the IEigenPod contract. -type IEigenPodNonBeaconChainETHReceived struct { - AmountReceived *big.Int - Raw types.Log // Blockchain specific contextual infos +// IEigenPodEigenPodStaked represents a EigenPodStaked event raised by the IEigenPod contract. +type IEigenPodEigenPodStaked struct { + Pubkey []byte + Raw types.Log // Blockchain specific contextual infos } -// FilterNonBeaconChainETHReceived is a free log retrieval operation binding the contract event 0x6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf49. +// FilterEigenPodStaked is a free log retrieval operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. // -// Solidity: event NonBeaconChainETHReceived(uint256 amountReceived) -func (_IEigenPod *IEigenPodFilterer) FilterNonBeaconChainETHReceived(opts *bind.FilterOpts) (*IEigenPodNonBeaconChainETHReceivedIterator, error) { +// Solidity: event EigenPodStaked(bytes pubkey) +func (_IEigenPod *IEigenPodFilterer) FilterEigenPodStaked(opts *bind.FilterOpts) (*IEigenPodEigenPodStakedIterator, error) { - logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "NonBeaconChainETHReceived") + logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "EigenPodStaked") if err != nil { return nil, err } - return &IEigenPodNonBeaconChainETHReceivedIterator{contract: _IEigenPod.contract, event: "NonBeaconChainETHReceived", logs: logs, sub: sub}, nil + return &IEigenPodEigenPodStakedIterator{contract: _IEigenPod.contract, event: "EigenPodStaked", logs: logs, sub: sub}, nil } -// WatchNonBeaconChainETHReceived is a free log subscription operation binding the contract event 0x6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf49. +// WatchEigenPodStaked is a free log subscription operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. // -// Solidity: event NonBeaconChainETHReceived(uint256 amountReceived) -func (_IEigenPod *IEigenPodFilterer) WatchNonBeaconChainETHReceived(opts *bind.WatchOpts, sink chan<- *IEigenPodNonBeaconChainETHReceived) (event.Subscription, error) { +// Solidity: event EigenPodStaked(bytes pubkey) +func (_IEigenPod *IEigenPodFilterer) WatchEigenPodStaked(opts *bind.WatchOpts, sink chan<- *IEigenPodEigenPodStaked) (event.Subscription, error) { - logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "NonBeaconChainETHReceived") + logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "EigenPodStaked") if err != nil { return nil, err } @@ -1173,8 +1243,8 @@ func (_IEigenPod *IEigenPodFilterer) WatchNonBeaconChainETHReceived(opts *bind.W select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(IEigenPodNonBeaconChainETHReceived) - if err := _IEigenPod.contract.UnpackLog(event, "NonBeaconChainETHReceived", log); err != nil { + event := new(IEigenPodEigenPodStaked) + if err := _IEigenPod.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { return err } event.Raw = log @@ -1195,21 +1265,21 @@ func (_IEigenPod *IEigenPodFilterer) WatchNonBeaconChainETHReceived(opts *bind.W }), nil } -// ParseNonBeaconChainETHReceived is a log parse operation binding the contract event 0x6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf49. +// ParseEigenPodStaked is a log parse operation binding the contract event 0x606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e23. // -// Solidity: event NonBeaconChainETHReceived(uint256 amountReceived) -func (_IEigenPod *IEigenPodFilterer) ParseNonBeaconChainETHReceived(log types.Log) (*IEigenPodNonBeaconChainETHReceived, error) { - event := new(IEigenPodNonBeaconChainETHReceived) - if err := _IEigenPod.contract.UnpackLog(event, "NonBeaconChainETHReceived", log); err != nil { +// Solidity: event EigenPodStaked(bytes pubkey) +func (_IEigenPod *IEigenPodFilterer) ParseEigenPodStaked(log types.Log) (*IEigenPodEigenPodStaked, error) { + event := new(IEigenPodEigenPodStaked) + if err := _IEigenPod.contract.UnpackLog(event, "EigenPodStaked", log); err != nil { return nil, err } event.Raw = log return event, nil } -// IEigenPodNonBeaconChainETHWithdrawnIterator is returned from FilterNonBeaconChainETHWithdrawn and is used to iterate over the raw logs and unpacked data for NonBeaconChainETHWithdrawn events raised by the IEigenPod contract. -type IEigenPodNonBeaconChainETHWithdrawnIterator struct { - Event *IEigenPodNonBeaconChainETHWithdrawn // Event containing the contract specifics and raw log +// IEigenPodNonBeaconChainETHReceivedIterator is returned from FilterNonBeaconChainETHReceived and is used to iterate over the raw logs and unpacked data for NonBeaconChainETHReceived events raised by the IEigenPod contract. +type IEigenPodNonBeaconChainETHReceivedIterator struct { + Event *IEigenPodNonBeaconChainETHReceived // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1223,7 +1293,7 @@ type IEigenPodNonBeaconChainETHWithdrawnIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *IEigenPodNonBeaconChainETHWithdrawnIterator) Next() bool { +func (it *IEigenPodNonBeaconChainETHReceivedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1232,7 +1302,7 @@ func (it *IEigenPodNonBeaconChainETHWithdrawnIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(IEigenPodNonBeaconChainETHWithdrawn) + it.Event = new(IEigenPodNonBeaconChainETHReceived) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1247,7 +1317,7 @@ func (it *IEigenPodNonBeaconChainETHWithdrawnIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(IEigenPodNonBeaconChainETHWithdrawn) + it.Event = new(IEigenPodNonBeaconChainETHReceived) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1263,52 +1333,41 @@ func (it *IEigenPodNonBeaconChainETHWithdrawnIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *IEigenPodNonBeaconChainETHWithdrawnIterator) Error() error { +func (it *IEigenPodNonBeaconChainETHReceivedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *IEigenPodNonBeaconChainETHWithdrawnIterator) Close() error { +func (it *IEigenPodNonBeaconChainETHReceivedIterator) Close() error { it.sub.Unsubscribe() return nil } -// IEigenPodNonBeaconChainETHWithdrawn represents a NonBeaconChainETHWithdrawn event raised by the IEigenPod contract. -type IEigenPodNonBeaconChainETHWithdrawn struct { - Recipient common.Address - AmountWithdrawn *big.Int - Raw types.Log // Blockchain specific contextual infos +// IEigenPodNonBeaconChainETHReceived represents a NonBeaconChainETHReceived event raised by the IEigenPod contract. +type IEigenPodNonBeaconChainETHReceived struct { + AmountReceived *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterNonBeaconChainETHWithdrawn is a free log retrieval operation binding the contract event 0x30420aacd028abb3c1fd03aba253ae725d6ddd52d16c9ac4cb5742cd43f53096. +// FilterNonBeaconChainETHReceived is a free log retrieval operation binding the contract event 0x6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf49. // -// Solidity: event NonBeaconChainETHWithdrawn(address indexed recipient, uint256 amountWithdrawn) -func (_IEigenPod *IEigenPodFilterer) FilterNonBeaconChainETHWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*IEigenPodNonBeaconChainETHWithdrawnIterator, error) { - - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) - } +// Solidity: event NonBeaconChainETHReceived(uint256 amountReceived) +func (_IEigenPod *IEigenPodFilterer) FilterNonBeaconChainETHReceived(opts *bind.FilterOpts) (*IEigenPodNonBeaconChainETHReceivedIterator, error) { - logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "NonBeaconChainETHWithdrawn", recipientRule) + logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "NonBeaconChainETHReceived") if err != nil { return nil, err } - return &IEigenPodNonBeaconChainETHWithdrawnIterator{contract: _IEigenPod.contract, event: "NonBeaconChainETHWithdrawn", logs: logs, sub: sub}, nil + return &IEigenPodNonBeaconChainETHReceivedIterator{contract: _IEigenPod.contract, event: "NonBeaconChainETHReceived", logs: logs, sub: sub}, nil } -// WatchNonBeaconChainETHWithdrawn is a free log subscription operation binding the contract event 0x30420aacd028abb3c1fd03aba253ae725d6ddd52d16c9ac4cb5742cd43f53096. +// WatchNonBeaconChainETHReceived is a free log subscription operation binding the contract event 0x6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf49. // -// Solidity: event NonBeaconChainETHWithdrawn(address indexed recipient, uint256 amountWithdrawn) -func (_IEigenPod *IEigenPodFilterer) WatchNonBeaconChainETHWithdrawn(opts *bind.WatchOpts, sink chan<- *IEigenPodNonBeaconChainETHWithdrawn, recipient []common.Address) (event.Subscription, error) { - - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) - } +// Solidity: event NonBeaconChainETHReceived(uint256 amountReceived) +func (_IEigenPod *IEigenPodFilterer) WatchNonBeaconChainETHReceived(opts *bind.WatchOpts, sink chan<- *IEigenPodNonBeaconChainETHReceived) (event.Subscription, error) { - logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "NonBeaconChainETHWithdrawn", recipientRule) + logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "NonBeaconChainETHReceived") if err != nil { return nil, err } @@ -1318,8 +1377,8 @@ func (_IEigenPod *IEigenPodFilterer) WatchNonBeaconChainETHWithdrawn(opts *bind. select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(IEigenPodNonBeaconChainETHWithdrawn) - if err := _IEigenPod.contract.UnpackLog(event, "NonBeaconChainETHWithdrawn", log); err != nil { + event := new(IEigenPodNonBeaconChainETHReceived) + if err := _IEigenPod.contract.UnpackLog(event, "NonBeaconChainETHReceived", log); err != nil { return err } event.Raw = log @@ -1340,21 +1399,21 @@ func (_IEigenPod *IEigenPodFilterer) WatchNonBeaconChainETHWithdrawn(opts *bind. }), nil } -// ParseNonBeaconChainETHWithdrawn is a log parse operation binding the contract event 0x30420aacd028abb3c1fd03aba253ae725d6ddd52d16c9ac4cb5742cd43f53096. +// ParseNonBeaconChainETHReceived is a log parse operation binding the contract event 0x6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf49. // -// Solidity: event NonBeaconChainETHWithdrawn(address indexed recipient, uint256 amountWithdrawn) -func (_IEigenPod *IEigenPodFilterer) ParseNonBeaconChainETHWithdrawn(log types.Log) (*IEigenPodNonBeaconChainETHWithdrawn, error) { - event := new(IEigenPodNonBeaconChainETHWithdrawn) - if err := _IEigenPod.contract.UnpackLog(event, "NonBeaconChainETHWithdrawn", log); err != nil { +// Solidity: event NonBeaconChainETHReceived(uint256 amountReceived) +func (_IEigenPod *IEigenPodFilterer) ParseNonBeaconChainETHReceived(log types.Log) (*IEigenPodNonBeaconChainETHReceived, error) { + event := new(IEigenPodNonBeaconChainETHReceived) + if err := _IEigenPod.contract.UnpackLog(event, "NonBeaconChainETHReceived", log); err != nil { return nil, err } event.Raw = log return event, nil } -// IEigenPodPartialWithdrawalRedeemedIterator is returned from FilterPartialWithdrawalRedeemed and is used to iterate over the raw logs and unpacked data for PartialWithdrawalRedeemed events raised by the IEigenPod contract. -type IEigenPodPartialWithdrawalRedeemedIterator struct { - Event *IEigenPodPartialWithdrawalRedeemed // Event containing the contract specifics and raw log +// IEigenPodProofSubmitterUpdatedIterator is returned from FilterProofSubmitterUpdated and is used to iterate over the raw logs and unpacked data for ProofSubmitterUpdated events raised by the IEigenPod contract. +type IEigenPodProofSubmitterUpdatedIterator struct { + Event *IEigenPodProofSubmitterUpdated // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1368,7 +1427,7 @@ type IEigenPodPartialWithdrawalRedeemedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *IEigenPodPartialWithdrawalRedeemedIterator) Next() bool { +func (it *IEigenPodProofSubmitterUpdatedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1377,7 +1436,7 @@ func (it *IEigenPodPartialWithdrawalRedeemedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(IEigenPodPartialWithdrawalRedeemed) + it.Event = new(IEigenPodProofSubmitterUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1392,7 +1451,7 @@ func (it *IEigenPodPartialWithdrawalRedeemedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(IEigenPodPartialWithdrawalRedeemed) + it.Event = new(IEigenPodProofSubmitterUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1408,54 +1467,42 @@ func (it *IEigenPodPartialWithdrawalRedeemedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *IEigenPodPartialWithdrawalRedeemedIterator) Error() error { +func (it *IEigenPodProofSubmitterUpdatedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *IEigenPodPartialWithdrawalRedeemedIterator) Close() error { +func (it *IEigenPodProofSubmitterUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -// IEigenPodPartialWithdrawalRedeemed represents a PartialWithdrawalRedeemed event raised by the IEigenPod contract. -type IEigenPodPartialWithdrawalRedeemed struct { - ValidatorIndex *big.Int - WithdrawalTimestamp uint64 - Recipient common.Address - PartialWithdrawalAmountGwei uint64 - Raw types.Log // Blockchain specific contextual infos +// IEigenPodProofSubmitterUpdated represents a ProofSubmitterUpdated event raised by the IEigenPod contract. +type IEigenPodProofSubmitterUpdated struct { + PrevProofSubmitter common.Address + NewProofSubmitter common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterPartialWithdrawalRedeemed is a free log retrieval operation binding the contract event 0x8a7335714231dbd551aaba6314f4a97a14c201e53a3e25e1140325cdf67d7a4e. +// FilterProofSubmitterUpdated is a free log retrieval operation binding the contract event 0xfb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac. // -// Solidity: event PartialWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 partialWithdrawalAmountGwei) -func (_IEigenPod *IEigenPodFilterer) FilterPartialWithdrawalRedeemed(opts *bind.FilterOpts, recipient []common.Address) (*IEigenPodPartialWithdrawalRedeemedIterator, error) { +// Solidity: event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter) +func (_IEigenPod *IEigenPodFilterer) FilterProofSubmitterUpdated(opts *bind.FilterOpts) (*IEigenPodProofSubmitterUpdatedIterator, error) { - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) - } - - logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "PartialWithdrawalRedeemed", recipientRule) + logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "ProofSubmitterUpdated") if err != nil { return nil, err } - return &IEigenPodPartialWithdrawalRedeemedIterator{contract: _IEigenPod.contract, event: "PartialWithdrawalRedeemed", logs: logs, sub: sub}, nil + return &IEigenPodProofSubmitterUpdatedIterator{contract: _IEigenPod.contract, event: "ProofSubmitterUpdated", logs: logs, sub: sub}, nil } -// WatchPartialWithdrawalRedeemed is a free log subscription operation binding the contract event 0x8a7335714231dbd551aaba6314f4a97a14c201e53a3e25e1140325cdf67d7a4e. +// WatchProofSubmitterUpdated is a free log subscription operation binding the contract event 0xfb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac. // -// Solidity: event PartialWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 partialWithdrawalAmountGwei) -func (_IEigenPod *IEigenPodFilterer) WatchPartialWithdrawalRedeemed(opts *bind.WatchOpts, sink chan<- *IEigenPodPartialWithdrawalRedeemed, recipient []common.Address) (event.Subscription, error) { - - var recipientRule []interface{} - for _, recipientItem := range recipient { - recipientRule = append(recipientRule, recipientItem) - } +// Solidity: event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter) +func (_IEigenPod *IEigenPodFilterer) WatchProofSubmitterUpdated(opts *bind.WatchOpts, sink chan<- *IEigenPodProofSubmitterUpdated) (event.Subscription, error) { - logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "PartialWithdrawalRedeemed", recipientRule) + logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "ProofSubmitterUpdated") if err != nil { return nil, err } @@ -1465,8 +1512,8 @@ func (_IEigenPod *IEigenPodFilterer) WatchPartialWithdrawalRedeemed(opts *bind.W select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(IEigenPodPartialWithdrawalRedeemed) - if err := _IEigenPod.contract.UnpackLog(event, "PartialWithdrawalRedeemed", log); err != nil { + event := new(IEigenPodProofSubmitterUpdated) + if err := _IEigenPod.contract.UnpackLog(event, "ProofSubmitterUpdated", log); err != nil { return err } event.Raw = log @@ -1487,12 +1534,12 @@ func (_IEigenPod *IEigenPodFilterer) WatchPartialWithdrawalRedeemed(opts *bind.W }), nil } -// ParsePartialWithdrawalRedeemed is a log parse operation binding the contract event 0x8a7335714231dbd551aaba6314f4a97a14c201e53a3e25e1140325cdf67d7a4e. +// ParseProofSubmitterUpdated is a log parse operation binding the contract event 0xfb8129080a19d34dceac04ba253fc50304dc86c729bd63cdca4a969ad19a5eac. // -// Solidity: event PartialWithdrawalRedeemed(uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 partialWithdrawalAmountGwei) -func (_IEigenPod *IEigenPodFilterer) ParsePartialWithdrawalRedeemed(log types.Log) (*IEigenPodPartialWithdrawalRedeemed, error) { - event := new(IEigenPodPartialWithdrawalRedeemed) - if err := _IEigenPod.contract.UnpackLog(event, "PartialWithdrawalRedeemed", log); err != nil { +// Solidity: event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter) +func (_IEigenPod *IEigenPodFilterer) ParseProofSubmitterUpdated(log types.Log) (*IEigenPodProofSubmitterUpdated, error) { + event := new(IEigenPodProofSubmitterUpdated) + if err := _IEigenPod.contract.UnpackLog(event, "ProofSubmitterUpdated", log); err != nil { return nil, err } event.Raw = log @@ -1644,9 +1691,9 @@ func (_IEigenPod *IEigenPodFilterer) ParseRestakedBeaconChainETHWithdrawn(log ty return event, nil } -// IEigenPodRestakingActivatedIterator is returned from FilterRestakingActivated and is used to iterate over the raw logs and unpacked data for RestakingActivated events raised by the IEigenPod contract. -type IEigenPodRestakingActivatedIterator struct { - Event *IEigenPodRestakingActivated // Event containing the contract specifics and raw log +// IEigenPodValidatorBalanceUpdatedIterator is returned from FilterValidatorBalanceUpdated and is used to iterate over the raw logs and unpacked data for ValidatorBalanceUpdated events raised by the IEigenPod contract. +type IEigenPodValidatorBalanceUpdatedIterator struct { + Event *IEigenPodValidatorBalanceUpdated // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1660,7 +1707,7 @@ type IEigenPodRestakingActivatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *IEigenPodRestakingActivatedIterator) Next() bool { +func (it *IEigenPodValidatorBalanceUpdatedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1669,7 +1716,7 @@ func (it *IEigenPodRestakingActivatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(IEigenPodRestakingActivated) + it.Event = new(IEigenPodValidatorBalanceUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1684,7 +1731,7 @@ func (it *IEigenPodRestakingActivatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(IEigenPodRestakingActivated) + it.Event = new(IEigenPodValidatorBalanceUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1700,51 +1747,43 @@ func (it *IEigenPodRestakingActivatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *IEigenPodRestakingActivatedIterator) Error() error { +func (it *IEigenPodValidatorBalanceUpdatedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *IEigenPodRestakingActivatedIterator) Close() error { +func (it *IEigenPodValidatorBalanceUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -// IEigenPodRestakingActivated represents a RestakingActivated event raised by the IEigenPod contract. -type IEigenPodRestakingActivated struct { - PodOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// IEigenPodValidatorBalanceUpdated represents a ValidatorBalanceUpdated event raised by the IEigenPod contract. +type IEigenPodValidatorBalanceUpdated struct { + ValidatorIndex *big.Int + BalanceTimestamp uint64 + NewValidatorBalanceGwei uint64 + Raw types.Log // Blockchain specific contextual infos } -// FilterRestakingActivated is a free log retrieval operation binding the contract event 0xca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd. +// FilterValidatorBalanceUpdated is a free log retrieval operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. // -// Solidity: event RestakingActivated(address indexed podOwner) -func (_IEigenPod *IEigenPodFilterer) FilterRestakingActivated(opts *bind.FilterOpts, podOwner []common.Address) (*IEigenPodRestakingActivatedIterator, error) { - - var podOwnerRule []interface{} - for _, podOwnerItem := range podOwner { - podOwnerRule = append(podOwnerRule, podOwnerItem) - } +// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) +func (_IEigenPod *IEigenPodFilterer) FilterValidatorBalanceUpdated(opts *bind.FilterOpts) (*IEigenPodValidatorBalanceUpdatedIterator, error) { - logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "RestakingActivated", podOwnerRule) + logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "ValidatorBalanceUpdated") if err != nil { return nil, err } - return &IEigenPodRestakingActivatedIterator{contract: _IEigenPod.contract, event: "RestakingActivated", logs: logs, sub: sub}, nil + return &IEigenPodValidatorBalanceUpdatedIterator{contract: _IEigenPod.contract, event: "ValidatorBalanceUpdated", logs: logs, sub: sub}, nil } -// WatchRestakingActivated is a free log subscription operation binding the contract event 0xca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd. +// WatchValidatorBalanceUpdated is a free log subscription operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. // -// Solidity: event RestakingActivated(address indexed podOwner) -func (_IEigenPod *IEigenPodFilterer) WatchRestakingActivated(opts *bind.WatchOpts, sink chan<- *IEigenPodRestakingActivated, podOwner []common.Address) (event.Subscription, error) { - - var podOwnerRule []interface{} - for _, podOwnerItem := range podOwner { - podOwnerRule = append(podOwnerRule, podOwnerItem) - } +// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) +func (_IEigenPod *IEigenPodFilterer) WatchValidatorBalanceUpdated(opts *bind.WatchOpts, sink chan<- *IEigenPodValidatorBalanceUpdated) (event.Subscription, error) { - logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "RestakingActivated", podOwnerRule) + logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "ValidatorBalanceUpdated") if err != nil { return nil, err } @@ -1754,8 +1793,8 @@ func (_IEigenPod *IEigenPodFilterer) WatchRestakingActivated(opts *bind.WatchOpt select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(IEigenPodRestakingActivated) - if err := _IEigenPod.contract.UnpackLog(event, "RestakingActivated", log); err != nil { + event := new(IEigenPodValidatorBalanceUpdated) + if err := _IEigenPod.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { return err } event.Raw = log @@ -1776,21 +1815,21 @@ func (_IEigenPod *IEigenPodFilterer) WatchRestakingActivated(opts *bind.WatchOpt }), nil } -// ParseRestakingActivated is a log parse operation binding the contract event 0xca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd. +// ParseValidatorBalanceUpdated is a log parse operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. // -// Solidity: event RestakingActivated(address indexed podOwner) -func (_IEigenPod *IEigenPodFilterer) ParseRestakingActivated(log types.Log) (*IEigenPodRestakingActivated, error) { - event := new(IEigenPodRestakingActivated) - if err := _IEigenPod.contract.UnpackLog(event, "RestakingActivated", log); err != nil { +// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) +func (_IEigenPod *IEigenPodFilterer) ParseValidatorBalanceUpdated(log types.Log) (*IEigenPodValidatorBalanceUpdated, error) { + event := new(IEigenPodValidatorBalanceUpdated) + if err := _IEigenPod.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -// IEigenPodValidatorBalanceUpdatedIterator is returned from FilterValidatorBalanceUpdated and is used to iterate over the raw logs and unpacked data for ValidatorBalanceUpdated events raised by the IEigenPod contract. -type IEigenPodValidatorBalanceUpdatedIterator struct { - Event *IEigenPodValidatorBalanceUpdated // Event containing the contract specifics and raw log +// IEigenPodValidatorCheckpointedIterator is returned from FilterValidatorCheckpointed and is used to iterate over the raw logs and unpacked data for ValidatorCheckpointed events raised by the IEigenPod contract. +type IEigenPodValidatorCheckpointedIterator struct { + Event *IEigenPodValidatorCheckpointed // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1804,7 +1843,7 @@ type IEigenPodValidatorBalanceUpdatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *IEigenPodValidatorBalanceUpdatedIterator) Next() bool { +func (it *IEigenPodValidatorCheckpointedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1813,7 +1852,7 @@ func (it *IEigenPodValidatorBalanceUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(IEigenPodValidatorBalanceUpdated) + it.Event = new(IEigenPodValidatorCheckpointed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1828,7 +1867,7 @@ func (it *IEigenPodValidatorBalanceUpdatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(IEigenPodValidatorBalanceUpdated) + it.Event = new(IEigenPodValidatorCheckpointed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1844,43 +1883,60 @@ func (it *IEigenPodValidatorBalanceUpdatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *IEigenPodValidatorBalanceUpdatedIterator) Error() error { +func (it *IEigenPodValidatorCheckpointedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *IEigenPodValidatorBalanceUpdatedIterator) Close() error { +func (it *IEigenPodValidatorCheckpointedIterator) Close() error { it.sub.Unsubscribe() return nil } -// IEigenPodValidatorBalanceUpdated represents a ValidatorBalanceUpdated event raised by the IEigenPod contract. -type IEigenPodValidatorBalanceUpdated struct { - ValidatorIndex *big.Int - BalanceTimestamp uint64 - NewValidatorBalanceGwei uint64 - Raw types.Log // Blockchain specific contextual infos +// IEigenPodValidatorCheckpointed represents a ValidatorCheckpointed event raised by the IEigenPod contract. +type IEigenPodValidatorCheckpointed struct { + CheckpointTimestamp uint64 + ValidatorIndex *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterValidatorBalanceUpdated is a free log retrieval operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. +// FilterValidatorCheckpointed is a free log retrieval operation binding the contract event 0xa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f. // -// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) -func (_IEigenPod *IEigenPodFilterer) FilterValidatorBalanceUpdated(opts *bind.FilterOpts) (*IEigenPodValidatorBalanceUpdatedIterator, error) { +// Solidity: event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_IEigenPod *IEigenPodFilterer) FilterValidatorCheckpointed(opts *bind.FilterOpts, checkpointTimestamp []uint64, validatorIndex []*big.Int) (*IEigenPodValidatorCheckpointedIterator, error) { - logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "ValidatorBalanceUpdated") + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "ValidatorCheckpointed", checkpointTimestampRule, validatorIndexRule) if err != nil { return nil, err } - return &IEigenPodValidatorBalanceUpdatedIterator{contract: _IEigenPod.contract, event: "ValidatorBalanceUpdated", logs: logs, sub: sub}, nil + return &IEigenPodValidatorCheckpointedIterator{contract: _IEigenPod.contract, event: "ValidatorCheckpointed", logs: logs, sub: sub}, nil } -// WatchValidatorBalanceUpdated is a free log subscription operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. +// WatchValidatorCheckpointed is a free log subscription operation binding the contract event 0xa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f. // -// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) -func (_IEigenPod *IEigenPodFilterer) WatchValidatorBalanceUpdated(opts *bind.WatchOpts, sink chan<- *IEigenPodValidatorBalanceUpdated) (event.Subscription, error) { +// Solidity: event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_IEigenPod *IEigenPodFilterer) WatchValidatorCheckpointed(opts *bind.WatchOpts, sink chan<- *IEigenPodValidatorCheckpointed, checkpointTimestamp []uint64, validatorIndex []*big.Int) (event.Subscription, error) { - logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "ValidatorBalanceUpdated") + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "ValidatorCheckpointed", checkpointTimestampRule, validatorIndexRule) if err != nil { return nil, err } @@ -1890,8 +1946,8 @@ func (_IEigenPod *IEigenPodFilterer) WatchValidatorBalanceUpdated(opts *bind.Wat select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(IEigenPodValidatorBalanceUpdated) - if err := _IEigenPod.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { + event := new(IEigenPodValidatorCheckpointed) + if err := _IEigenPod.contract.UnpackLog(event, "ValidatorCheckpointed", log); err != nil { return err } event.Raw = log @@ -1912,12 +1968,12 @@ func (_IEigenPod *IEigenPodFilterer) WatchValidatorBalanceUpdated(opts *bind.Wat }), nil } -// ParseValidatorBalanceUpdated is a log parse operation binding the contract event 0x0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df. +// ParseValidatorCheckpointed is a log parse operation binding the contract event 0xa91c59033c3423e18b54d0acecebb4972f9ea95aedf5f4cae3b677b02eaf3a3f. // -// Solidity: event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei) -func (_IEigenPod *IEigenPodFilterer) ParseValidatorBalanceUpdated(log types.Log) (*IEigenPodValidatorBalanceUpdated, error) { - event := new(IEigenPodValidatorBalanceUpdated) - if err := _IEigenPod.contract.UnpackLog(event, "ValidatorBalanceUpdated", log); err != nil { +// Solidity: event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_IEigenPod *IEigenPodFilterer) ParseValidatorCheckpointed(log types.Log) (*IEigenPodValidatorCheckpointed, error) { + event := new(IEigenPodValidatorCheckpointed) + if err := _IEigenPod.contract.UnpackLog(event, "ValidatorCheckpointed", log); err != nil { return nil, err } event.Raw = log @@ -2057,3 +2113,156 @@ func (_IEigenPod *IEigenPodFilterer) ParseValidatorRestaked(log types.Log) (*IEi event.Raw = log return event, nil } + +// IEigenPodValidatorWithdrawnIterator is returned from FilterValidatorWithdrawn and is used to iterate over the raw logs and unpacked data for ValidatorWithdrawn events raised by the IEigenPod contract. +type IEigenPodValidatorWithdrawnIterator struct { + Event *IEigenPodValidatorWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IEigenPodValidatorWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IEigenPodValidatorWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IEigenPodValidatorWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IEigenPodValidatorWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IEigenPodValidatorWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IEigenPodValidatorWithdrawn represents a ValidatorWithdrawn event raised by the IEigenPod contract. +type IEigenPodValidatorWithdrawn struct { + CheckpointTimestamp uint64 + ValidatorIndex *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorWithdrawn is a free log retrieval operation binding the contract event 0x2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a. +// +// Solidity: event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_IEigenPod *IEigenPodFilterer) FilterValidatorWithdrawn(opts *bind.FilterOpts, checkpointTimestamp []uint64, validatorIndex []*big.Int) (*IEigenPodValidatorWithdrawnIterator, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _IEigenPod.contract.FilterLogs(opts, "ValidatorWithdrawn", checkpointTimestampRule, validatorIndexRule) + if err != nil { + return nil, err + } + return &IEigenPodValidatorWithdrawnIterator{contract: _IEigenPod.contract, event: "ValidatorWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchValidatorWithdrawn is a free log subscription operation binding the contract event 0x2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a. +// +// Solidity: event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_IEigenPod *IEigenPodFilterer) WatchValidatorWithdrawn(opts *bind.WatchOpts, sink chan<- *IEigenPodValidatorWithdrawn, checkpointTimestamp []uint64, validatorIndex []*big.Int) (event.Subscription, error) { + + var checkpointTimestampRule []interface{} + for _, checkpointTimestampItem := range checkpointTimestamp { + checkpointTimestampRule = append(checkpointTimestampRule, checkpointTimestampItem) + } + var validatorIndexRule []interface{} + for _, validatorIndexItem := range validatorIndex { + validatorIndexRule = append(validatorIndexRule, validatorIndexItem) + } + + logs, sub, err := _IEigenPod.contract.WatchLogs(opts, "ValidatorWithdrawn", checkpointTimestampRule, validatorIndexRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IEigenPodValidatorWithdrawn) + if err := _IEigenPod.contract.UnpackLog(event, "ValidatorWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorWithdrawn is a log parse operation binding the contract event 0x2a02361ffa66cf2c2da4682c2355a6adcaa9f6c227b6e6563e68480f9587626a. +// +// Solidity: event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex) +func (_IEigenPod *IEigenPodFilterer) ParseValidatorWithdrawn(log types.Log) (*IEigenPodValidatorWithdrawn, error) { + event := new(IEigenPodValidatorWithdrawn) + if err := _IEigenPod.contract.UnpackLog(event, "ValidatorWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/pkg/bindings/IEigenPodManager/binding.go b/pkg/bindings/IEigenPodManager/binding.go index e4e8150ef..8574aafa1 100644 --- a/pkg/bindings/IEigenPodManager/binding.go +++ b/pkg/bindings/IEigenPodManager/binding.go @@ -31,7 +31,7 @@ var ( // IEigenPodManagerMetaData contains all meta data concerning the IEigenPodManager contract. var IEigenPodManagerMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"function\",\"name\":\"addShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"beaconChainOracle\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeaconChainOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createPod\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"denebForkTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBlockRootAtTimestamp\",\"inputs\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"numPods\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerToPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwnerShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recordBeaconChainETHBalanceUpdate\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setDenebForkTimestamp\",\"inputs\":[{\"name\":\"newDenebForkTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slasher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISlasher\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateBeaconChainOracle\",\"inputs\":[{\"name\":\"newBeaconChainOracle\",\"type\":\"address\",\"internalType\":\"contractIBeaconChainOracle\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSharesAsTokens\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destination\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"BeaconChainETHDeposited\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainETHWithdrawalCompleted\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"nonce\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"delegatedAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconOracleUpdated\",\"inputs\":[{\"name\":\"newOracleAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DenebForkTimestampUpdated\",\"inputs\":[{\"name\":\"newValue\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodDeployed\",\"inputs\":[{\"name\":\"eigenPod\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodSharesUpdated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + ABI: "[{\"type\":\"function\",\"name\":\"addShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createPod\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"eigenPodBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"numPods\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerToPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwnerShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recordBeaconChainETHBalanceUpdate\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slasher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISlasher\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSharesAsTokens\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destination\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"BeaconChainETHDeposited\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainETHWithdrawalCompleted\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"nonce\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"delegatedAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NewTotalShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newTotalShares\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodDeployed\",\"inputs\":[{\"name\":\"eigenPod\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodSharesUpdated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", } // IEigenPodManagerABI is the input ABI used to generate the binding from. @@ -211,68 +211,6 @@ func (_IEigenPodManager *IEigenPodManagerCallerSession) BeaconChainETHStrategy() return _IEigenPodManager.Contract.BeaconChainETHStrategy(&_IEigenPodManager.CallOpts) } -// BeaconChainOracle is a free data retrieval call binding the contract method 0xc052bd61. -// -// Solidity: function beaconChainOracle() view returns(address) -func (_IEigenPodManager *IEigenPodManagerCaller) BeaconChainOracle(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _IEigenPodManager.contract.Call(opts, &out, "beaconChainOracle") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// BeaconChainOracle is a free data retrieval call binding the contract method 0xc052bd61. -// -// Solidity: function beaconChainOracle() view returns(address) -func (_IEigenPodManager *IEigenPodManagerSession) BeaconChainOracle() (common.Address, error) { - return _IEigenPodManager.Contract.BeaconChainOracle(&_IEigenPodManager.CallOpts) -} - -// BeaconChainOracle is a free data retrieval call binding the contract method 0xc052bd61. -// -// Solidity: function beaconChainOracle() view returns(address) -func (_IEigenPodManager *IEigenPodManagerCallerSession) BeaconChainOracle() (common.Address, error) { - return _IEigenPodManager.Contract.BeaconChainOracle(&_IEigenPodManager.CallOpts) -} - -// DenebForkTimestamp is a free data retrieval call binding the contract method 0x44e71c80. -// -// Solidity: function denebForkTimestamp() view returns(uint64) -func (_IEigenPodManager *IEigenPodManagerCaller) DenebForkTimestamp(opts *bind.CallOpts) (uint64, error) { - var out []interface{} - err := _IEigenPodManager.contract.Call(opts, &out, "denebForkTimestamp") - - if err != nil { - return *new(uint64), err - } - - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) - - return out0, err - -} - -// DenebForkTimestamp is a free data retrieval call binding the contract method 0x44e71c80. -// -// Solidity: function denebForkTimestamp() view returns(uint64) -func (_IEigenPodManager *IEigenPodManagerSession) DenebForkTimestamp() (uint64, error) { - return _IEigenPodManager.Contract.DenebForkTimestamp(&_IEigenPodManager.CallOpts) -} - -// DenebForkTimestamp is a free data retrieval call binding the contract method 0x44e71c80. -// -// Solidity: function denebForkTimestamp() view returns(uint64) -func (_IEigenPodManager *IEigenPodManagerCallerSession) DenebForkTimestamp() (uint64, error) { - return _IEigenPodManager.Contract.DenebForkTimestamp(&_IEigenPodManager.CallOpts) -} - // EigenPodBeacon is a free data retrieval call binding the contract method 0x292b7b2b. // // Solidity: function eigenPodBeacon() view returns(address) @@ -335,37 +273,6 @@ func (_IEigenPodManager *IEigenPodManagerCallerSession) EthPOS() (common.Address return _IEigenPodManager.Contract.EthPOS(&_IEigenPodManager.CallOpts) } -// GetBlockRootAtTimestamp is a free data retrieval call binding the contract method 0xd1c64cc9. -// -// Solidity: function getBlockRootAtTimestamp(uint64 timestamp) view returns(bytes32) -func (_IEigenPodManager *IEigenPodManagerCaller) GetBlockRootAtTimestamp(opts *bind.CallOpts, timestamp uint64) ([32]byte, error) { - var out []interface{} - err := _IEigenPodManager.contract.Call(opts, &out, "getBlockRootAtTimestamp", timestamp) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// GetBlockRootAtTimestamp is a free data retrieval call binding the contract method 0xd1c64cc9. -// -// Solidity: function getBlockRootAtTimestamp(uint64 timestamp) view returns(bytes32) -func (_IEigenPodManager *IEigenPodManagerSession) GetBlockRootAtTimestamp(timestamp uint64) ([32]byte, error) { - return _IEigenPodManager.Contract.GetBlockRootAtTimestamp(&_IEigenPodManager.CallOpts, timestamp) -} - -// GetBlockRootAtTimestamp is a free data retrieval call binding the contract method 0xd1c64cc9. -// -// Solidity: function getBlockRootAtTimestamp(uint64 timestamp) view returns(bytes32) -func (_IEigenPodManager *IEigenPodManagerCallerSession) GetBlockRootAtTimestamp(timestamp uint64) ([32]byte, error) { - return _IEigenPodManager.Contract.GetBlockRootAtTimestamp(&_IEigenPodManager.CallOpts, timestamp) -} - // GetPod is a free data retrieval call binding the contract method 0xa38406a3. // // Solidity: function getPod(address podOwner) view returns(address) @@ -802,27 +709,6 @@ func (_IEigenPodManager *IEigenPodManagerTransactorSession) RemoveShares(podOwne return _IEigenPodManager.Contract.RemoveShares(&_IEigenPodManager.TransactOpts, podOwner, shares) } -// SetDenebForkTimestamp is a paid mutator transaction binding the contract method 0x463db038. -// -// Solidity: function setDenebForkTimestamp(uint64 newDenebForkTimestamp) returns() -func (_IEigenPodManager *IEigenPodManagerTransactor) SetDenebForkTimestamp(opts *bind.TransactOpts, newDenebForkTimestamp uint64) (*types.Transaction, error) { - return _IEigenPodManager.contract.Transact(opts, "setDenebForkTimestamp", newDenebForkTimestamp) -} - -// SetDenebForkTimestamp is a paid mutator transaction binding the contract method 0x463db038. -// -// Solidity: function setDenebForkTimestamp(uint64 newDenebForkTimestamp) returns() -func (_IEigenPodManager *IEigenPodManagerSession) SetDenebForkTimestamp(newDenebForkTimestamp uint64) (*types.Transaction, error) { - return _IEigenPodManager.Contract.SetDenebForkTimestamp(&_IEigenPodManager.TransactOpts, newDenebForkTimestamp) -} - -// SetDenebForkTimestamp is a paid mutator transaction binding the contract method 0x463db038. -// -// Solidity: function setDenebForkTimestamp(uint64 newDenebForkTimestamp) returns() -func (_IEigenPodManager *IEigenPodManagerTransactorSession) SetDenebForkTimestamp(newDenebForkTimestamp uint64) (*types.Transaction, error) { - return _IEigenPodManager.Contract.SetDenebForkTimestamp(&_IEigenPodManager.TransactOpts, newDenebForkTimestamp) -} - // SetPauserRegistry is a paid mutator transaction binding the contract method 0x10d67a2f. // // Solidity: function setPauserRegistry(address newPauserRegistry) returns() @@ -886,27 +772,6 @@ func (_IEigenPodManager *IEigenPodManagerTransactorSession) Unpause(newPausedSta return _IEigenPodManager.Contract.Unpause(&_IEigenPodManager.TransactOpts, newPausedStatus) } -// UpdateBeaconChainOracle is a paid mutator transaction binding the contract method 0xc1de3aef. -// -// Solidity: function updateBeaconChainOracle(address newBeaconChainOracle) returns() -func (_IEigenPodManager *IEigenPodManagerTransactor) UpdateBeaconChainOracle(opts *bind.TransactOpts, newBeaconChainOracle common.Address) (*types.Transaction, error) { - return _IEigenPodManager.contract.Transact(opts, "updateBeaconChainOracle", newBeaconChainOracle) -} - -// UpdateBeaconChainOracle is a paid mutator transaction binding the contract method 0xc1de3aef. -// -// Solidity: function updateBeaconChainOracle(address newBeaconChainOracle) returns() -func (_IEigenPodManager *IEigenPodManagerSession) UpdateBeaconChainOracle(newBeaconChainOracle common.Address) (*types.Transaction, error) { - return _IEigenPodManager.Contract.UpdateBeaconChainOracle(&_IEigenPodManager.TransactOpts, newBeaconChainOracle) -} - -// UpdateBeaconChainOracle is a paid mutator transaction binding the contract method 0xc1de3aef. -// -// Solidity: function updateBeaconChainOracle(address newBeaconChainOracle) returns() -func (_IEigenPodManager *IEigenPodManagerTransactorSession) UpdateBeaconChainOracle(newBeaconChainOracle common.Address) (*types.Transaction, error) { - return _IEigenPodManager.Contract.UpdateBeaconChainOracle(&_IEigenPodManager.TransactOpts, newBeaconChainOracle) -} - // WithdrawSharesAsTokens is a paid mutator transaction binding the contract method 0x387b1300. // // Solidity: function withdrawSharesAsTokens(address podOwner, address destination, uint256 shares) returns() @@ -1222,9 +1087,9 @@ func (_IEigenPodManager *IEigenPodManagerFilterer) ParseBeaconChainETHWithdrawal return event, nil } -// IEigenPodManagerBeaconOracleUpdatedIterator is returned from FilterBeaconOracleUpdated and is used to iterate over the raw logs and unpacked data for BeaconOracleUpdated events raised by the IEigenPodManager contract. -type IEigenPodManagerBeaconOracleUpdatedIterator struct { - Event *IEigenPodManagerBeaconOracleUpdated // Event containing the contract specifics and raw log +// IEigenPodManagerNewTotalSharesIterator is returned from FilterNewTotalShares and is used to iterate over the raw logs and unpacked data for NewTotalShares events raised by the IEigenPodManager contract. +type IEigenPodManagerNewTotalSharesIterator struct { + Event *IEigenPodManagerNewTotalShares // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1238,7 +1103,7 @@ type IEigenPodManagerBeaconOracleUpdatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *IEigenPodManagerBeaconOracleUpdatedIterator) Next() bool { +func (it *IEigenPodManagerNewTotalSharesIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1247,7 +1112,7 @@ func (it *IEigenPodManagerBeaconOracleUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(IEigenPodManagerBeaconOracleUpdated) + it.Event = new(IEigenPodManagerNewTotalShares) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1262,7 +1127,7 @@ func (it *IEigenPodManagerBeaconOracleUpdatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(IEigenPodManagerBeaconOracleUpdated) + it.Event = new(IEigenPodManagerNewTotalShares) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1278,185 +1143,52 @@ func (it *IEigenPodManagerBeaconOracleUpdatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *IEigenPodManagerBeaconOracleUpdatedIterator) Error() error { +func (it *IEigenPodManagerNewTotalSharesIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *IEigenPodManagerBeaconOracleUpdatedIterator) Close() error { +func (it *IEigenPodManagerNewTotalSharesIterator) Close() error { it.sub.Unsubscribe() return nil } -// IEigenPodManagerBeaconOracleUpdated represents a BeaconOracleUpdated event raised by the IEigenPodManager contract. -type IEigenPodManagerBeaconOracleUpdated struct { - NewOracleAddress common.Address - Raw types.Log // Blockchain specific contextual infos +// IEigenPodManagerNewTotalShares represents a NewTotalShares event raised by the IEigenPodManager contract. +type IEigenPodManagerNewTotalShares struct { + PodOwner common.Address + NewTotalShares *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterBeaconOracleUpdated is a free log retrieval operation binding the contract event 0x08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f6. +// FilterNewTotalShares is a free log retrieval operation binding the contract event 0xd4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098. // -// Solidity: event BeaconOracleUpdated(address indexed newOracleAddress) -func (_IEigenPodManager *IEigenPodManagerFilterer) FilterBeaconOracleUpdated(opts *bind.FilterOpts, newOracleAddress []common.Address) (*IEigenPodManagerBeaconOracleUpdatedIterator, error) { +// Solidity: event NewTotalShares(address indexed podOwner, int256 newTotalShares) +func (_IEigenPodManager *IEigenPodManagerFilterer) FilterNewTotalShares(opts *bind.FilterOpts, podOwner []common.Address) (*IEigenPodManagerNewTotalSharesIterator, error) { - var newOracleAddressRule []interface{} - for _, newOracleAddressItem := range newOracleAddress { - newOracleAddressRule = append(newOracleAddressRule, newOracleAddressItem) + var podOwnerRule []interface{} + for _, podOwnerItem := range podOwner { + podOwnerRule = append(podOwnerRule, podOwnerItem) } - logs, sub, err := _IEigenPodManager.contract.FilterLogs(opts, "BeaconOracleUpdated", newOracleAddressRule) + logs, sub, err := _IEigenPodManager.contract.FilterLogs(opts, "NewTotalShares", podOwnerRule) if err != nil { return nil, err } - return &IEigenPodManagerBeaconOracleUpdatedIterator{contract: _IEigenPodManager.contract, event: "BeaconOracleUpdated", logs: logs, sub: sub}, nil + return &IEigenPodManagerNewTotalSharesIterator{contract: _IEigenPodManager.contract, event: "NewTotalShares", logs: logs, sub: sub}, nil } -// WatchBeaconOracleUpdated is a free log subscription operation binding the contract event 0x08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f6. +// WatchNewTotalShares is a free log subscription operation binding the contract event 0xd4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098. // -// Solidity: event BeaconOracleUpdated(address indexed newOracleAddress) -func (_IEigenPodManager *IEigenPodManagerFilterer) WatchBeaconOracleUpdated(opts *bind.WatchOpts, sink chan<- *IEigenPodManagerBeaconOracleUpdated, newOracleAddress []common.Address) (event.Subscription, error) { - - var newOracleAddressRule []interface{} - for _, newOracleAddressItem := range newOracleAddress { - newOracleAddressRule = append(newOracleAddressRule, newOracleAddressItem) - } +// Solidity: event NewTotalShares(address indexed podOwner, int256 newTotalShares) +func (_IEigenPodManager *IEigenPodManagerFilterer) WatchNewTotalShares(opts *bind.WatchOpts, sink chan<- *IEigenPodManagerNewTotalShares, podOwner []common.Address) (event.Subscription, error) { - logs, sub, err := _IEigenPodManager.contract.WatchLogs(opts, "BeaconOracleUpdated", newOracleAddressRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(IEigenPodManagerBeaconOracleUpdated) - if err := _IEigenPodManager.contract.UnpackLog(event, "BeaconOracleUpdated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseBeaconOracleUpdated is a log parse operation binding the contract event 0x08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f6. -// -// Solidity: event BeaconOracleUpdated(address indexed newOracleAddress) -func (_IEigenPodManager *IEigenPodManagerFilterer) ParseBeaconOracleUpdated(log types.Log) (*IEigenPodManagerBeaconOracleUpdated, error) { - event := new(IEigenPodManagerBeaconOracleUpdated) - if err := _IEigenPodManager.contract.UnpackLog(event, "BeaconOracleUpdated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// IEigenPodManagerDenebForkTimestampUpdatedIterator is returned from FilterDenebForkTimestampUpdated and is used to iterate over the raw logs and unpacked data for DenebForkTimestampUpdated events raised by the IEigenPodManager contract. -type IEigenPodManagerDenebForkTimestampUpdatedIterator struct { - Event *IEigenPodManagerDenebForkTimestampUpdated // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *IEigenPodManagerDenebForkTimestampUpdatedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(IEigenPodManagerDenebForkTimestampUpdated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(IEigenPodManagerDenebForkTimestampUpdated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *IEigenPodManagerDenebForkTimestampUpdatedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *IEigenPodManagerDenebForkTimestampUpdatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// IEigenPodManagerDenebForkTimestampUpdated represents a DenebForkTimestampUpdated event raised by the IEigenPodManager contract. -type IEigenPodManagerDenebForkTimestampUpdated struct { - NewValue uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDenebForkTimestampUpdated is a free log retrieval operation binding the contract event 0x19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db. -// -// Solidity: event DenebForkTimestampUpdated(uint64 newValue) -func (_IEigenPodManager *IEigenPodManagerFilterer) FilterDenebForkTimestampUpdated(opts *bind.FilterOpts) (*IEigenPodManagerDenebForkTimestampUpdatedIterator, error) { - - logs, sub, err := _IEigenPodManager.contract.FilterLogs(opts, "DenebForkTimestampUpdated") - if err != nil { - return nil, err + var podOwnerRule []interface{} + for _, podOwnerItem := range podOwner { + podOwnerRule = append(podOwnerRule, podOwnerItem) } - return &IEigenPodManagerDenebForkTimestampUpdatedIterator{contract: _IEigenPodManager.contract, event: "DenebForkTimestampUpdated", logs: logs, sub: sub}, nil -} - -// WatchDenebForkTimestampUpdated is a free log subscription operation binding the contract event 0x19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db. -// -// Solidity: event DenebForkTimestampUpdated(uint64 newValue) -func (_IEigenPodManager *IEigenPodManagerFilterer) WatchDenebForkTimestampUpdated(opts *bind.WatchOpts, sink chan<- *IEigenPodManagerDenebForkTimestampUpdated) (event.Subscription, error) { - logs, sub, err := _IEigenPodManager.contract.WatchLogs(opts, "DenebForkTimestampUpdated") + logs, sub, err := _IEigenPodManager.contract.WatchLogs(opts, "NewTotalShares", podOwnerRule) if err != nil { return nil, err } @@ -1466,8 +1198,8 @@ func (_IEigenPodManager *IEigenPodManagerFilterer) WatchDenebForkTimestampUpdate select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(IEigenPodManagerDenebForkTimestampUpdated) - if err := _IEigenPodManager.contract.UnpackLog(event, "DenebForkTimestampUpdated", log); err != nil { + event := new(IEigenPodManagerNewTotalShares) + if err := _IEigenPodManager.contract.UnpackLog(event, "NewTotalShares", log); err != nil { return err } event.Raw = log @@ -1488,12 +1220,12 @@ func (_IEigenPodManager *IEigenPodManagerFilterer) WatchDenebForkTimestampUpdate }), nil } -// ParseDenebForkTimestampUpdated is a log parse operation binding the contract event 0x19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db. +// ParseNewTotalShares is a log parse operation binding the contract event 0xd4def76d6d2bed6f14d5cd9af73cc2913d618d00edde42432e81c09bfe077098. // -// Solidity: event DenebForkTimestampUpdated(uint64 newValue) -func (_IEigenPodManager *IEigenPodManagerFilterer) ParseDenebForkTimestampUpdated(log types.Log) (*IEigenPodManagerDenebForkTimestampUpdated, error) { - event := new(IEigenPodManagerDenebForkTimestampUpdated) - if err := _IEigenPodManager.contract.UnpackLog(event, "DenebForkTimestampUpdated", log); err != nil { +// Solidity: event NewTotalShares(address indexed podOwner, int256 newTotalShares) +func (_IEigenPodManager *IEigenPodManagerFilterer) ParseNewTotalShares(log types.Log) (*IEigenPodManagerNewTotalShares, error) { + event := new(IEigenPodManagerNewTotalShares) + if err := _IEigenPodManager.contract.UnpackLog(event, "NewTotalShares", log); err != nil { return nil, err } event.Raw = log diff --git a/pkg/bindings/RewardsCoordinator/binding.go b/pkg/bindings/RewardsCoordinator/binding.go index 8a8a4b60a..b9a0577d4 100644 --- a/pkg/bindings/RewardsCoordinator/binding.go +++ b/pkg/bindings/RewardsCoordinator/binding.go @@ -78,7 +78,7 @@ type IRewardsCoordinatorTokenTreeMerkleLeaf struct { // RewardsCoordinatorMetaData contains all meta data concerning the RewardsCoordinator contract. var RewardsCoordinatorMetaData = &bind.MetaData{ ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_delegationManager\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"},{\"name\":\"_strategyManager\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"},{\"name\":\"_CALCULATION_INTERVAL_SECONDS\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_MAX_REWARDS_DURATION\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_MAX_RETROACTIVE_LENGTH\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_MAX_FUTURE_LENGTH\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"__GENESIS_REWARDS_TIMESTAMP\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"CALCULATION_INTERVAL_SECONDS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"GENESIS_REWARDS_TIMESTAMP\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_FUTURE_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_RETROACTIVE_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_REWARDS_DURATION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"activationDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateEarnerLeafHash\",\"inputs\":[{\"name\":\"leaf\",\"type\":\"tuple\",\"internalType\":\"structIRewardsCoordinator.EarnerTreeMerkleLeaf\",\"components\":[{\"name\":\"earner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"earnerTokenRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"calculateTokenLeafHash\",\"inputs\":[{\"name\":\"leaf\",\"type\":\"tuple\",\"internalType\":\"structIRewardsCoordinator.TokenTreeMerkleLeaf\",\"components\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"cumulativeEarnings\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"checkClaim\",\"inputs\":[{\"name\":\"claim\",\"type\":\"tuple\",\"internalType\":\"structIRewardsCoordinator.RewardsMerkleClaim\",\"components\":[{\"name\":\"rootIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"earnerIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"earnerTreeProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"earnerLeaf\",\"type\":\"tuple\",\"internalType\":\"structIRewardsCoordinator.EarnerTreeMerkleLeaf\",\"components\":[{\"name\":\"earner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"earnerTokenRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"tokenIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"tokenTreeProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"tokenLeaves\",\"type\":\"tuple[]\",\"internalType\":\"structIRewardsCoordinator.TokenTreeMerkleLeaf[]\",\"components\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"cumulativeEarnings\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimerFor\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createAVSRewardsSubmission\",\"inputs\":[{\"name\":\"rewardsSubmissions\",\"type\":\"tuple[]\",\"internalType\":\"structIRewardsCoordinator.RewardsSubmission[]\",\"components\":[{\"name\":\"strategiesAndMultipliers\",\"type\":\"tuple[]\",\"internalType\":\"structIRewardsCoordinator.StrategyAndMultiplier[]\",\"components\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"multiplier\",\"type\":\"uint96\",\"internalType\":\"uint96\"}]},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startTimestamp\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"duration\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createRewardsForAllSubmission\",\"inputs\":[{\"name\":\"rewardsSubmissions\",\"type\":\"tuple[]\",\"internalType\":\"structIRewardsCoordinator.RewardsSubmission[]\",\"components\":[{\"name\":\"strategiesAndMultipliers\",\"type\":\"tuple[]\",\"internalType\":\"structIRewardsCoordinator.StrategyAndMultiplier[]\",\"components\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"multiplier\",\"type\":\"uint96\",\"internalType\":\"uint96\"}]},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startTimestamp\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"duration\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"cumulativeClaimed\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"currRewardsCalculationEndTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"delegationManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"disableRoot\",\"inputs\":[{\"name\":\"rootIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getCurrentClaimableDistributionRoot\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIRewardsCoordinator.DistributionRoot\",\"components\":[{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rewardsCalculationEndTimestamp\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"activatedAt\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"disabled\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getCurrentDistributionRoot\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIRewardsCoordinator.DistributionRoot\",\"components\":[{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rewardsCalculationEndTimestamp\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"activatedAt\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"disabled\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getDistributionRootAtIndex\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIRewardsCoordinator.DistributionRoot\",\"components\":[{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rewardsCalculationEndTimestamp\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"activatedAt\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"disabled\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getDistributionRootsLength\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRootIndexFromHash\",\"inputs\":[{\"name\":\"rootHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalOperatorCommissionBips\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"initialPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_rewardsUpdater\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_activationDelay\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_globalCommissionBips\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isAVSRewardsSubmissionHash\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isRewardsForAllSubmitter\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isRewardsSubmissionForAllHash\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"operatorCommissionBips\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"processClaim\",\"inputs\":[{\"name\":\"claim\",\"type\":\"tuple\",\"internalType\":\"structIRewardsCoordinator.RewardsMerkleClaim\",\"components\":[{\"name\":\"rootIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"earnerIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"earnerTreeProof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"earnerLeaf\",\"type\":\"tuple\",\"internalType\":\"structIRewardsCoordinator.EarnerTreeMerkleLeaf\",\"components\":[{\"name\":\"earner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"earnerTokenRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"tokenIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"tokenTreeProofs\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"tokenLeaves\",\"type\":\"tuple[]\",\"internalType\":\"structIRewardsCoordinator.TokenTreeMerkleLeaf[]\",\"components\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"cumulativeEarnings\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}]},{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"rewardsUpdater\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setActivationDelay\",\"inputs\":[{\"name\":\"_activationDelay\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setClaimerFor\",\"inputs\":[{\"name\":\"claimer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGlobalOperatorCommission\",\"inputs\":[{\"name\":\"_globalCommissionBips\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setRewardsForAllSubmitter\",\"inputs\":[{\"name\":\"_submitter\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_newValue\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setRewardsUpdater\",\"inputs\":[{\"name\":\"_rewardsUpdater\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"submissionNonce\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"submitRoot\",\"inputs\":[{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rewardsCalculationEndTimestamp\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"AVSRewardsSubmissionCreated\",\"inputs\":[{\"name\":\"avs\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"submissionNonce\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"rewardsSubmissionHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"rewardsSubmission\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIRewardsCoordinator.RewardsSubmission\",\"components\":[{\"name\":\"strategiesAndMultipliers\",\"type\":\"tuple[]\",\"internalType\":\"structIRewardsCoordinator.StrategyAndMultiplier[]\",\"components\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"multiplier\",\"type\":\"uint96\",\"internalType\":\"uint96\"}]},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startTimestamp\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"duration\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ActivationDelaySet\",\"inputs\":[{\"name\":\"oldActivationDelay\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"newActivationDelay\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ClaimerForSet\",\"inputs\":[{\"name\":\"earner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"oldClaimer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"claimer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DistributionRootDisabled\",\"inputs\":[{\"name\":\"rootIndex\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DistributionRootSubmitted\",\"inputs\":[{\"name\":\"rootIndex\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"uint32\"},{\"name\":\"root\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"rewardsCalculationEndTimestamp\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"uint32\"},{\"name\":\"activatedAt\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalCommissionBipsSet\",\"inputs\":[{\"name\":\"oldGlobalCommissionBips\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"},{\"name\":\"newGlobalCommissionBips\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RewardsClaimed\",\"inputs\":[{\"name\":\"root\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"earner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"claimer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"token\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIERC20\"},{\"name\":\"claimedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RewardsForAllSubmitterSet\",\"inputs\":[{\"name\":\"rewardsForAllSubmitter\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"oldValue\",\"type\":\"bool\",\"indexed\":true,\"internalType\":\"bool\"},{\"name\":\"newValue\",\"type\":\"bool\",\"indexed\":true,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RewardsSubmissionForAllCreated\",\"inputs\":[{\"name\":\"submitter\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"submissionNonce\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"rewardsSubmissionHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"rewardsSubmission\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIRewardsCoordinator.RewardsSubmission\",\"components\":[{\"name\":\"strategiesAndMultipliers\",\"type\":\"tuple[]\",\"internalType\":\"structIRewardsCoordinator.StrategyAndMultiplier[]\",\"components\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"multiplier\",\"type\":\"uint96\",\"internalType\":\"uint96\"}]},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startTimestamp\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"duration\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RewardsUpdaterSet\",\"inputs\":[{\"name\":\"oldRewardsUpdater\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newRewardsUpdater\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", - Bin: "0x6101806040523480156200001257600080fd5b5060405162004367380380620043678339810160408190526200003591620002e4565b868686868686866200004885826200037e565b63ffffffff1615620000ed5760405162461bcd60e51b815260206004820152606060248201527f52657761726473436f6f7264696e61746f723a2047454e455349535f5245574160448201527f5244535f54494d455354414d50206d7573742062652061206d756c7469706c6560648201527f206f662043414c43554c4154494f4e5f494e54455256414c5f5345434f4e4453608482015260a4015b60405180910390fd5b620000fc62015180866200037e565b63ffffffff16156200019d5760405162461bcd60e51b815260206004820152605760248201527f52657761726473436f6f7264696e61746f723a2043414c43554c4154494f4e5f60448201527f494e54455256414c5f5345434f4e4453206d7573742062652061206d756c746960648201527f706c65206f6620534e415053484f545f434144454e4345000000000000000000608482015260a401620000e4565b6001600160a01b0396871661012052949095166101405263ffffffff92831660805290821660a052811660c05291821660e0521661010052620001df620001f2565b5050466101605250620003b09350505050565b600054610100900460ff16156200025c5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608401620000e4565b60005460ff9081161015620002af576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b0381168114620002c757600080fd5b50565b805163ffffffff81168114620002df57600080fd5b919050565b600080600080600080600060e0888a0312156200030057600080fd5b87516200030d81620002b1565b60208901519097506200032081620002b1565b95506200033060408901620002ca565b94506200034060608901620002ca565b93506200035060808901620002ca565b92506200036060a08901620002ca565b91506200037060c08901620002ca565b905092959891949750929550565b600063ffffffff80841680620003a457634e487b7160e01b600052601260045260246000fd5b92169190910692915050565b60805160a05160c05160e05161010051610120516101405161016051613f20620004476000396000611a640152600081816104c7015261271e015260006107590152600081816103d0015261254d0152600081816102fc01526125f90152600081816104a001526124fc0152600081816106b8015261227301526000818161065e0152818161232a01526124050152613f206000f3fe608060405234801561001057600080fd5b50600436106102ba5760003560e01c8063715018a611610182578063c46db606116100e9578063f2fde38b116100a2578063f96abf2e1161007c578063f96abf2e146107a9578063fabc1cbc146107bc578063fbf1e2c1146107cf578063fce36c7d146107e257600080fd5b8063f2fde38b1461077b578063f698da251461078e578063f8cd84481461079657600080fd5b8063c46db606146106da578063d4540a5514610708578063de02e5031461071b578063e221b2451461072e578063e810ce2114610741578063ea4d3c9b1461075457600080fd5b80639104c3191161013b5780639104c319146106365780639be3d4e4146106515780639d45c28114610659578063a0169ddd14610680578063bb7e451f14610693578063bf21a8aa146106b357600080fd5b8063715018a6146105c45780637b8f8b05146105cc578063863cb9a9146105d4578063865c6953146105e7578063886f1195146106125780638da5cb5b1461062557600080fd5b806337838ed01161022657806358baaa3e116101df57806358baaa3e1461053d578063595c6a67146105505780635ac86ab7146105585780635c975abb1461057b5780635e9d8348146105835780636d21117e1461059657600080fd5b806337838ed01461049b57806339b70e38146104c25780633a8c0786146104e95780633ccc861d146105005780633efe1db6146105135780634d18cc351461052657600080fd5b8063131433b411610278578063131433b4146103cb578063136439dd146103f2578063149bc8721461040557806322f19a64146104265780632b9f64a41461044757806336af41fa1461048857600080fd5b806218572c146102bf57806304a0c502146102f7578063092db007146103335780630e9a53cf1461035b5780630eb38345146103a357806310d67a2f146103b8575b600080fd5b6102e26102cd3660046135a9565b60d16020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016102ee565b60cb5461034890600160e01b900461ffff1681565b60405161ffff90911681526020016102ee565b6103636107f5565b604080518251815260208084015163ffffffff908116918301919091528383015116918101919091526060918201511515918101919091526080016102ee565b6103b66103b13660046135d4565b6108d4565b005b6103b66103c63660046135a9565b610956565b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b6103b661040036600461360d565b610a12565b61041861041336600461363e565b610b51565b6040519081526020016102ee565b61034861043436600461365a565b505060cb54600160e01b900461ffff1690565b6104706104553660046135a9565b60cc602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016102ee565b6103b6610496366004613688565b610bc7565b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b6104707f000000000000000000000000000000000000000000000000000000000000000081565b60cb5461031e90600160a01b900463ffffffff1681565b6103b661050e366004613710565b610e01565b6103b6610521366004613770565b6111c5565b60cb5461031e90600160c01b900463ffffffff1681565b6103b661054b36600461379c565b611496565b6103b66114a7565b6102e26105663660046137b7565b606654600160ff9092169190911b9081161490565b606654610418565b6102e26105913660046137da565b61156e565b6102e26105a436600461380f565b60cf60209081526000928352604080842090915290825290205460ff1681565b6103b66115fb565b60ca54610418565b6103b66105e23660046135a9565b61160f565b6104186105f536600461365a565b60cd60209081526000928352604080842090915290825290205481565b606554610470906001600160a01b031681565b6033546001600160a01b0316610470565b61047073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b610363611620565b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b6103b661068e3660046135a9565b6116be565b6104186106a13660046135a9565b60ce6020526000908152604090205481565b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b6102e26106e836600461380f565b60d060209081526000928352604080842090915290825290205460ff1681565b6103b6610716366004613858565b61171d565b61036361072936600461360d565b611865565b6103b661073c3660046138cb565b6118f7565b61031e61074f36600461360d565b611908565b6104707f000000000000000000000000000000000000000000000000000000000000000081565b6103b66107893660046135a9565b6119ea565b610418611a60565b6104186107a436600461363e565b611a9e565b6103b66107b736600461379c565b611aaf565b6103b66107ca36600461360d565b611ce5565b60cb54610470906001600160a01b031681565b6103b66107f0366004613688565b611e41565b60408051608081018252600080825260208201819052918101829052606081019190915260ca545b80156108d057600060ca6108326001846138fc565b8154811061084257610842613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff1615801560608301819052919250906108b25750806040015163ffffffff164210155b156108bd5792915050565b50806108c881613929565b91505061081d565b5090565b6108dc611fc0565b6001600160a01b038216600081815260d1602052604080822054905160ff9091169284151592841515927f4de6293e668df1398422e1def12118052c1539a03cbfedc145895d48d7685f1c9190a4506001600160a01b0391909116600090815260d160205260409020805460ff1916911515919091179055565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cd9190613940565b6001600160a01b0316336001600160a01b031614610a065760405162461bcd60e51b81526004016109fd9061395d565b60405180910390fd5b610a0f8161201a565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610a5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7e91906139a7565b610a9a5760405162461bcd60e51b81526004016109fd906139c4565b60665481811614610b135760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016109fd565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b600080610b6160208401846135a9565b8360200135604051602001610baa9392919060f89390931b6001600160f81b031916835260609190911b6bffffffffffffffffffffffff19166001830152601582015260350190565b604051602081830303815290604052805190602001209050919050565b60665460019060029081161415610bf05760405162461bcd60e51b81526004016109fd90613a0c565b33600090815260d1602052604090205460ff16610c8f5760405162461bcd60e51b815260206004820152605160248201527f52657761726473436f6f7264696e61746f723a2063616c6c6572206973206e6f60448201527f7420612076616c69642063726561746552657761726473466f72416c6c53756260648201527036b4b9b9b4b7b71039bab136b4ba3a32b960791b608482015260a4016109fd565b60026097541415610cb25760405162461bcd60e51b81526004016109fd90613a43565b600260975560005b82811015610df65736848483818110610cd557610cd5613913565b9050602002810190610ce79190613a7a565b33600081815260ce60209081526040808320549051949550939192610d129290918591879101613bbf565b604051602081830303815290604052805190602001209050610d3383612111565b33600090815260d0602090815260408083208484529091529020805460ff19166001908117909155610d66908390613bef565b33600081815260ce602052604090819020929092559051829184917f51088b8c89628df3a8174002c2a034d0152fce6af8415d651b2a4734bf27048290610dae908890613c07565b60405180910390a4610de0333060408601803590610dcf90602089016135a9565b6001600160a01b03169291906128e9565b5050508080610dee90613c1a565b915050610cba565b505060016097555050565b60665460029060049081161415610e2a5760405162461bcd60e51b81526004016109fd90613a0c565b60026097541415610e4d5760405162461bcd60e51b81526004016109fd90613a43565b6002609755600060ca610e63602086018661379c565b63ffffffff1681548110610e7957610e79613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff16151560608201529050610eda848261295a565b6000610eec60808601606087016135a9565b6001600160a01b03808216600090815260cc60205260409020549192501680610f125750805b336001600160a01b03821614610f905760405162461bcd60e51b815260206004820152603c60248201527f52657761726473436f6f7264696e61746f722e70726f63657373436c61696d3a60448201527f2063616c6c6572206973206e6f742076616c696420636c61696d65720000000060648201526084016109fd565b60005b610fa060a0880188613c35565b90508110156111b75736610fb760e0890189613c86565b83818110610fc757610fc7613913565b6001600160a01b038716600090815260cd602090815260408083209302949094019450929091508290610ffc908501856135a9565b6001600160a01b03166001600160a01b03168152602001908152602001600020549050808260200135116110b65760405162461bcd60e51b815260206004820152605560248201527f52657761726473436f6f7264696e61746f722e70726f63657373436c61696d3a60448201527f2063756d756c61746976654561726e696e6773206d75737420626520677420746064820152741a185b8818dd5b5d5b185d1a5d9950db185a5b5959605a1b608482015260a4016109fd565b60006110c68260208501356138fc565b6001600160a01b038716600090815260cd602090815260408220929350850180359291906110f490876135a9565b6001600160a01b0316815260208082019290925260400160002091909155611136908a908390611126908701876135a9565b6001600160a01b03169190612c26565b86516001600160a01b03808b1691878216918916907f9543dbd55580842586a951f0386e24d68a5df99ae29e3b216588b45fd684ce319061117a60208901896135a9565b604080519283526001600160a01b039091166020830152810186905260600160405180910390a450505080806111af90613c1a565b915050610f93565b505060016097555050505050565b606654600390600890811614156111ee5760405162461bcd60e51b81526004016109fd90613a0c565b60cb546001600160a01b031633146112185760405162461bcd60e51b81526004016109fd90613cd0565b60cb5463ffffffff600160c01b9091048116908316116112b45760405162461bcd60e51b815260206004820152604b60248201527f52657761726473436f6f7264696e61746f722e7375626d6974526f6f743a206e60448201527f657720726f6f74206d75737420626520666f72206e657765722063616c63756c60648201526a185d1959081c195c9a5bd960aa1b608482015260a4016109fd565b428263ffffffff161061134d5760405162461bcd60e51b815260206004820152605560248201527f52657761726473436f6f7264696e61746f722e7375626d6974526f6f743a207260448201527f65776172647343616c63756c6174696f6e456e6454696d657374616d702063616064820152746e6e6f7420626520696e207468652066757475726560581b608482015260a4016109fd565b60ca5460cb5460009061136d90600160a01b900463ffffffff1642613d24565b6040805160808101825287815263ffffffff878116602080840182815286841685870181815260006060880181815260ca8054600181018255925297517f42d72674974f694b5f5159593243114d38a5c39c89d6b62fee061ff523240ee160029092029182015592517f42d72674974f694b5f5159593243114d38a5c39c89d6b62fee061ff523240ee290930180549151975193871667ffffffffffffffff1990921691909117600160201b978716979097029690961760ff60401b1916600160401b921515929092029190911790945560cb805463ffffffff60c01b1916600160c01b840217905593519283529394508892908616917fecd866c3c158fa00bf34d803d5f6023000b57080bcb48af004c2b4b46b3afd08910160405180910390a45050505050565b61149e611fc0565b610a0f81612c56565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156114ef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151391906139a7565b61152f5760405162461bcd60e51b81526004016109fd906139c4565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b60006115f38260ca611583602083018361379c565b63ffffffff168154811061159957611599613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff161515606082015261295a565b506001919050565b611603611fc0565b61160d6000612cc7565b565b611617611fc0565b610a0f81612d19565b60408051608081018252600080825260208201819052918101829052606081019190915260ca8054611654906001906138fc565b8154811061166457611664613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff1615156060820152919050565b33600081815260cc602052604080822080546001600160a01b031981166001600160a01b038781169182179093559251911692839185917fbab947934d42e0ad206f25c9cab18b5bb6ae144acfb00f40b4e3aa59590ca31291a4505050565b600054610100900460ff161580801561173d5750600054600160ff909116105b806117575750303b158015611757575060005460ff166001145b6117ba5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109fd565b6000805460ff1916600117905580156117dd576000805461ff0019166101001790555b6117e5612d75565b60c9556117f28686612e0c565b6117fb87612cc7565b61180484612d19565b61180d83612c56565b61181682612ef6565b801561185c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260ca828154811061189c5761189c613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff161515606082015292915050565b6118ff611fc0565b610a0f81612ef6565b60ca546000905b63ffffffff81161561197b578260ca611929600184613d4c565b63ffffffff168154811061193f5761193f613913565b906000526020600020906002020160000154141561196957611962600182613d4c565b9392505050565b8061197381613d71565b91505061190f565b5060405162461bcd60e51b815260206004820152603760248201527f52657761726473436f6f7264696e61746f722e676574526f6f74496e6465784660448201527f726f6d486173683a20726f6f74206e6f7420666f756e6400000000000000000060648201526084016109fd565b6119f2611fc0565b6001600160a01b038116611a575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109fd565b610a0f81612cc7565b60007f0000000000000000000000000000000000000000000000000000000000000000461415611a91575060c95490565b611a99612d75565b905090565b60006001610b6160208401846135a9565b60665460039060089081161415611ad85760405162461bcd60e51b81526004016109fd90613a0c565b60cb546001600160a01b03163314611b025760405162461bcd60e51b81526004016109fd90613cd0565b60ca5463ffffffff831610611b735760405162461bcd60e51b815260206004820152603160248201527f52657761726473436f6f7264696e61746f722e64697361626c65526f6f743a206044820152700d2dcecc2d8d2c840e4dedee892dcc8caf607b1b60648201526084016109fd565b600060ca8363ffffffff1681548110611b8e57611b8e613913565b906000526020600020906002020190508060010160089054906101000a900460ff1615611c1b5760405162461bcd60e51b815260206004820152603560248201527f52657761726473436f6f7264696e61746f722e64697361626c65526f6f743a206044820152741c9bdbdd08185b1c9958591e48191a5cd8589b1959605a1b60648201526084016109fd565b6001810154600160201b900463ffffffff164210611c9a5760405162461bcd60e51b815260206004820152603660248201527f52657761726473436f6f7264696e61746f722e64697361626c65526f6f743a206044820152751c9bdbdd08185b1c9958591e481858dd1a5d985d195960521b60648201526084016109fd565b60018101805460ff60401b1916600160401b17905560405163ffffffff8416907fd850e6e5dfa497b72661fa73df2923464eaed9dc2ff1d3cb82bccbfeabe5c41e90600090a2505050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d5c9190613940565b6001600160a01b0316336001600160a01b031614611d8c5760405162461bcd60e51b81526004016109fd9061395d565b606654198119606654191614611e0a5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016109fd565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610b46565b60665460009060019081161415611e6a5760405162461bcd60e51b81526004016109fd90613a0c565b60026097541415611e8d5760405162461bcd60e51b81526004016109fd90613a43565b600260975560005b82811015610df65736848483818110611eb057611eb0613913565b9050602002810190611ec29190613a7a565b33600081815260ce60209081526040808320549051949550939192611eed9290918591879101613bbf565b604051602081830303815290604052805190602001209050611f0e83612111565b33600090815260cf602090815260408083208484529091529020805460ff19166001908117909155611f41908390613bef565b33600081815260ce602052604090819020929092559051829184917f450a367a380c4e339e5ae7340c8464ef27af7781ad9945cfe8abd828f89e628190611f89908890613c07565b60405180910390a4611faa333060408601803590610dcf90602089016135a9565b5050508080611fb890613c1a565b915050611e95565b6033546001600160a01b0316331461160d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109fd565b6001600160a01b0381166120a85760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016109fd565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b600061211d8280613c86565b905011612182576040805162461bcd60e51b8152602060048201526024810191909152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a206e6f20737472617465676965732073657460648201526084016109fd565b60008160400135116121f45760405162461bcd60e51b81526020600482015260416024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20616d6f756e742063616e6e6f74206265206064820152600360fc1b608482015260a4016109fd565b6f4b3b4ca85a86c47a098a223fffffffff8160400135111561226c5760405162461bcd60e51b815260206004820152603f6024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20616d6f756e7420746f6f206c617267650060648201526084016109fd565b63ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166122a360a083016080840161379c565b63ffffffff1611156123285760405162461bcd60e51b81526020600482015260546024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a206475726174696f6e20657863656564732060648201527326a0ac2fa922aba0a92229afa22aa920aa24a7a760611b608482015260a4016109fd565b7f000000000000000000000000000000000000000000000000000000000000000061235960a083016080840161379c565b6123639190613da7565b63ffffffff16156124035760405162461bcd60e51b815260206004820152606a6024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a206475726174696f6e206d7573742062652060648201527f61206d756c7469706c65206f662043414c43554c4154494f4e5f494e54455256608482015269414c5f5345434f4e445360b01b60a482015260c4016109fd565b7f0000000000000000000000000000000000000000000000000000000000000000612434608083016060840161379c565b61243e9190613da7565b63ffffffff16156124e45760405162461bcd60e51b81526020600482015260706024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20737461727454696d657374616d70206d7560648201527f73742062652061206d756c7469706c65206f662043414c43554c4154494f4e5f60848201526f494e54455256414c5f5345434f4e445360801b60a482015260c4016109fd565b6124f4608082016060830161379c565b63ffffffff167f000000000000000000000000000000000000000000000000000000000000000063ffffffff164261252c91906138fc565b111580156125755750612545608082016060830161379c565b63ffffffff167f000000000000000000000000000000000000000000000000000000000000000063ffffffff1611155b6125ef5760405162461bcd60e51b81526020600482015260516024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20737461727454696d657374616d7020746f6064820152701bc819985c881a5b881d1a19481c185cdd607a1b608482015260a4016109fd565b61261f63ffffffff7f00000000000000000000000000000000000000000000000000000000000000001642613bef565b61262f608083016060840161379c565b63ffffffff1611156126b35760405162461bcd60e51b81526020600482015260536024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20737461727454696d657374616d7020746f6064820152726f2066617220696e207468652066757475726560681b608482015260a4016109fd565b6000805b6126c18380613c86565b90508110156128e45760006126d68480613c86565b838181106126e6576126e6613913565b6126fc92602060409092020190810191506135a9565b60405163198f077960e21b81526001600160a01b0380831660048301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063663c1de490602401602060405180830381865afa158015612767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278b91906139a7565b806127b257506001600160a01b03811673beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac0145b6128255760405162461bcd60e51b815260206004820152604a6024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20696e76616c69642073747261746567792060648201526918dbdb9cda59195c995960b21b608482015260a4016109fd565b806001600160a01b0316836001600160a01b0316106128d25760405162461bcd60e51b81526020600482015260696024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a2073747261746567696573206d757374206260648201527f6520696e20617363656e64696e67206f7264657220746f2068616e646c65206460848201526875706c69636174657360b81b60a482015260c4016109fd565b91506128dd81613c1a565b90506126b7565b505050565b6040516001600160a01b03808516602483015283166044820152606481018290526129549085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612f61565b50505050565b8060600151156129b35760405162461bcd60e51b81526020600482015260306024820152600080516020613eab83398151915260448201526f1c9bdbdd081a5cc8191a5cd8589b195960821b60648201526084016109fd565b806040015163ffffffff16421015612a1a5760405162461bcd60e51b81526020600482015260366024820152600080516020613eab8339815191526044820152751c9bdbdd081b9bdd081858dd1a5d985d1959081e595d60521b60648201526084016109fd565b612a2760c0830183613c35565b9050612a3660a0840184613c35565b905014612aae5760405162461bcd60e51b815260206004820152604c6024820152600080516020613eab83398151915260448201527f746f6b656e496e646963657320616e6420746f6b656e50726f6f6673206c656e60648201526b0cee8d040dad2e6dac2e8c6d60a31b608482015260a4016109fd565b612abb60e0830183613c86565b9050612aca60c0840184613c35565b905014612b405760405162461bcd60e51b815260206004820152604a6024820152600080516020613eab83398151915260448201527f746f6b656e5472656550726f6f667320616e64206c6561766573206c656e67746064820152690d040dad2e6dac2e8c6d60b31b608482015260a4016109fd565b8051612b6c90612b56604085016020860161379c565b612b636040860186613dca565b86606001613033565b60005b612b7c60a0840184613c35565b90508110156128e457612c166080840135612b9a60a0860186613c35565b84818110612baa57612baa613913565b9050602002016020810190612bbf919061379c565b612bcc60c0870187613c35565b85818110612bdc57612bdc613913565b9050602002810190612bee9190613dca565b612bfb60e0890189613c86565b87818110612c0b57612c0b613913565b9050604002016131a7565b612c1f81613c1a565b9050612b6f565b6040516001600160a01b0383166024820152604481018290526128e490849063a9059cbb60e01b9060640161291d565b60cb546040805163ffffffff600160a01b9093048316815291831660208301527faf557c6c02c208794817a705609cfa935f827312a1adfdd26494b6b95dd2b4b3910160405180910390a160cb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60cb546040516001600160a01b038084169216907f237b82f438d75fc568ebab484b75b01d9287b9e98b490b7c23221623b6705dbb90600090a360cb80546001600160a01b0319166001600160a01b0392909216919091179055565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b6065546001600160a01b0316158015612e2d57506001600160a01b03821615155b612eaf5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016109fd565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2612ef28261201a565b5050565b60cb546040805161ffff600160e01b9093048316815291831660208301527f8cdc428b0431b82d1619763f443a48197db344ba96905f3949643acd1c863a06910160405180910390a160cb805461ffff909216600160e01b0261ffff60e01b19909216919091179055565b6000612fb6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166132f89092919063ffffffff16565b8051909150156128e45780806020019051810190612fd491906139a7565b6128e45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109fd565b61303e602083613e11565b6001901b8463ffffffff16106130c85760405162461bcd60e51b815260206004820152604360248201527f52657761726473436f6f7264696e61746f722e5f7665726966794561726e657260448201527f436c61696d50726f6f663a20696e76616c6964206561726e65724c656166496e6064820152620c8caf60eb1b608482015260a4016109fd565b60006130d382610b51565b905061311e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92508591505063ffffffff891661330f565b61319f5760405162461bcd60e51b815260206004820152604660248201527f52657761726473436f6f7264696e61746f722e5f7665726966794561726e657260448201527f436c61696d50726f6f663a20696e76616c6964206561726e657220636c61696d60648201526510383937b7b360d11b608482015260a4016109fd565b505050505050565b6131b2602083613e11565b6001901b8463ffffffff16106132305760405162461bcd60e51b815260206004820152603c60248201527f52657761726473436f6f7264696e61746f722e5f766572696679546f6b656e4360448201527f6c61696d3a20696e76616c696420746f6b656e4c656166496e6465780000000060648201526084016109fd565b600061323b82611a9e565b905061328684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92508591505063ffffffff891661330f565b61319f5760405162461bcd60e51b815260206004820152603f60248201527f52657761726473436f6f7264696e61746f722e5f766572696679546f6b656e4360448201527f6c61696d3a20696e76616c696420746f6b656e20636c61696d2070726f6f660060648201526084016109fd565b60606133078484600085613327565b949350505050565b60008361331d868585613458565b1495945050505050565b6060824710156133885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109fd565b6001600160a01b0385163b6133df5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109fd565b600080866001600160a01b031685876040516133fb9190613e51565b60006040518083038185875af1925050503d8060008114613438576040519150601f19603f3d011682016040523d82523d6000602084013e61343d565b606091505b509150915061344d82828661355b565b979650505050505050565b6000602084516134689190613e63565b156134ef5760405162461bcd60e51b815260206004820152604b60248201527f4d65726b6c652e70726f63657373496e636c7573696f6e50726f6f664b65636360448201527f616b3a2070726f6f66206c656e6774682073686f756c642062652061206d756c60648201526a3a34b836329037b310199960a91b608482015260a4016109fd565b8260205b8551811161355257613506600285613e63565b61352757816000528086015160205260406000209150600284049350613540565b8086015160005281602052604060002091506002840493505b61354b602082613bef565b90506134f3565b50949350505050565b6060831561356a575081611962565b82511561357a5782518084602001fd5b8160405162461bcd60e51b81526004016109fd9190613e77565b6001600160a01b0381168114610a0f57600080fd5b6000602082840312156135bb57600080fd5b813561196281613594565b8015158114610a0f57600080fd5b600080604083850312156135e757600080fd5b82356135f281613594565b91506020830135613602816135c6565b809150509250929050565b60006020828403121561361f57600080fd5b5035919050565b60006040828403121561363857600080fd5b50919050565b60006040828403121561365057600080fd5b6119628383613626565b6000806040838503121561366d57600080fd5b823561367881613594565b9150602083013561360281613594565b6000806020838503121561369b57600080fd5b823567ffffffffffffffff808211156136b357600080fd5b818501915085601f8301126136c757600080fd5b8135818111156136d657600080fd5b8660208260051b85010111156136eb57600080fd5b60209290920196919550909350505050565b6000610100828403121561363857600080fd5b6000806040838503121561372357600080fd5b823567ffffffffffffffff81111561373a57600080fd5b613746858286016136fd565b925050602083013561360281613594565b803563ffffffff8116811461376b57600080fd5b919050565b6000806040838503121561378357600080fd5b8235915061379360208401613757565b90509250929050565b6000602082840312156137ae57600080fd5b61196282613757565b6000602082840312156137c957600080fd5b813560ff8116811461196257600080fd5b6000602082840312156137ec57600080fd5b813567ffffffffffffffff81111561380357600080fd5b613307848285016136fd565b6000806040838503121561382257600080fd5b823561382d81613594565b946020939093013593505050565b803561376b81613594565b803561ffff8116811461376b57600080fd5b60008060008060008060c0878903121561387157600080fd5b863561387c81613594565b9550602087013561388c81613594565b94506040870135935060608701356138a381613594565b92506138b160808801613757565b91506138bf60a08801613846565b90509295509295509295565b6000602082840312156138dd57600080fd5b61196282613846565b634e487b7160e01b600052601160045260246000fd5b60008282101561390e5761390e6138e6565b500390565b634e487b7160e01b600052603260045260246000fd5b600081613938576139386138e6565b506000190190565b60006020828403121561395257600080fd5b815161196281613594565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b6000602082840312156139b957600080fd5b8151611962816135c6565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b60208082526019908201527f5061757361626c653a20696e6465782069732070617573656400000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60008235609e19833603018112613a9057600080fd5b9190910192915050565b818352600060208085019450826000805b86811015613aff578235613abe81613594565b6001600160a01b03168852828401356bffffffffffffffffffffffff8116808214613ae7578384fd5b89860152506040978801979290920191600101613aab565b50959695505050505050565b60008135601e19833603018112613b2157600080fd5b8201803567ffffffffffffffff811115613b3a57600080fd5b8060061b3603841315613b4c57600080fd5b60a08552613b6160a086018260208501613a9a565b915050613b706020840161383b565b6001600160a01b0316602085015260408381013590850152613b9460608401613757565b63ffffffff166060850152613bab60808401613757565b63ffffffff81166080860152509392505050565b60018060a01b0384168152826020820152606060408201526000613be66060830184613b0b565b95945050505050565b60008219821115613c0257613c026138e6565b500190565b6020815260006119626020830184613b0b565b6000600019821415613c2e57613c2e6138e6565b5060010190565b6000808335601e19843603018112613c4c57600080fd5b83018035915067ffffffffffffffff821115613c6757600080fd5b6020019150600581901b3603821315613c7f57600080fd5b9250929050565b6000808335601e19843603018112613c9d57600080fd5b83018035915067ffffffffffffffff821115613cb857600080fd5b6020019150600681901b3603821315613c7f57600080fd5b60208082526034908201527f52657761726473436f6f7264696e61746f723a2063616c6c6572206973206e6f6040820152733a103a3432903932bbb0b93239aab83230ba32b960611b606082015260800190565b600063ffffffff808316818516808303821115613d4357613d436138e6565b01949350505050565b600063ffffffff83811690831681811015613d6957613d696138e6565b039392505050565b600063ffffffff821680613d8757613d876138e6565b6000190192915050565b634e487b7160e01b600052601260045260246000fd5b600063ffffffff80841680613dbe57613dbe613d91565b92169190910692915050565b6000808335601e19843603018112613de157600080fd5b83018035915067ffffffffffffffff821115613dfc57600080fd5b602001915036819003821315613c7f57600080fd5b600082613e2057613e20613d91565b500490565b60005b83811015613e40578181015183820152602001613e28565b838111156129545750506000910152565b60008251613a90818460208701613e25565b600082613e7257613e72613d91565b500690565b6020815260008251806020840152613e96816040850160208701613e25565b601f01601f1916919091016040019291505056fe52657761726473436f6f7264696e61746f722e5f636865636b436c61696d3a2052657761726473436f6f7264696e61746f722e5f76616c696461746552657761a2646970667358221220e5af77c5c79a3a1f7b84974f2789fb89e4b95901500e1c742b1e285bb759f77e64736f6c634300080c0033", + Bin: "0x6101806040523480156200001257600080fd5b5060405162004367380380620043678339810160408190526200003591620002e4565b868686868686866200004885826200037e565b63ffffffff1615620000ed5760405162461bcd60e51b815260206004820152606060248201527f52657761726473436f6f7264696e61746f723a2047454e455349535f5245574160448201527f5244535f54494d455354414d50206d7573742062652061206d756c7469706c6560648201527f206f662043414c43554c4154494f4e5f494e54455256414c5f5345434f4e4453608482015260a4015b60405180910390fd5b620000fc62015180866200037e565b63ffffffff16156200019d5760405162461bcd60e51b815260206004820152605760248201527f52657761726473436f6f7264696e61746f723a2043414c43554c4154494f4e5f60448201527f494e54455256414c5f5345434f4e4453206d7573742062652061206d756c746960648201527f706c65206f6620534e415053484f545f434144454e4345000000000000000000608482015260a401620000e4565b6001600160a01b0396871661012052949095166101405263ffffffff92831660805290821660a052811660c05291821660e0521661010052620001df620001f2565b5050466101605250620003b09350505050565b600054610100900460ff16156200025c5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608401620000e4565b60005460ff9081161015620002af576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b0381168114620002c757600080fd5b50565b805163ffffffff81168114620002df57600080fd5b919050565b600080600080600080600060e0888a0312156200030057600080fd5b87516200030d81620002b1565b60208901519097506200032081620002b1565b95506200033060408901620002ca565b94506200034060608901620002ca565b93506200035060808901620002ca565b92506200036060a08901620002ca565b91506200037060c08901620002ca565b905092959891949750929550565b600063ffffffff80841680620003a457634e487b7160e01b600052601260045260246000fd5b92169190910692915050565b60805160a05160c05160e05161010051610120516101405161016051613f20620004476000396000611a640152600081816104c7015261271e015260006107590152600081816103d0015261254d0152600081816102fc01526125f90152600081816104a001526124fc0152600081816106b8015261227301526000818161065e0152818161232a01526124050152613f206000f3fe608060405234801561001057600080fd5b50600436106102ba5760003560e01c8063715018a611610182578063c46db606116100e9578063f2fde38b116100a2578063f96abf2e1161007c578063f96abf2e146107a9578063fabc1cbc146107bc578063fbf1e2c1146107cf578063fce36c7d146107e257600080fd5b8063f2fde38b1461077b578063f698da251461078e578063f8cd84481461079657600080fd5b8063c46db606146106da578063d4540a5514610708578063de02e5031461071b578063e221b2451461072e578063e810ce2114610741578063ea4d3c9b1461075457600080fd5b80639104c3191161013b5780639104c319146106365780639be3d4e4146106515780639d45c28114610659578063a0169ddd14610680578063bb7e451f14610693578063bf21a8aa146106b357600080fd5b8063715018a6146105c45780637b8f8b05146105cc578063863cb9a9146105d4578063865c6953146105e7578063886f1195146106125780638da5cb5b1461062557600080fd5b806337838ed01161022657806358baaa3e116101df57806358baaa3e1461053d578063595c6a67146105505780635ac86ab7146105585780635c975abb1461057b5780635e9d8348146105835780636d21117e1461059657600080fd5b806337838ed01461049b57806339b70e38146104c25780633a8c0786146104e95780633ccc861d146105005780633efe1db6146105135780634d18cc351461052657600080fd5b8063131433b411610278578063131433b4146103cb578063136439dd146103f2578063149bc8721461040557806322f19a64146104265780632b9f64a41461044757806336af41fa1461048857600080fd5b806218572c146102bf57806304a0c502146102f7578063092db007146103335780630e9a53cf1461035b5780630eb38345146103a357806310d67a2f146103b8575b600080fd5b6102e26102cd3660046135a9565b60d16020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016102ee565b60cb5461034890600160e01b900461ffff1681565b60405161ffff90911681526020016102ee565b6103636107f5565b604080518251815260208084015163ffffffff908116918301919091528383015116918101919091526060918201511515918101919091526080016102ee565b6103b66103b13660046135d4565b6108d4565b005b6103b66103c63660046135a9565b610956565b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b6103b661040036600461360d565b610a12565b61041861041336600461363e565b610b51565b6040519081526020016102ee565b61034861043436600461365a565b505060cb54600160e01b900461ffff1690565b6104706104553660046135a9565b60cc602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016102ee565b6103b6610496366004613688565b610bc7565b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b6104707f000000000000000000000000000000000000000000000000000000000000000081565b60cb5461031e90600160a01b900463ffffffff1681565b6103b661050e366004613710565b610e01565b6103b6610521366004613770565b6111c5565b60cb5461031e90600160c01b900463ffffffff1681565b6103b661054b36600461379c565b611496565b6103b66114a7565b6102e26105663660046137b7565b606654600160ff9092169190911b9081161490565b606654610418565b6102e26105913660046137da565b61156e565b6102e26105a436600461380f565b60cf60209081526000928352604080842090915290825290205460ff1681565b6103b66115fb565b60ca54610418565b6103b66105e23660046135a9565b61160f565b6104186105f536600461365a565b60cd60209081526000928352604080842090915290825290205481565b606554610470906001600160a01b031681565b6033546001600160a01b0316610470565b61047073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b610363611620565b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b6103b661068e3660046135a9565b6116be565b6104186106a13660046135a9565b60ce6020526000908152604090205481565b61031e7f000000000000000000000000000000000000000000000000000000000000000081565b6102e26106e836600461380f565b60d060209081526000928352604080842090915290825290205460ff1681565b6103b6610716366004613858565b61171d565b61036361072936600461360d565b611865565b6103b661073c3660046138cb565b6118f7565b61031e61074f36600461360d565b611908565b6104707f000000000000000000000000000000000000000000000000000000000000000081565b6103b66107893660046135a9565b6119ea565b610418611a60565b6104186107a436600461363e565b611a9e565b6103b66107b736600461379c565b611aaf565b6103b66107ca36600461360d565b611ce5565b60cb54610470906001600160a01b031681565b6103b66107f0366004613688565b611e41565b60408051608081018252600080825260208201819052918101829052606081019190915260ca545b80156108d057600060ca6108326001846138fc565b8154811061084257610842613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff1615801560608301819052919250906108b25750806040015163ffffffff164210155b156108bd5792915050565b50806108c881613929565b91505061081d565b5090565b6108dc611fc0565b6001600160a01b038216600081815260d1602052604080822054905160ff9091169284151592841515927f4de6293e668df1398422e1def12118052c1539a03cbfedc145895d48d7685f1c9190a4506001600160a01b0391909116600090815260d160205260409020805460ff1916911515919091179055565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cd9190613940565b6001600160a01b0316336001600160a01b031614610a065760405162461bcd60e51b81526004016109fd9061395d565b60405180910390fd5b610a0f8161201a565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610a5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7e91906139a7565b610a9a5760405162461bcd60e51b81526004016109fd906139c4565b60665481811614610b135760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016109fd565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b600080610b6160208401846135a9565b8360200135604051602001610baa9392919060f89390931b6001600160f81b031916835260609190911b6bffffffffffffffffffffffff19166001830152601582015260350190565b604051602081830303815290604052805190602001209050919050565b60665460019060029081161415610bf05760405162461bcd60e51b81526004016109fd90613a0c565b33600090815260d1602052604090205460ff16610c8f5760405162461bcd60e51b815260206004820152605160248201527f52657761726473436f6f7264696e61746f723a2063616c6c6572206973206e6f60448201527f7420612076616c69642063726561746552657761726473466f72416c6c53756260648201527036b4b9b9b4b7b71039bab136b4ba3a32b960791b608482015260a4016109fd565b60026097541415610cb25760405162461bcd60e51b81526004016109fd90613a43565b600260975560005b82811015610df65736848483818110610cd557610cd5613913565b9050602002810190610ce79190613a7a565b33600081815260ce60209081526040808320549051949550939192610d129290918591879101613bbf565b604051602081830303815290604052805190602001209050610d3383612111565b33600090815260d0602090815260408083208484529091529020805460ff19166001908117909155610d66908390613bef565b33600081815260ce602052604090819020929092559051829184917f51088b8c89628df3a8174002c2a034d0152fce6af8415d651b2a4734bf27048290610dae908890613c07565b60405180910390a4610de0333060408601803590610dcf90602089016135a9565b6001600160a01b03169291906128e9565b5050508080610dee90613c1a565b915050610cba565b505060016097555050565b60665460029060049081161415610e2a5760405162461bcd60e51b81526004016109fd90613a0c565b60026097541415610e4d5760405162461bcd60e51b81526004016109fd90613a43565b6002609755600060ca610e63602086018661379c565b63ffffffff1681548110610e7957610e79613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff16151560608201529050610eda848261295a565b6000610eec60808601606087016135a9565b6001600160a01b03808216600090815260cc60205260409020549192501680610f125750805b336001600160a01b03821614610f905760405162461bcd60e51b815260206004820152603c60248201527f52657761726473436f6f7264696e61746f722e70726f63657373436c61696d3a60448201527f2063616c6c6572206973206e6f742076616c696420636c61696d65720000000060648201526084016109fd565b60005b610fa060a0880188613c35565b90508110156111b75736610fb760e0890189613c86565b83818110610fc757610fc7613913565b6001600160a01b038716600090815260cd602090815260408083209302949094019450929091508290610ffc908501856135a9565b6001600160a01b03166001600160a01b03168152602001908152602001600020549050808260200135116110b65760405162461bcd60e51b815260206004820152605560248201527f52657761726473436f6f7264696e61746f722e70726f63657373436c61696d3a60448201527f2063756d756c61746976654561726e696e6773206d75737420626520677420746064820152741a185b8818dd5b5d5b185d1a5d9950db185a5b5959605a1b608482015260a4016109fd565b60006110c68260208501356138fc565b6001600160a01b038716600090815260cd602090815260408220929350850180359291906110f490876135a9565b6001600160a01b0316815260208082019290925260400160002091909155611136908a908390611126908701876135a9565b6001600160a01b03169190612c26565b86516001600160a01b03808b1691878216918916907f9543dbd55580842586a951f0386e24d68a5df99ae29e3b216588b45fd684ce319061117a60208901896135a9565b604080519283526001600160a01b039091166020830152810186905260600160405180910390a450505080806111af90613c1a565b915050610f93565b505060016097555050505050565b606654600390600890811614156111ee5760405162461bcd60e51b81526004016109fd90613a0c565b60cb546001600160a01b031633146112185760405162461bcd60e51b81526004016109fd90613cd0565b60cb5463ffffffff600160c01b9091048116908316116112b45760405162461bcd60e51b815260206004820152604b60248201527f52657761726473436f6f7264696e61746f722e7375626d6974526f6f743a206e60448201527f657720726f6f74206d75737420626520666f72206e657765722063616c63756c60648201526a185d1959081c195c9a5bd960aa1b608482015260a4016109fd565b428263ffffffff161061134d5760405162461bcd60e51b815260206004820152605560248201527f52657761726473436f6f7264696e61746f722e7375626d6974526f6f743a207260448201527f65776172647343616c63756c6174696f6e456e6454696d657374616d702063616064820152746e6e6f7420626520696e207468652066757475726560581b608482015260a4016109fd565b60ca5460cb5460009061136d90600160a01b900463ffffffff1642613d24565b6040805160808101825287815263ffffffff878116602080840182815286841685870181815260006060880181815260ca8054600181018255925297517f42d72674974f694b5f5159593243114d38a5c39c89d6b62fee061ff523240ee160029092029182015592517f42d72674974f694b5f5159593243114d38a5c39c89d6b62fee061ff523240ee290930180549151975193871667ffffffffffffffff1990921691909117600160201b978716979097029690961760ff60401b1916600160401b921515929092029190911790945560cb805463ffffffff60c01b1916600160c01b840217905593519283529394508892908616917fecd866c3c158fa00bf34d803d5f6023000b57080bcb48af004c2b4b46b3afd08910160405180910390a45050505050565b61149e611fc0565b610a0f81612c56565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156114ef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151391906139a7565b61152f5760405162461bcd60e51b81526004016109fd906139c4565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b60006115f38260ca611583602083018361379c565b63ffffffff168154811061159957611599613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff161515606082015261295a565b506001919050565b611603611fc0565b61160d6000612cc7565b565b611617611fc0565b610a0f81612d19565b60408051608081018252600080825260208201819052918101829052606081019190915260ca8054611654906001906138fc565b8154811061166457611664613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff1615156060820152919050565b33600081815260cc602052604080822080546001600160a01b031981166001600160a01b038781169182179093559251911692839185917fbab947934d42e0ad206f25c9cab18b5bb6ae144acfb00f40b4e3aa59590ca31291a4505050565b600054610100900460ff161580801561173d5750600054600160ff909116105b806117575750303b158015611757575060005460ff166001145b6117ba5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109fd565b6000805460ff1916600117905580156117dd576000805461ff0019166101001790555b6117e5612d75565b60c9556117f28686612e0c565b6117fb87612cc7565b61180484612d19565b61180d83612c56565b61181682612ef6565b801561185c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260ca828154811061189c5761189c613913565b600091825260209182902060408051608081018252600293909302909101805483526001015463ffffffff80821694840194909452600160201b810490931690820152600160401b90910460ff161515606082015292915050565b6118ff611fc0565b610a0f81612ef6565b60ca546000905b63ffffffff81161561197b578260ca611929600184613d4c565b63ffffffff168154811061193f5761193f613913565b906000526020600020906002020160000154141561196957611962600182613d4c565b9392505050565b8061197381613d71565b91505061190f565b5060405162461bcd60e51b815260206004820152603760248201527f52657761726473436f6f7264696e61746f722e676574526f6f74496e6465784660448201527f726f6d486173683a20726f6f74206e6f7420666f756e6400000000000000000060648201526084016109fd565b6119f2611fc0565b6001600160a01b038116611a575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109fd565b610a0f81612cc7565b60007f0000000000000000000000000000000000000000000000000000000000000000461415611a91575060c95490565b611a99612d75565b905090565b60006001610b6160208401846135a9565b60665460039060089081161415611ad85760405162461bcd60e51b81526004016109fd90613a0c565b60cb546001600160a01b03163314611b025760405162461bcd60e51b81526004016109fd90613cd0565b60ca5463ffffffff831610611b735760405162461bcd60e51b815260206004820152603160248201527f52657761726473436f6f7264696e61746f722e64697361626c65526f6f743a206044820152700d2dcecc2d8d2c840e4dedee892dcc8caf607b1b60648201526084016109fd565b600060ca8363ffffffff1681548110611b8e57611b8e613913565b906000526020600020906002020190508060010160089054906101000a900460ff1615611c1b5760405162461bcd60e51b815260206004820152603560248201527f52657761726473436f6f7264696e61746f722e64697361626c65526f6f743a206044820152741c9bdbdd08185b1c9958591e48191a5cd8589b1959605a1b60648201526084016109fd565b6001810154600160201b900463ffffffff164210611c9a5760405162461bcd60e51b815260206004820152603660248201527f52657761726473436f6f7264696e61746f722e64697361626c65526f6f743a206044820152751c9bdbdd08185b1c9958591e481858dd1a5d985d195960521b60648201526084016109fd565b60018101805460ff60401b1916600160401b17905560405163ffffffff8416907fd850e6e5dfa497b72661fa73df2923464eaed9dc2ff1d3cb82bccbfeabe5c41e90600090a2505050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d5c9190613940565b6001600160a01b0316336001600160a01b031614611d8c5760405162461bcd60e51b81526004016109fd9061395d565b606654198119606654191614611e0a5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016109fd565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610b46565b60665460009060019081161415611e6a5760405162461bcd60e51b81526004016109fd90613a0c565b60026097541415611e8d5760405162461bcd60e51b81526004016109fd90613a43565b600260975560005b82811015610df65736848483818110611eb057611eb0613913565b9050602002810190611ec29190613a7a565b33600081815260ce60209081526040808320549051949550939192611eed9290918591879101613bbf565b604051602081830303815290604052805190602001209050611f0e83612111565b33600090815260cf602090815260408083208484529091529020805460ff19166001908117909155611f41908390613bef565b33600081815260ce602052604090819020929092559051829184917f450a367a380c4e339e5ae7340c8464ef27af7781ad9945cfe8abd828f89e628190611f89908890613c07565b60405180910390a4611faa333060408601803590610dcf90602089016135a9565b5050508080611fb890613c1a565b915050611e95565b6033546001600160a01b0316331461160d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109fd565b6001600160a01b0381166120a85760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016109fd565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b600061211d8280613c86565b905011612182576040805162461bcd60e51b8152602060048201526024810191909152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a206e6f20737472617465676965732073657460648201526084016109fd565b60008160400135116121f45760405162461bcd60e51b81526020600482015260416024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20616d6f756e742063616e6e6f74206265206064820152600360fc1b608482015260a4016109fd565b6f4b3b4ca85a86c47a098a223fffffffff8160400135111561226c5760405162461bcd60e51b815260206004820152603f6024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20616d6f756e7420746f6f206c617267650060648201526084016109fd565b63ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166122a360a083016080840161379c565b63ffffffff1611156123285760405162461bcd60e51b81526020600482015260546024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a206475726174696f6e20657863656564732060648201527326a0ac2fa922aba0a92229afa22aa920aa24a7a760611b608482015260a4016109fd565b7f000000000000000000000000000000000000000000000000000000000000000061235960a083016080840161379c565b6123639190613da7565b63ffffffff16156124035760405162461bcd60e51b815260206004820152606a6024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a206475726174696f6e206d7573742062652060648201527f61206d756c7469706c65206f662043414c43554c4154494f4e5f494e54455256608482015269414c5f5345434f4e445360b01b60a482015260c4016109fd565b7f0000000000000000000000000000000000000000000000000000000000000000612434608083016060840161379c565b61243e9190613da7565b63ffffffff16156124e45760405162461bcd60e51b81526020600482015260706024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20737461727454696d657374616d70206d7560648201527f73742062652061206d756c7469706c65206f662043414c43554c4154494f4e5f60848201526f494e54455256414c5f5345434f4e445360801b60a482015260c4016109fd565b6124f4608082016060830161379c565b63ffffffff167f000000000000000000000000000000000000000000000000000000000000000063ffffffff164261252c91906138fc565b111580156125755750612545608082016060830161379c565b63ffffffff167f000000000000000000000000000000000000000000000000000000000000000063ffffffff1611155b6125ef5760405162461bcd60e51b81526020600482015260516024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20737461727454696d657374616d7020746f6064820152701bc819985c881a5b881d1a19481c185cdd607a1b608482015260a4016109fd565b61261f63ffffffff7f00000000000000000000000000000000000000000000000000000000000000001642613bef565b61262f608083016060840161379c565b63ffffffff1611156126b35760405162461bcd60e51b81526020600482015260536024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20737461727454696d657374616d7020746f6064820152726f2066617220696e207468652066757475726560681b608482015260a4016109fd565b6000805b6126c18380613c86565b90508110156128e45760006126d68480613c86565b838181106126e6576126e6613913565b6126fc92602060409092020190810191506135a9565b60405163198f077960e21b81526001600160a01b0380831660048301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063663c1de490602401602060405180830381865afa158015612767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278b91906139a7565b806127b257506001600160a01b03811673beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac0145b6128255760405162461bcd60e51b815260206004820152604a6024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a20696e76616c69642073747261746567792060648201526918dbdb9cda59195c995960b21b608482015260a4016109fd565b806001600160a01b0316836001600160a01b0316106128d25760405162461bcd60e51b81526020600482015260696024820152600080516020613ecb83398151915260448201527f7264735375626d697373696f6e3a2073747261746567696573206d757374206260648201527f6520696e20617363656e64696e67206f7264657220746f2068616e646c65206460848201526875706c69636174657360b81b60a482015260c4016109fd565b91506128dd81613c1a565b90506126b7565b505050565b6040516001600160a01b03808516602483015283166044820152606481018290526129549085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612f61565b50505050565b8060600151156129b35760405162461bcd60e51b81526020600482015260306024820152600080516020613eab83398151915260448201526f1c9bdbdd081a5cc8191a5cd8589b195960821b60648201526084016109fd565b806040015163ffffffff16421015612a1a5760405162461bcd60e51b81526020600482015260366024820152600080516020613eab8339815191526044820152751c9bdbdd081b9bdd081858dd1a5d985d1959081e595d60521b60648201526084016109fd565b612a2760c0830183613c35565b9050612a3660a0840184613c35565b905014612aae5760405162461bcd60e51b815260206004820152604c6024820152600080516020613eab83398151915260448201527f746f6b656e496e646963657320616e6420746f6b656e50726f6f6673206c656e60648201526b0cee8d040dad2e6dac2e8c6d60a31b608482015260a4016109fd565b612abb60e0830183613c86565b9050612aca60c0840184613c35565b905014612b405760405162461bcd60e51b815260206004820152604a6024820152600080516020613eab83398151915260448201527f746f6b656e5472656550726f6f667320616e64206c6561766573206c656e67746064820152690d040dad2e6dac2e8c6d60b31b608482015260a4016109fd565b8051612b6c90612b56604085016020860161379c565b612b636040860186613dca565b86606001613033565b60005b612b7c60a0840184613c35565b90508110156128e457612c166080840135612b9a60a0860186613c35565b84818110612baa57612baa613913565b9050602002016020810190612bbf919061379c565b612bcc60c0870187613c35565b85818110612bdc57612bdc613913565b9050602002810190612bee9190613dca565b612bfb60e0890189613c86565b87818110612c0b57612c0b613913565b9050604002016131a7565b612c1f81613c1a565b9050612b6f565b6040516001600160a01b0383166024820152604481018290526128e490849063a9059cbb60e01b9060640161291d565b60cb546040805163ffffffff600160a01b9093048316815291831660208301527faf557c6c02c208794817a705609cfa935f827312a1adfdd26494b6b95dd2b4b3910160405180910390a160cb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60cb546040516001600160a01b038084169216907f237b82f438d75fc568ebab484b75b01d9287b9e98b490b7c23221623b6705dbb90600090a360cb80546001600160a01b0319166001600160a01b0392909216919091179055565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b6065546001600160a01b0316158015612e2d57506001600160a01b03821615155b612eaf5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016109fd565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2612ef28261201a565b5050565b60cb546040805161ffff600160e01b9093048316815291831660208301527f8cdc428b0431b82d1619763f443a48197db344ba96905f3949643acd1c863a06910160405180910390a160cb805461ffff909216600160e01b0261ffff60e01b19909216919091179055565b6000612fb6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166132f89092919063ffffffff16565b8051909150156128e45780806020019051810190612fd491906139a7565b6128e45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109fd565b61303e602083613e11565b6001901b8463ffffffff16106130c85760405162461bcd60e51b815260206004820152604360248201527f52657761726473436f6f7264696e61746f722e5f7665726966794561726e657260448201527f436c61696d50726f6f663a20696e76616c6964206561726e65724c656166496e6064820152620c8caf60eb1b608482015260a4016109fd565b60006130d382610b51565b905061311e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92508591505063ffffffff891661330f565b61319f5760405162461bcd60e51b815260206004820152604660248201527f52657761726473436f6f7264696e61746f722e5f7665726966794561726e657260448201527f436c61696d50726f6f663a20696e76616c6964206561726e657220636c61696d60648201526510383937b7b360d11b608482015260a4016109fd565b505050505050565b6131b2602083613e11565b6001901b8463ffffffff16106132305760405162461bcd60e51b815260206004820152603c60248201527f52657761726473436f6f7264696e61746f722e5f766572696679546f6b656e4360448201527f6c61696d3a20696e76616c696420746f6b656e4c656166496e6465780000000060648201526084016109fd565b600061323b82611a9e565b905061328684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92508591505063ffffffff891661330f565b61319f5760405162461bcd60e51b815260206004820152603f60248201527f52657761726473436f6f7264696e61746f722e5f766572696679546f6b656e4360448201527f6c61696d3a20696e76616c696420746f6b656e20636c61696d2070726f6f660060648201526084016109fd565b60606133078484600085613327565b949350505050565b60008361331d868585613458565b1495945050505050565b6060824710156133885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109fd565b6001600160a01b0385163b6133df5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109fd565b600080866001600160a01b031685876040516133fb9190613e51565b60006040518083038185875af1925050503d8060008114613438576040519150601f19603f3d011682016040523d82523d6000602084013e61343d565b606091505b509150915061344d82828661355b565b979650505050505050565b6000602084516134689190613e63565b156134ef5760405162461bcd60e51b815260206004820152604b60248201527f4d65726b6c652e70726f63657373496e636c7573696f6e50726f6f664b65636360448201527f616b3a2070726f6f66206c656e6774682073686f756c642062652061206d756c60648201526a3a34b836329037b310199960a91b608482015260a4016109fd565b8260205b8551811161355257613506600285613e63565b61352757816000528086015160205260406000209150600284049350613540565b8086015160005281602052604060002091506002840493505b61354b602082613bef565b90506134f3565b50949350505050565b6060831561356a575081611962565b82511561357a5782518084602001fd5b8160405162461bcd60e51b81526004016109fd9190613e77565b6001600160a01b0381168114610a0f57600080fd5b6000602082840312156135bb57600080fd5b813561196281613594565b8015158114610a0f57600080fd5b600080604083850312156135e757600080fd5b82356135f281613594565b91506020830135613602816135c6565b809150509250929050565b60006020828403121561361f57600080fd5b5035919050565b60006040828403121561363857600080fd5b50919050565b60006040828403121561365057600080fd5b6119628383613626565b6000806040838503121561366d57600080fd5b823561367881613594565b9150602083013561360281613594565b6000806020838503121561369b57600080fd5b823567ffffffffffffffff808211156136b357600080fd5b818501915085601f8301126136c757600080fd5b8135818111156136d657600080fd5b8660208260051b85010111156136eb57600080fd5b60209290920196919550909350505050565b6000610100828403121561363857600080fd5b6000806040838503121561372357600080fd5b823567ffffffffffffffff81111561373a57600080fd5b613746858286016136fd565b925050602083013561360281613594565b803563ffffffff8116811461376b57600080fd5b919050565b6000806040838503121561378357600080fd5b8235915061379360208401613757565b90509250929050565b6000602082840312156137ae57600080fd5b61196282613757565b6000602082840312156137c957600080fd5b813560ff8116811461196257600080fd5b6000602082840312156137ec57600080fd5b813567ffffffffffffffff81111561380357600080fd5b613307848285016136fd565b6000806040838503121561382257600080fd5b823561382d81613594565b946020939093013593505050565b803561376b81613594565b803561ffff8116811461376b57600080fd5b60008060008060008060c0878903121561387157600080fd5b863561387c81613594565b9550602087013561388c81613594565b94506040870135935060608701356138a381613594565b92506138b160808801613757565b91506138bf60a08801613846565b90509295509295509295565b6000602082840312156138dd57600080fd5b61196282613846565b634e487b7160e01b600052601160045260246000fd5b60008282101561390e5761390e6138e6565b500390565b634e487b7160e01b600052603260045260246000fd5b600081613938576139386138e6565b506000190190565b60006020828403121561395257600080fd5b815161196281613594565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b6000602082840312156139b957600080fd5b8151611962816135c6565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b60208082526019908201527f5061757361626c653a20696e6465782069732070617573656400000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60008235609e19833603018112613a9057600080fd5b9190910192915050565b818352600060208085019450826000805b86811015613aff578235613abe81613594565b6001600160a01b03168852828401356bffffffffffffffffffffffff8116808214613ae7578384fd5b89860152506040978801979290920191600101613aab565b50959695505050505050565b60008135601e19833603018112613b2157600080fd5b8201803567ffffffffffffffff811115613b3a57600080fd5b8060061b3603841315613b4c57600080fd5b60a08552613b6160a086018260208501613a9a565b915050613b706020840161383b565b6001600160a01b0316602085015260408381013590850152613b9460608401613757565b63ffffffff166060850152613bab60808401613757565b63ffffffff81166080860152509392505050565b60018060a01b0384168152826020820152606060408201526000613be66060830184613b0b565b95945050505050565b60008219821115613c0257613c026138e6565b500190565b6020815260006119626020830184613b0b565b6000600019821415613c2e57613c2e6138e6565b5060010190565b6000808335601e19843603018112613c4c57600080fd5b83018035915067ffffffffffffffff821115613c6757600080fd5b6020019150600581901b3603821315613c7f57600080fd5b9250929050565b6000808335601e19843603018112613c9d57600080fd5b83018035915067ffffffffffffffff821115613cb857600080fd5b6020019150600681901b3603821315613c7f57600080fd5b60208082526034908201527f52657761726473436f6f7264696e61746f723a2063616c6c6572206973206e6f6040820152733a103a3432903932bbb0b93239aab83230ba32b960611b606082015260800190565b600063ffffffff808316818516808303821115613d4357613d436138e6565b01949350505050565b600063ffffffff83811690831681811015613d6957613d696138e6565b039392505050565b600063ffffffff821680613d8757613d876138e6565b6000190192915050565b634e487b7160e01b600052601260045260246000fd5b600063ffffffff80841680613dbe57613dbe613d91565b92169190910692915050565b6000808335601e19843603018112613de157600080fd5b83018035915067ffffffffffffffff821115613dfc57600080fd5b602001915036819003821315613c7f57600080fd5b600082613e2057613e20613d91565b500490565b60005b83811015613e40578181015183820152602001613e28565b838111156129545750506000910152565b60008251613a90818460208701613e25565b600082613e7257613e72613d91565b500690565b6020815260008251806020840152613e96816040850160208701613e25565b601f01601f1916919091016040019291505056fe52657761726473436f6f7264696e61746f722e5f636865636b436c61696d3a2052657761726473436f6f7264696e61746f722e5f76616c696461746552657761a2646970667358221220db81f327c7281cb3b530523833b68678bd1da0cec9cccdb599b0104a361ccafc64736f6c634300080c0033", } // RewardsCoordinatorABI is the input ABI used to generate the binding from. diff --git a/pkg/bindings/StrategyBase/binding.go b/pkg/bindings/StrategyBase/binding.go index 60855287e..02377ad8a 100644 --- a/pkg/bindings/StrategyBase/binding.go +++ b/pkg/bindings/StrategyBase/binding.go @@ -32,7 +32,7 @@ var ( // StrategyBaseMetaData contains all meta data concerning the StrategyBase contract. var StrategyBaseMetaData = &bind.MetaData{ ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_strategyManager\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"newShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"explanation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_underlyingToken\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"shares\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"sharesToUnderlying\",\"inputs\":[{\"name\":\"amountShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"sharesToUnderlyingView\",\"inputs\":[{\"name\":\"amountShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalShares\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"underlyingToShares\",\"inputs\":[{\"name\":\"amountUnderlying\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"underlyingToSharesView\",\"inputs\":[{\"name\":\"amountUnderlying\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"underlyingToken\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"userUnderlying\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"userUnderlyingView\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amountShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"ExchangeRateEmitted\",\"inputs\":[{\"name\":\"rate\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StrategyTokenSet\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIERC20\"},{\"name\":\"decimals\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001ab438038062001ab4833981016040819052620000349162000114565b6001600160a01b0381166080526200004b62000052565b5062000146565b600054610100900460ff1615620000bf5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000112576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200012757600080fd5b81516001600160a01b03811681146200013f57600080fd5b9392505050565b60805161193d620001776000396000818161019901528181610570015281816109f50152610ac0015261193d6000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80635c975abb116100b8578063ab5921e11161007c578063ab5921e11461029c578063ce7c2ac2146102b1578063d9caed12146102c4578063e3dae51c146102d7578063f3e73875146102ea578063fabc1cbc146102fd57600080fd5b80635c975abb146102425780637a8b26371461024a578063886f11951461025d5780638c871019146102765780638f6a62401461028957600080fd5b806347e7ef24116100ff57806347e7ef24146101d2578063485cc955146101e5578063553ca5f8146101f8578063595c6a671461020b5780635ac86ab71461021357600080fd5b806310d67a2f1461013c578063136439dd146101515780632495a5991461016457806339b70e38146101945780633a98ef39146101bb575b600080fd5b61014f61014a3660046115a6565b610310565b005b61014f61015f3660046115c3565b6103cc565b603254610177906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101777f000000000000000000000000000000000000000000000000000000000000000081565b6101c460335481565b60405190815260200161018b565b6101c46101e03660046115dc565b610510565b61014f6101f3366004611608565b610754565b6101c46102063660046115a6565b610869565b61014f61087d565b610232610221366004611650565b6001805460ff9092161b9081161490565b604051901515815260200161018b565b6001546101c4565b6101c46102583660046115c3565b610949565b600054610177906201000090046001600160a01b031681565b6101c46102843660046115c3565b610994565b6101c46102973660046115a6565b61099f565b6102a46109ad565b60405161018b919061169d565b6101c46102bf3660046115a6565b6109cd565b61014f6102d23660046116d0565b610a62565b6101c46102e53660046115c3565b610c48565b6101c46102f83660046115c3565b610c81565b61014f61030b3660046115c3565b610c8c565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610363573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103879190611711565b6001600160a01b0316336001600160a01b0316146103c05760405162461bcd60e51b81526004016103b79061172e565b60405180910390fd5b6103c981610de8565b50565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610419573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043d9190611778565b6104595760405162461bcd60e51b81526004016103b79061179a565b600154818116146104d25760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016103b7565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b600180546000918291811614156105655760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016103b7565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105dd5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e6167657260448201526064016103b7565b6105e78484610eed565b60335460006105f86103e8836117f8565b905060006103e8610607610f6d565b61061191906117f8565b9050600061061f8783611810565b90508061062c8489611827565b6106369190611846565b95508561069c5760405162461bcd60e51b815260206004820152602e60248201527f5374726174656779426173652e6465706f7369743a206e65775368617265732060448201526d63616e6e6f74206265207a65726f60901b60648201526084016103b7565b6106a686856117f8565b60338190556f4b3b4ca85a86c47a098a223fffffffff10156107305760405162461bcd60e51b815260206004820152603c60248201527f5374726174656779426173652e6465706f7369743a20746f74616c536861726560448201527f73206578636565647320604d41585f544f54414c5f534841524553600000000060648201526084016103b7565b610749826103e860335461074491906117f8565b610fdf565b505050505092915050565b600054610100900460ff16158080156107745750600054600160ff909116105b8061078e5750303b15801561078e575060005460ff166001145b6107f15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103b7565b6000805460ff191660011790558015610814576000805461ff0019166101001790555b61081e8383611033565b8015610864576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6000610877610258836109cd565b92915050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa1580156108ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ee9190611778565b61090a5760405162461bcd60e51b81526004016103b79061179a565b600019600181905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000806103e860335461095c91906117f8565b905060006103e861096b610f6d565b61097591906117f8565b9050816109828583611827565b61098c9190611846565b949350505050565b600061087782610c48565b60006108776102f8836109cd565b60606040518060800160405280604d81526020016118bb604d9139905090565b604051633d3f06c960e11b81526001600160a01b0382811660048301523060248301526000917f000000000000000000000000000000000000000000000000000000000000000090911690637a7e0d9290604401602060405180830381865afa158015610a3e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190611868565b6001805460029081161415610ab55760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016103b7565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b2d5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e6167657260448201526064016103b7565b610b3884848461117e565b60335480831115610bc75760405162461bcd60e51b815260206004820152604d60248201527f5374726174656779426173652e77697468647261773a20616d6f756e7453686160448201527f726573206d757374206265206c657373207468616e206f7220657175616c207460648201526c6f20746f74616c53686172657360981b608482015260a4016103b7565b6000610bd56103e8836117f8565b905060006103e8610be4610f6d565b610bee91906117f8565b9050600082610bfd8784611827565b610c079190611846565b9050610c138685611810565b603355610c33610c238284611810565b6103e860335461074491906117f8565b610c3e888883611201565b5050505050505050565b6000806103e8603354610c5b91906117f8565b905060006103e8610c6a610f6d565b610c7491906117f8565b9050806109828386611827565b600061087782610949565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d039190611711565b6001600160a01b0316336001600160a01b031614610d335760405162461bcd60e51b81526004016103b79061172e565b600154198119600154191614610db15760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016103b7565b600181905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610505565b6001600160a01b038116610e765760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016103b7565b600054604080516001600160a01b03620100009093048316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6032546001600160a01b03838116911614610f695760405162461bcd60e51b815260206004820152603660248201527f5374726174656779426173652e6465706f7369743a2043616e206f6e6c79206460448201527532b837b9b4ba103ab73232b9363cb4b733aa37b5b2b760511b60648201526084016103b7565b5050565b6032546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fda9190611868565b905090565b7fd2494f3479e5da49d386657c292c610b5b01df313d07c62eb0cfa49924a31be88161101384670de0b6b3a7640000611827565b61101d9190611846565b6040519081526020015b60405180910390a15050565b600054610100900460ff1661109e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016103b7565b603280546001600160a01b0319166001600160a01b0384161790556110c4816000611215565b7f1c540707b00eb5427b6b774fc799d756516a54aee108b64b327acc55af557507603260009054906101000a90046001600160a01b0316836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190611881565b604080516001600160a01b03909316835260ff909116602083015201611027565b6032546001600160a01b038381169116146108645760405162461bcd60e51b815260206004820152603b60248201527f5374726174656779426173652e77697468647261773a2043616e206f6e6c792060448201527f77697468647261772074686520737472617465677920746f6b656e000000000060648201526084016103b7565b6108646001600160a01b0383168483611301565b6000546201000090046001600160a01b031615801561123c57506001600160a01b03821615155b6112be5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016103b7565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2610f6982610de8565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908401526108649286929160009161139191851690849061140e565b80519091501561086457808060200190518101906113af9190611778565b6108645760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103b7565b606061141d8484600085611427565b90505b9392505050565b6060824710156114885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103b7565b6001600160a01b0385163b6114df5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103b7565b600080866001600160a01b031685876040516114fb919061189e565b60006040518083038185875af1925050503d8060008114611538576040519150601f19603f3d011682016040523d82523d6000602084013e61153d565b606091505b509150915061154d828286611558565b979650505050505050565b60608315611567575081611420565b8251156115775782518084602001fd5b8160405162461bcd60e51b81526004016103b7919061169d565b6001600160a01b03811681146103c957600080fd5b6000602082840312156115b857600080fd5b813561142081611591565b6000602082840312156115d557600080fd5b5035919050565b600080604083850312156115ef57600080fd5b82356115fa81611591565b946020939093013593505050565b6000806040838503121561161b57600080fd5b823561162681611591565b9150602083013561163681611591565b809150509250929050565b60ff811681146103c957600080fd5b60006020828403121561166257600080fd5b813561142081611641565b60005b83811015611688578181015183820152602001611670565b83811115611697576000848401525b50505050565b60208152600082518060208401526116bc81604085016020870161166d565b601f01601f19169190910160400192915050565b6000806000606084860312156116e557600080fd5b83356116f081611591565b9250602084013561170081611591565b929592945050506040919091013590565b60006020828403121561172357600080fd5b815161142081611591565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60006020828403121561178a57600080fd5b8151801515811461142057600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000821982111561180b5761180b6117e2565b500190565b600082821015611822576118226117e2565b500390565b6000816000190483118215151615611841576118416117e2565b500290565b60008261186357634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561187a57600080fd5b5051919050565b60006020828403121561189357600080fd5b815161142081611641565b600082516118b081846020870161166d565b919091019291505056fe4261736520537472617465677920696d706c656d656e746174696f6e20746f20696e68657269742066726f6d20666f72206d6f726520636f6d706c657820696d706c656d656e746174696f6e73a2646970667358221220fdb1cf41dad704373536b605ad5d3c82b532af827f4ae30f7139f31ec1f8ee7064736f6c634300080c0033", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001ab438038062001ab4833981016040819052620000349162000114565b6001600160a01b0381166080526200004b62000052565b5062000146565b600054610100900460ff1615620000bf5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000112576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200012757600080fd5b81516001600160a01b03811681146200013f57600080fd5b9392505050565b60805161193d620001776000396000818161019901528181610570015281816109f50152610ac0015261193d6000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80635c975abb116100b8578063ab5921e11161007c578063ab5921e11461029c578063ce7c2ac2146102b1578063d9caed12146102c4578063e3dae51c146102d7578063f3e73875146102ea578063fabc1cbc146102fd57600080fd5b80635c975abb146102425780637a8b26371461024a578063886f11951461025d5780638c871019146102765780638f6a62401461028957600080fd5b806347e7ef24116100ff57806347e7ef24146101d2578063485cc955146101e5578063553ca5f8146101f8578063595c6a671461020b5780635ac86ab71461021357600080fd5b806310d67a2f1461013c578063136439dd146101515780632495a5991461016457806339b70e38146101945780633a98ef39146101bb575b600080fd5b61014f61014a3660046115a6565b610310565b005b61014f61015f3660046115c3565b6103cc565b603254610177906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101777f000000000000000000000000000000000000000000000000000000000000000081565b6101c460335481565b60405190815260200161018b565b6101c46101e03660046115dc565b610510565b61014f6101f3366004611608565b610754565b6101c46102063660046115a6565b610869565b61014f61087d565b610232610221366004611650565b6001805460ff9092161b9081161490565b604051901515815260200161018b565b6001546101c4565b6101c46102583660046115c3565b610949565b600054610177906201000090046001600160a01b031681565b6101c46102843660046115c3565b610994565b6101c46102973660046115a6565b61099f565b6102a46109ad565b60405161018b919061169d565b6101c46102bf3660046115a6565b6109cd565b61014f6102d23660046116d0565b610a62565b6101c46102e53660046115c3565b610c48565b6101c46102f83660046115c3565b610c81565b61014f61030b3660046115c3565b610c8c565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610363573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103879190611711565b6001600160a01b0316336001600160a01b0316146103c05760405162461bcd60e51b81526004016103b79061172e565b60405180910390fd5b6103c981610de8565b50565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610419573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043d9190611778565b6104595760405162461bcd60e51b81526004016103b79061179a565b600154818116146104d25760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016103b7565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b600180546000918291811614156105655760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016103b7565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105dd5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e6167657260448201526064016103b7565b6105e78484610eed565b60335460006105f86103e8836117f8565b905060006103e8610607610f6d565b61061191906117f8565b9050600061061f8783611810565b90508061062c8489611827565b6106369190611846565b95508561069c5760405162461bcd60e51b815260206004820152602e60248201527f5374726174656779426173652e6465706f7369743a206e65775368617265732060448201526d63616e6e6f74206265207a65726f60901b60648201526084016103b7565b6106a686856117f8565b60338190556f4b3b4ca85a86c47a098a223fffffffff10156107305760405162461bcd60e51b815260206004820152603c60248201527f5374726174656779426173652e6465706f7369743a20746f74616c536861726560448201527f73206578636565647320604d41585f544f54414c5f534841524553600000000060648201526084016103b7565b610749826103e860335461074491906117f8565b610fdf565b505050505092915050565b600054610100900460ff16158080156107745750600054600160ff909116105b8061078e5750303b15801561078e575060005460ff166001145b6107f15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103b7565b6000805460ff191660011790558015610814576000805461ff0019166101001790555b61081e8383611033565b8015610864576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6000610877610258836109cd565b92915050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa1580156108ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ee9190611778565b61090a5760405162461bcd60e51b81526004016103b79061179a565b600019600181905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000806103e860335461095c91906117f8565b905060006103e861096b610f6d565b61097591906117f8565b9050816109828583611827565b61098c9190611846565b949350505050565b600061087782610c48565b60006108776102f8836109cd565b60606040518060800160405280604d81526020016118bb604d9139905090565b604051633d3f06c960e11b81526001600160a01b0382811660048301523060248301526000917f000000000000000000000000000000000000000000000000000000000000000090911690637a7e0d9290604401602060405180830381865afa158015610a3e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190611868565b6001805460029081161415610ab55760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016103b7565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b2d5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e6167657260448201526064016103b7565b610b3884848461117e565b60335480831115610bc75760405162461bcd60e51b815260206004820152604d60248201527f5374726174656779426173652e77697468647261773a20616d6f756e7453686160448201527f726573206d757374206265206c657373207468616e206f7220657175616c207460648201526c6f20746f74616c53686172657360981b608482015260a4016103b7565b6000610bd56103e8836117f8565b905060006103e8610be4610f6d565b610bee91906117f8565b9050600082610bfd8784611827565b610c079190611846565b9050610c138685611810565b603355610c33610c238284611810565b6103e860335461074491906117f8565b610c3e888883611201565b5050505050505050565b6000806103e8603354610c5b91906117f8565b905060006103e8610c6a610f6d565b610c7491906117f8565b9050806109828386611827565b600061087782610949565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d039190611711565b6001600160a01b0316336001600160a01b031614610d335760405162461bcd60e51b81526004016103b79061172e565b600154198119600154191614610db15760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016103b7565b600181905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610505565b6001600160a01b038116610e765760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016103b7565b600054604080516001600160a01b03620100009093048316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6032546001600160a01b03838116911614610f695760405162461bcd60e51b815260206004820152603660248201527f5374726174656779426173652e6465706f7369743a2043616e206f6e6c79206460448201527532b837b9b4ba103ab73232b9363cb4b733aa37b5b2b760511b60648201526084016103b7565b5050565b6032546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fda9190611868565b905090565b7fd2494f3479e5da49d386657c292c610b5b01df313d07c62eb0cfa49924a31be88161101384670de0b6b3a7640000611827565b61101d9190611846565b6040519081526020015b60405180910390a15050565b600054610100900460ff1661109e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016103b7565b603280546001600160a01b0319166001600160a01b0384161790556110c4816000611215565b7f1c540707b00eb5427b6b774fc799d756516a54aee108b64b327acc55af557507603260009054906101000a90046001600160a01b0316836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190611881565b604080516001600160a01b03909316835260ff909116602083015201611027565b6032546001600160a01b038381169116146108645760405162461bcd60e51b815260206004820152603b60248201527f5374726174656779426173652e77697468647261773a2043616e206f6e6c792060448201527f77697468647261772074686520737472617465677920746f6b656e000000000060648201526084016103b7565b6108646001600160a01b0383168483611301565b6000546201000090046001600160a01b031615801561123c57506001600160a01b03821615155b6112be5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016103b7565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2610f6982610de8565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908401526108649286929160009161139191851690849061140e565b80519091501561086457808060200190518101906113af9190611778565b6108645760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103b7565b606061141d8484600085611427565b90505b9392505050565b6060824710156114885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103b7565b6001600160a01b0385163b6114df5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103b7565b600080866001600160a01b031685876040516114fb919061189e565b60006040518083038185875af1925050503d8060008114611538576040519150601f19603f3d011682016040523d82523d6000602084013e61153d565b606091505b509150915061154d828286611558565b979650505050505050565b60608315611567575081611420565b8251156115775782518084602001fd5b8160405162461bcd60e51b81526004016103b7919061169d565b6001600160a01b03811681146103c957600080fd5b6000602082840312156115b857600080fd5b813561142081611591565b6000602082840312156115d557600080fd5b5035919050565b600080604083850312156115ef57600080fd5b82356115fa81611591565b946020939093013593505050565b6000806040838503121561161b57600080fd5b823561162681611591565b9150602083013561163681611591565b809150509250929050565b60ff811681146103c957600080fd5b60006020828403121561166257600080fd5b813561142081611641565b60005b83811015611688578181015183820152602001611670565b83811115611697576000848401525b50505050565b60208152600082518060208401526116bc81604085016020870161166d565b601f01601f19169190910160400192915050565b6000806000606084860312156116e557600080fd5b83356116f081611591565b9250602084013561170081611591565b929592945050506040919091013590565b60006020828403121561172357600080fd5b815161142081611591565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60006020828403121561178a57600080fd5b8151801515811461142057600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000821982111561180b5761180b6117e2565b500190565b600082821015611822576118226117e2565b500390565b6000816000190483118215151615611841576118416117e2565b500290565b60008261186357634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561187a57600080fd5b5051919050565b60006020828403121561189357600080fd5b815161142081611641565b600082516118b081846020870161166d565b919091019291505056fe4261736520537472617465677920696d706c656d656e746174696f6e20746f20696e68657269742066726f6d20666f72206d6f726520636f6d706c657820696d706c656d656e746174696f6e73a264697066735822122010a959346f6109c589a9783919e1f435adfbf8e6f523baaaa3307a9e4b75ffcb64736f6c634300080c0033", } // StrategyBaseABI is the input ABI used to generate the binding from. diff --git a/pkg/bindings/StrategyBaseTVLLimits/binding.go b/pkg/bindings/StrategyBaseTVLLimits/binding.go index 063817b1a..c0b5f85d3 100644 --- a/pkg/bindings/StrategyBaseTVLLimits/binding.go +++ b/pkg/bindings/StrategyBaseTVLLimits/binding.go @@ -32,7 +32,7 @@ var ( // StrategyBaseTVLLimitsMetaData contains all meta data concerning the StrategyBaseTVLLimits contract. var StrategyBaseTVLLimitsMetaData = &bind.MetaData{ ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_strategyManager\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"newShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"explanation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getTVLLimits\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_maxPerDeposit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_maxTotalDeposits\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_underlyingToken\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_underlyingToken\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxPerDeposit\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"maxTotalDeposits\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setTVLLimits\",\"inputs\":[{\"name\":\"newMaxPerDeposit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"newMaxTotalDeposits\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"shares\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"sharesToUnderlying\",\"inputs\":[{\"name\":\"amountShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"sharesToUnderlyingView\",\"inputs\":[{\"name\":\"amountShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalShares\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"underlyingToShares\",\"inputs\":[{\"name\":\"amountUnderlying\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"underlyingToSharesView\",\"inputs\":[{\"name\":\"amountUnderlying\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"underlyingToken\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"userUnderlying\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"userUnderlyingView\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amountShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"ExchangeRateEmitted\",\"inputs\":[{\"name\":\"rate\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxPerDepositUpdated\",\"inputs\":[{\"name\":\"previousValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxTotalDepositsUpdated\",\"inputs\":[{\"name\":\"previousValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newValue\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StrategyTokenSet\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIERC20\"},{\"name\":\"decimals\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001f4d38038062001f4d833981016040819052620000349162000116565b6001600160a01b038116608052806200004c62000054565b505062000148565b600054610100900460ff1615620000c15760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000114576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200012957600080fd5b81516001600160a01b03811681146200014157600080fd5b9392505050565b608051611dd46200017960003960008181610216015281816107a901528181610be70152610cb20152611dd46000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c80635c975abb116100de578063ab5921e111610097578063df6fadc111610071578063df6fadc114610366578063e3dae51c14610381578063f3e7387514610394578063fabc1cbc146103a757600080fd5b8063ab5921e11461032b578063ce7c2ac214610340578063d9caed121461035357600080fd5b80635c975abb146102c857806361b01b5d146102d05780637a8b2637146102d9578063886f1195146102ec5780638c871019146103055780638f6a62401461031857600080fd5b80633a98ef391161014b578063485cc95511610125578063485cc9551461026b578063553ca5f81461027e578063595c6a67146102915780635ac86ab71461029957600080fd5b80633a98ef391461023857806343fe08b01461024f57806347e7ef241461025857600080fd5b8063019e27291461019357806310d67a2f146101a857806311c70c9d146101bb578063136439dd146101ce5780632495a599146101e157806339b70e3814610211575b600080fd5b6101a66101a1366004611983565b6103ba565b005b6101a66101b63660046119cd565b61049d565b6101a66101c93660046119ea565b610550565b6101a66101dc366004611a0c565b610605565b6032546101f4906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101f47f000000000000000000000000000000000000000000000000000000000000000081565b61024160335481565b604051908152602001610208565b61024160645481565b610241610266366004611a25565b610749565b6101a6610279366004611a51565b61098d565b61024161028c3660046119cd565b610a5b565b6101a6610a6f565b6102b86102a7366004611a99565b6001805460ff9092161b9081161490565b6040519015158152602001610208565b600154610241565b61024160655481565b6102416102e7366004611a0c565b610b3b565b6000546101f4906201000090046001600160a01b031681565b610241610313366004611a0c565b610b86565b6102416103263660046119cd565b610b91565b610333610b9f565b6040516102089190611ae6565b61024161034e3660046119cd565b610bbf565b6101a6610361366004611b19565b610c54565b60645460655460408051928352602083019190915201610208565b61024161038f366004611a0c565b610e3a565b6102416103a2366004611a0c565b610e73565b6101a66103b5366004611a0c565b610e7e565b600054610100900460ff16158080156103da5750600054600160ff909116105b806103f45750303b1580156103f4575060005460ff166001145b6104195760405162461bcd60e51b815260040161041090611b5a565b60405180910390fd5b6000805460ff19166001179055801561043c576000805461ff0019166101001790555b6104468585610fda565b61045083836110e7565b8015610496576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105149190611ba8565b6001600160a01b0316336001600160a01b0316146105445760405162461bcd60e51b815260040161041090611bc5565b61054d8161123a565b50565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c79190611ba8565b6001600160a01b0316336001600160a01b0316146105f75760405162461bcd60e51b815260040161041090611bc5565b6106018282610fda565b5050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106769190611c0f565b6106925760405162461bcd60e51b815260040161041090611c31565b6001548181161461070b5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610410565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6001805460009182918116141561079e5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610410565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108165760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e616765726044820152606401610410565b610820848461133f565b60335460006108316103e883611c8f565b905060006103e8610840611421565b61084a9190611c8f565b905060006108588783611ca7565b9050806108658489611cbe565b61086f9190611cdd565b9550856108d55760405162461bcd60e51b815260206004820152602e60248201527f5374726174656779426173652e6465706f7369743a206e65775368617265732060448201526d63616e6e6f74206265207a65726f60901b6064820152608401610410565b6108df8685611c8f565b60338190556f4b3b4ca85a86c47a098a223fffffffff10156109695760405162461bcd60e51b815260206004820152603c60248201527f5374726174656779426173652e6465706f7369743a20746f74616c536861726560448201527f73206578636565647320604d41585f544f54414c5f53484152455360000000006064820152608401610410565b610982826103e860335461097d9190611c8f565b611493565b505050505092915050565b600054610100900460ff16158080156109ad5750600054600160ff909116105b806109c75750303b1580156109c7575060005460ff166001145b6109e35760405162461bcd60e51b815260040161041090611b5a565b6000805460ff191660011790558015610a06576000805461ff0019166101001790555b610a1083836110e7565b8015610a56576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6000610a696102e783610bbf565b92915050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae09190611c0f565b610afc5760405162461bcd60e51b815260040161041090611c31565b600019600181905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000806103e8603354610b4e9190611c8f565b905060006103e8610b5d611421565b610b679190611c8f565b905081610b748583611cbe565b610b7e9190611cdd565b949350505050565b6000610a6982610e3a565b6000610a696103a283610bbf565b60606040518060800160405280604d8152602001611d52604d9139905090565b604051633d3f06c960e11b81526001600160a01b0382811660048301523060248301526000917f000000000000000000000000000000000000000000000000000000000000000090911690637a7e0d9290604401602060405180830381865afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a699190611cff565b6001805460029081161415610ca75760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610410565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610d1f5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e616765726044820152606401610410565b610d2a8484846114df565b60335480831115610db95760405162461bcd60e51b815260206004820152604d60248201527f5374726174656779426173652e77697468647261773a20616d6f756e7453686160448201527f726573206d757374206265206c657373207468616e206f7220657175616c207460648201526c6f20746f74616c53686172657360981b608482015260a401610410565b6000610dc76103e883611c8f565b905060006103e8610dd6611421565b610de09190611c8f565b9050600082610def8784611cbe565b610df99190611cdd565b9050610e058685611ca7565b603355610e25610e158284611ca7565b6103e860335461097d9190611c8f565b610e30888883611562565b5050505050505050565b6000806103e8603354610e4d9190611c8f565b905060006103e8610e5c611421565b610e669190611c8f565b905080610b748386611cbe565b6000610a6982610b3b565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ed1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef59190611ba8565b6001600160a01b0316336001600160a01b031614610f255760405162461bcd60e51b815260040161041090611bc5565b600154198119600154191614610fa35760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610410565b600181905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161073e565b60645460408051918252602082018490527ff97ed4e083acac67830025ecbc756d8fe847cdbdca4cee3fe1e128e98b54ecb5910160405180910390a160655460408051918252602082018390527f6ab181e0440bfbf4bacdf2e99674735ce6638005490688c5f994f5399353e452910160405180910390a1808211156110dc5760405162461bcd60e51b815260206004820152604b60248201527f53747261746567794261736554564c4c696d6974732e5f73657454564c4c696d60448201527f6974733a206d61785065724465706f7369742065786365656473206d6178546f60648201526a74616c4465706f7369747360a81b608482015260a401610410565b606491909155606555565b600054610100900460ff166111525760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610410565b603280546001600160a01b0319166001600160a01b038416179055611178816000611576565b7f1c540707b00eb5427b6b774fc799d756516a54aee108b64b327acc55af557507603260009054906101000a90046001600160a01b0316836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112119190611d18565b604080516001600160a01b03909316835260ff9091166020830152015b60405180910390a15050565b6001600160a01b0381166112c85760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610410565b600054604080516001600160a01b03620100009093048316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6064548111156113a95760405162461bcd60e51b815260206004820152602f60248201527f53747261746567794261736554564c4c696d6974733a206d617820706572206460448201526e195c1bdcda5d08195e18d959591959608a1b6064820152608401610410565b6065546113b4611421565b11156114175760405162461bcd60e51b815260206004820152602c60248201527f53747261746567794261736554564c4c696d6974733a206d6178206465706f7360448201526b1a5d1cc8195e18d95959195960a21b6064820152608401610410565b6106018282611662565b6032546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561146a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148e9190611cff565b905090565b7fd2494f3479e5da49d386657c292c610b5b01df313d07c62eb0cfa49924a31be8816114c784670de0b6b3a7640000611cbe565b6114d19190611cdd565b60405190815260200161122e565b6032546001600160a01b03838116911614610a565760405162461bcd60e51b815260206004820152603b60248201527f5374726174656779426173652e77697468647261773a2043616e206f6e6c792060448201527f77697468647261772074686520737472617465677920746f6b656e00000000006064820152608401610410565b610a566001600160a01b03831684836116de565b6000546201000090046001600160a01b031615801561159d57506001600160a01b03821615155b61161f5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610410565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26106018261123a565b6032546001600160a01b038381169116146106015760405162461bcd60e51b815260206004820152603660248201527f5374726174656779426173652e6465706f7369743a2043616e206f6e6c79206460448201527532b837b9b4ba103ab73232b9363cb4b733aa37b5b2b760511b6064820152608401610410565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490840152610a569286929160009161176e9185169084906117eb565b805190915015610a56578080602001905181019061178c9190611c0f565b610a565760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610410565b60606117fa8484600085611804565b90505b9392505050565b6060824710156118655760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610410565b6001600160a01b0385163b6118bc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610410565b600080866001600160a01b031685876040516118d89190611d35565b60006040518083038185875af1925050503d8060008114611915576040519150601f19603f3d011682016040523d82523d6000602084013e61191a565b606091505b509150915061192a828286611935565b979650505050505050565b606083156119445750816117fd565b8251156119545782518084602001fd5b8160405162461bcd60e51b81526004016104109190611ae6565b6001600160a01b038116811461054d57600080fd5b6000806000806080858703121561199957600080fd5b843593506020850135925060408501356119b28161196e565b915060608501356119c28161196e565b939692955090935050565b6000602082840312156119df57600080fd5b81356117fd8161196e565b600080604083850312156119fd57600080fd5b50508035926020909101359150565b600060208284031215611a1e57600080fd5b5035919050565b60008060408385031215611a3857600080fd5b8235611a438161196e565b946020939093013593505050565b60008060408385031215611a6457600080fd5b8235611a6f8161196e565b91506020830135611a7f8161196e565b809150509250929050565b60ff8116811461054d57600080fd5b600060208284031215611aab57600080fd5b81356117fd81611a8a565b60005b83811015611ad1578181015183820152602001611ab9565b83811115611ae0576000848401525b50505050565b6020815260008251806020840152611b05816040850160208701611ab6565b601f01601f19169190910160400192915050565b600080600060608486031215611b2e57600080fd5b8335611b398161196e565b92506020840135611b498161196e565b929592945050506040919091013590565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b600060208284031215611bba57600080fd5b81516117fd8161196e565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611c2157600080fd5b815180151581146117fd57600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115611ca257611ca2611c79565b500190565b600082821015611cb957611cb9611c79565b500390565b6000816000190483118215151615611cd857611cd8611c79565b500290565b600082611cfa57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215611d1157600080fd5b5051919050565b600060208284031215611d2a57600080fd5b81516117fd81611a8a565b60008251611d47818460208701611ab6565b919091019291505056fe4261736520537472617465677920696d706c656d656e746174696f6e20746f20696e68657269742066726f6d20666f72206d6f726520636f6d706c657820696d706c656d656e746174696f6e73a26469706673582212207629c6ae7de5baead1b34690cf58d97cbb4740b886269a92273b5fcdf7067a4e64736f6c634300080c0033", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001f4d38038062001f4d833981016040819052620000349162000116565b6001600160a01b038116608052806200004c62000054565b505062000148565b600054610100900460ff1615620000c15760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000114576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200012957600080fd5b81516001600160a01b03811681146200014157600080fd5b9392505050565b608051611dd46200017960003960008181610216015281816107a901528181610be70152610cb20152611dd46000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c80635c975abb116100de578063ab5921e111610097578063df6fadc111610071578063df6fadc114610366578063e3dae51c14610381578063f3e7387514610394578063fabc1cbc146103a757600080fd5b8063ab5921e11461032b578063ce7c2ac214610340578063d9caed121461035357600080fd5b80635c975abb146102c857806361b01b5d146102d05780637a8b2637146102d9578063886f1195146102ec5780638c871019146103055780638f6a62401461031857600080fd5b80633a98ef391161014b578063485cc95511610125578063485cc9551461026b578063553ca5f81461027e578063595c6a67146102915780635ac86ab71461029957600080fd5b80633a98ef391461023857806343fe08b01461024f57806347e7ef241461025857600080fd5b8063019e27291461019357806310d67a2f146101a857806311c70c9d146101bb578063136439dd146101ce5780632495a599146101e157806339b70e3814610211575b600080fd5b6101a66101a1366004611983565b6103ba565b005b6101a66101b63660046119cd565b61049d565b6101a66101c93660046119ea565b610550565b6101a66101dc366004611a0c565b610605565b6032546101f4906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101f47f000000000000000000000000000000000000000000000000000000000000000081565b61024160335481565b604051908152602001610208565b61024160645481565b610241610266366004611a25565b610749565b6101a6610279366004611a51565b61098d565b61024161028c3660046119cd565b610a5b565b6101a6610a6f565b6102b86102a7366004611a99565b6001805460ff9092161b9081161490565b6040519015158152602001610208565b600154610241565b61024160655481565b6102416102e7366004611a0c565b610b3b565b6000546101f4906201000090046001600160a01b031681565b610241610313366004611a0c565b610b86565b6102416103263660046119cd565b610b91565b610333610b9f565b6040516102089190611ae6565b61024161034e3660046119cd565b610bbf565b6101a6610361366004611b19565b610c54565b60645460655460408051928352602083019190915201610208565b61024161038f366004611a0c565b610e3a565b6102416103a2366004611a0c565b610e73565b6101a66103b5366004611a0c565b610e7e565b600054610100900460ff16158080156103da5750600054600160ff909116105b806103f45750303b1580156103f4575060005460ff166001145b6104195760405162461bcd60e51b815260040161041090611b5a565b60405180910390fd5b6000805460ff19166001179055801561043c576000805461ff0019166101001790555b6104468585610fda565b61045083836110e7565b8015610496576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105149190611ba8565b6001600160a01b0316336001600160a01b0316146105445760405162461bcd60e51b815260040161041090611bc5565b61054d8161123a565b50565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c79190611ba8565b6001600160a01b0316336001600160a01b0316146105f75760405162461bcd60e51b815260040161041090611bc5565b6106018282610fda565b5050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106769190611c0f565b6106925760405162461bcd60e51b815260040161041090611c31565b6001548181161461070b5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610410565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6001805460009182918116141561079e5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610410565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108165760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e616765726044820152606401610410565b610820848461133f565b60335460006108316103e883611c8f565b905060006103e8610840611421565b61084a9190611c8f565b905060006108588783611ca7565b9050806108658489611cbe565b61086f9190611cdd565b9550856108d55760405162461bcd60e51b815260206004820152602e60248201527f5374726174656779426173652e6465706f7369743a206e65775368617265732060448201526d63616e6e6f74206265207a65726f60901b6064820152608401610410565b6108df8685611c8f565b60338190556f4b3b4ca85a86c47a098a223fffffffff10156109695760405162461bcd60e51b815260206004820152603c60248201527f5374726174656779426173652e6465706f7369743a20746f74616c536861726560448201527f73206578636565647320604d41585f544f54414c5f53484152455360000000006064820152608401610410565b610982826103e860335461097d9190611c8f565b611493565b505050505092915050565b600054610100900460ff16158080156109ad5750600054600160ff909116105b806109c75750303b1580156109c7575060005460ff166001145b6109e35760405162461bcd60e51b815260040161041090611b5a565b6000805460ff191660011790558015610a06576000805461ff0019166101001790555b610a1083836110e7565b8015610a56576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6000610a696102e783610bbf565b92915050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae09190611c0f565b610afc5760405162461bcd60e51b815260040161041090611c31565b600019600181905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000806103e8603354610b4e9190611c8f565b905060006103e8610b5d611421565b610b679190611c8f565b905081610b748583611cbe565b610b7e9190611cdd565b949350505050565b6000610a6982610e3a565b6000610a696103a283610bbf565b60606040518060800160405280604d8152602001611d52604d9139905090565b604051633d3f06c960e11b81526001600160a01b0382811660048301523060248301526000917f000000000000000000000000000000000000000000000000000000000000000090911690637a7e0d9290604401602060405180830381865afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a699190611cff565b6001805460029081161415610ca75760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610410565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610d1f5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e616765726044820152606401610410565b610d2a8484846114df565b60335480831115610db95760405162461bcd60e51b815260206004820152604d60248201527f5374726174656779426173652e77697468647261773a20616d6f756e7453686160448201527f726573206d757374206265206c657373207468616e206f7220657175616c207460648201526c6f20746f74616c53686172657360981b608482015260a401610410565b6000610dc76103e883611c8f565b905060006103e8610dd6611421565b610de09190611c8f565b9050600082610def8784611cbe565b610df99190611cdd565b9050610e058685611ca7565b603355610e25610e158284611ca7565b6103e860335461097d9190611c8f565b610e30888883611562565b5050505050505050565b6000806103e8603354610e4d9190611c8f565b905060006103e8610e5c611421565b610e669190611c8f565b905080610b748386611cbe565b6000610a6982610b3b565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ed1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef59190611ba8565b6001600160a01b0316336001600160a01b031614610f255760405162461bcd60e51b815260040161041090611bc5565b600154198119600154191614610fa35760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610410565b600181905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161073e565b60645460408051918252602082018490527ff97ed4e083acac67830025ecbc756d8fe847cdbdca4cee3fe1e128e98b54ecb5910160405180910390a160655460408051918252602082018390527f6ab181e0440bfbf4bacdf2e99674735ce6638005490688c5f994f5399353e452910160405180910390a1808211156110dc5760405162461bcd60e51b815260206004820152604b60248201527f53747261746567794261736554564c4c696d6974732e5f73657454564c4c696d60448201527f6974733a206d61785065724465706f7369742065786365656473206d6178546f60648201526a74616c4465706f7369747360a81b608482015260a401610410565b606491909155606555565b600054610100900460ff166111525760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610410565b603280546001600160a01b0319166001600160a01b038416179055611178816000611576565b7f1c540707b00eb5427b6b774fc799d756516a54aee108b64b327acc55af557507603260009054906101000a90046001600160a01b0316836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112119190611d18565b604080516001600160a01b03909316835260ff9091166020830152015b60405180910390a15050565b6001600160a01b0381166112c85760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610410565b600054604080516001600160a01b03620100009093048316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6064548111156113a95760405162461bcd60e51b815260206004820152602f60248201527f53747261746567794261736554564c4c696d6974733a206d617820706572206460448201526e195c1bdcda5d08195e18d959591959608a1b6064820152608401610410565b6065546113b4611421565b11156114175760405162461bcd60e51b815260206004820152602c60248201527f53747261746567794261736554564c4c696d6974733a206d6178206465706f7360448201526b1a5d1cc8195e18d95959195960a21b6064820152608401610410565b6106018282611662565b6032546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561146a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148e9190611cff565b905090565b7fd2494f3479e5da49d386657c292c610b5b01df313d07c62eb0cfa49924a31be8816114c784670de0b6b3a7640000611cbe565b6114d19190611cdd565b60405190815260200161122e565b6032546001600160a01b03838116911614610a565760405162461bcd60e51b815260206004820152603b60248201527f5374726174656779426173652e77697468647261773a2043616e206f6e6c792060448201527f77697468647261772074686520737472617465677920746f6b656e00000000006064820152608401610410565b610a566001600160a01b03831684836116de565b6000546201000090046001600160a01b031615801561159d57506001600160a01b03821615155b61161f5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610410565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26106018261123a565b6032546001600160a01b038381169116146106015760405162461bcd60e51b815260206004820152603660248201527f5374726174656779426173652e6465706f7369743a2043616e206f6e6c79206460448201527532b837b9b4ba103ab73232b9363cb4b733aa37b5b2b760511b6064820152608401610410565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490840152610a569286929160009161176e9185169084906117eb565b805190915015610a56578080602001905181019061178c9190611c0f565b610a565760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610410565b60606117fa8484600085611804565b90505b9392505050565b6060824710156118655760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610410565b6001600160a01b0385163b6118bc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610410565b600080866001600160a01b031685876040516118d89190611d35565b60006040518083038185875af1925050503d8060008114611915576040519150601f19603f3d011682016040523d82523d6000602084013e61191a565b606091505b509150915061192a828286611935565b979650505050505050565b606083156119445750816117fd565b8251156119545782518084602001fd5b8160405162461bcd60e51b81526004016104109190611ae6565b6001600160a01b038116811461054d57600080fd5b6000806000806080858703121561199957600080fd5b843593506020850135925060408501356119b28161196e565b915060608501356119c28161196e565b939692955090935050565b6000602082840312156119df57600080fd5b81356117fd8161196e565b600080604083850312156119fd57600080fd5b50508035926020909101359150565b600060208284031215611a1e57600080fd5b5035919050565b60008060408385031215611a3857600080fd5b8235611a438161196e565b946020939093013593505050565b60008060408385031215611a6457600080fd5b8235611a6f8161196e565b91506020830135611a7f8161196e565b809150509250929050565b60ff8116811461054d57600080fd5b600060208284031215611aab57600080fd5b81356117fd81611a8a565b60005b83811015611ad1578181015183820152602001611ab9565b83811115611ae0576000848401525b50505050565b6020815260008251806020840152611b05816040850160208701611ab6565b601f01601f19169190910160400192915050565b600080600060608486031215611b2e57600080fd5b8335611b398161196e565b92506020840135611b498161196e565b929592945050506040919091013590565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b600060208284031215611bba57600080fd5b81516117fd8161196e565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611c2157600080fd5b815180151581146117fd57600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115611ca257611ca2611c79565b500190565b600082821015611cb957611cb9611c79565b500390565b6000816000190483118215151615611cd857611cd8611c79565b500290565b600082611cfa57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215611d1157600080fd5b5051919050565b600060208284031215611d2a57600080fd5b81516117fd81611a8a565b60008251611d47818460208701611ab6565b919091019291505056fe4261736520537472617465677920696d706c656d656e746174696f6e20746f20696e68657269742066726f6d20666f72206d6f726520636f6d706c657820696d706c656d656e746174696f6e73a26469706673582212208549fd2100ff79e56d7fded410ac662be502dbe16e18a815844148c99c0b5bc864736f6c634300080c0033", } // StrategyBaseTVLLimitsABI is the input ABI used to generate the binding from. diff --git a/pkg/bindings/StrategyFactory/binding.go b/pkg/bindings/StrategyFactory/binding.go index e7c2bdc25..cd0633c74 100644 --- a/pkg/bindings/StrategyFactory/binding.go +++ b/pkg/bindings/StrategyFactory/binding.go @@ -32,7 +32,7 @@ var ( // StrategyFactoryMetaData contains all meta data concerning the StrategyFactory contract. var StrategyFactoryMetaData = &bind.MetaData{ ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_strategyManager\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"blacklistTokens\",\"inputs\":[{\"name\":\"tokens\",\"type\":\"address[]\",\"internalType\":\"contractIERC20[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deployNewStrategy\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"outputs\":[{\"name\":\"newStrategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deployedStrategies\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_initialOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"_initialPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_strategyBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isBlacklisted\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"removeStrategiesFromWhitelist\",\"inputs\":[{\"name\":\"strategiesToRemoveFromWhitelist\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setThirdPartyTransfersForbidden\",\"inputs\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"value\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"strategyBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"strategyManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategyManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"whitelistStrategies\",\"inputs\":[{\"name\":\"strategiesToWhitelist\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"thirdPartyTransfersForbiddenValues\",\"type\":\"bool[]\",\"internalType\":\"bool[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StrategyBeaconModified\",\"inputs\":[{\"name\":\"previousBeacon\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIBeacon\"},{\"name\":\"newBeacon\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIBeacon\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StrategySetForToken\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIERC20\"},{\"name\":\"strategy\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIStrategy\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TokenBlacklisted\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIERC20\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620024ae380380620024ae833981016040819052620000349162000114565b6001600160a01b0381166080526200004b62000052565b5062000146565b603354610100900460ff1615620000bf5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60335460ff908116101562000112576033805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200012757600080fd5b81516001600160a01b03811681146200013f57600080fd5b9392505050565b608051612329620001856000396000818161019701528181610829015281816108cc01528181610a1d01528181610d4a015261111101526123296000f3fe60806040523480156200001157600080fd5b5060043610620001455760003560e01c80636b9b622911620000bb578063f0062d9a116200007a578063f0062d9a14620002e1578063f2fde38b14620002f5578063fabc1cbc146200030c578063fe38b32d1462000323578063fe575a87146200033a57600080fd5b80636b9b62291462000283578063715018a6146200029a578063886f119514620002a45780638da5cb5b14620002b8578063be20309414620002ca57600080fd5b8063581dfd651162000108578063581dfd6514620001ed578063595c6a6714620002195780635ac86ab714620002235780635c975abb146200025a578063697d54b4146200026c57600080fd5b806310d67a2f146200014a578063136439dd146200016357806323103c41146200017a57806339b70e3814620001915780634e5a426314620001d6575b600080fd5b620001616200015b366004620014d8565b62000360565b005b6200016162000174366004620014ff565b62000424565b620001616200018b36600462001568565b6200056b565b620001b97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b62000161620001e7366004620015bd565b6200089b565b620001b9620001fe366004620014d8565b6001602052600090815260409020546001600160a01b031681565b620001616200092f565b6200024962000234366004620015fb565b609954600160ff9092169190911b9081161490565b6040519015158152602001620001cd565b609954604051908152602001620001cd565b620001616200027d36600462001620565b620009fc565b620001b962000294366004620014d8565b62000a5a565b6200016162000dc1565b609854620001b9906001600160a01b031681565b6066546001600160a01b0316620001b9565b62000161620002db36600462001693565b62000dd9565b600054620001b9906001600160a01b031681565b6200016162000306366004620014d8565b62000f0f565b620001616200031d366004620014ff565b62000f8b565b620001616200033436600462001568565b620010f0565b620002496200034b366004620014d8565b60026020526000908152604090205460ff1681565b609860009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620003b4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003da9190620016ed565b6001600160a01b0316336001600160a01b031614620004165760405162461bcd60e51b81526004016200040d906200170d565b60405180910390fd5b62000421816200114a565b50565b60985460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156200046d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000493919062001757565b620004b25760405162461bcd60e51b81526004016200040d9062001777565b609954818116146200052d5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016200040d565b609981905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6200057562001243565b60008167ffffffffffffffff811115620005935762000593620017bf565b604051908082528060200260200182016040528015620005bd578160200160208202803683370190505b5090506000805b83811015620008075760026000868684818110620005e657620005e6620017d5565b9050602002016020810190620005fd9190620014d8565b6001600160a01b0316815260208101919091526040016000205460ff16156200069b5760405162461bcd60e51b815260206004820152604360248201527f5374726174656779466163746f72792e626c61636b6c697374546f6b656e733a60448201527f2043616e6e6f7420626c61636b6c697374206465706c6f79656420737472617460648201526265677960e81b608482015260a4016200040d565b600160026000878785818110620006b657620006b6620017d5565b9050602002016020810190620006cd9190620014d8565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f75519c51f39873ec0e27dd3bbc09549e4865a113f505393fb9eab5898f6418b38585838181106200072b576200072b620017d5565b9050602002016020810190620007429190620014d8565b6040516001600160a01b03909116815260200160405180910390a1600060016000878785818110620007785762000778620017d5565b90506020020160208101906200078f9190620014d8565b6001600160a01b0390811682526020820192909252604001600020541690508015620007f35780848481518110620007cb57620007cb620017d5565b6001600160a01b039092166020928302919091019091015282620007ef81620017eb565b9350505b50620007ff81620017eb565b9050620005c4565b50808252801562000895576040516316bb16b760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b5d8b5b890620008609085906004016200185b565b600060405180830381600087803b1580156200087b57600080fd5b505af115801562000890573d6000803e3d6000fd5b505050505b50505050565b620008a562001243565b604051634e5a426360e01b81526001600160a01b03838116600483015282151560248301527f00000000000000000000000000000000000000000000000000000000000000001690634e5a4263906044015b600060405180830381600087803b1580156200091257600080fd5b505af115801562000927573d6000803e3d6000fd5b505050505050565b60985460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa15801562000978573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200099e919062001757565b620009bd5760405162461bcd60e51b81526004016200040d9062001777565b600019609981905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b62000a0662001243565b60405163df5b354760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063df5b35479062000860908790879087908790600401620018b2565b60995460009081906001908116141562000ab75760405162461bcd60e51b815260206004820152601960248201527f5061757361626c653a20696e646578206973207061757365640000000000000060448201526064016200040d565b6001600160a01b03831660009081526002602052604090205460ff161562000b485760405162461bcd60e51b815260206004820152603760248201527f5374726174656779466163746f72792e6465706c6f794e65775374726174656760448201527f793a20546f6b656e20697320626c61636b6c697374656400000000000000000060648201526084016200040d565b6001600160a01b03838116600090815260016020526040902054161562000be65760405162461bcd60e51b8152602060048201526044602482018190527f5374726174656779466163746f72792e6465706c6f794e657753747261746567908201527f793a20537472617465677920616c72656164792065786973747320666f72207460648201526337b5b2b760e11b608482015260a4016200040d565b600080546098546040516001600160a01b038781166024830152918216604482015291169063485cc95560e01b9060640160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905162000c5690620014b4565b62000c6392919062001916565b604051809103906000f08015801562000c80573d6000803e3d6000fd5b50905062000c8f84826200129f565b604080516001808252818301909252600091602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337019050509050828260008151811062000ceb5762000ceb620017d5565b60200260200101906001600160a01b031690816001600160a01b03168152505060008160008151811062000d235762000d23620017d5565b9115156020928302919091019091015260405163df5b354760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063df5b35479062000d8390859085906004016200197e565b600060405180830381600087803b15801562000d9e57600080fd5b505af115801562000db3573d6000803e3d6000fd5b509498975050505050505050565b62000dcb62001243565b62000dd760006200130a565b565b603354610100900460ff161580801562000dfa5750603354600160ff909116105b8062000e165750303b15801562000e16575060335460ff166001145b62000e7b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016200040d565b6033805460ff19166001179055801562000e9f576033805461ff0019166101001790555b62000eaa856200130a565b62000eb684846200135c565b62000ec1826200144b565b801562000f08576033805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b62000f1962001243565b6001600160a01b03811662000f805760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016200040d565b62000421816200130a565b609860009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000fdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620010059190620016ed565b6001600160a01b0316336001600160a01b031614620010385760405162461bcd60e51b81526004016200040d906200170d565b609954198119609954191614620010b85760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016200040d565b609981905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200162000560565b620010fa62001243565b6040516316bb16b760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b5d8b5b890620008f79085908590600401620019db565b6001600160a01b038116620011da5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016200040d565b609854604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1609880546001600160a01b0319166001600160a01b0392909216919091179055565b6066546001600160a01b0316331462000dd75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200040d565b6001600160a01b0382811660008181526001602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527f6852a55230ef089d785bce7ffbf757985de34026df90a87d7b4a6e56f95d251f910160405180910390a15050565b606680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6098546001600160a01b03161580156200137e57506001600160a01b03821615155b620014025760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016200040d565b609981905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a262001447826200114a565b5050565b600054604080516001600160a01b03928316815291831660208301527fe21755962a7d7e100b59b9c3e4d4b54085b146313719955efb6a7a25c5c7feee910160405180910390a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b6108fa80620019fa83390190565b6001600160a01b03811681146200042157600080fd5b600060208284031215620014eb57600080fd5b8135620014f881620014c2565b9392505050565b6000602082840312156200151257600080fd5b5035919050565b60008083601f8401126200152c57600080fd5b50813567ffffffffffffffff8111156200154557600080fd5b6020830191508360208260051b85010111156200156157600080fd5b9250929050565b600080602083850312156200157c57600080fd5b823567ffffffffffffffff8111156200159457600080fd5b620015a28582860162001519565b90969095509350505050565b80151581146200042157600080fd5b60008060408385031215620015d157600080fd5b8235620015de81620014c2565b91506020830135620015f081620015ae565b809150509250929050565b6000602082840312156200160e57600080fd5b813560ff81168114620014f857600080fd5b600080600080604085870312156200163757600080fd5b843567ffffffffffffffff808211156200165057600080fd5b6200165e8883890162001519565b909650945060208701359150808211156200167857600080fd5b50620016878782880162001519565b95989497509550505050565b60008060008060808587031215620016aa57600080fd5b8435620016b781620014c2565b93506020850135620016c981620014c2565b9250604085013591506060850135620016e281620014c2565b939692955090935050565b6000602082840312156200170057600080fd5b8151620014f881620014c2565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b6000602082840312156200176a57600080fd5b8151620014f881620015ae565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006000198214156200180e57634e487b7160e01b600052601160045260246000fd5b5060010190565b600081518084526020808501945080840160005b83811015620018505781516001600160a01b03168752958201959082019060010162001829565b509495945050505050565b602081526000620014f8602083018462001815565b8183526000602080850194508260005b85811015620018505781356200189681620014c2565b6001600160a01b03168752958201959082019060010162001880565b604081526000620018c860408301868862001870565b8281036020848101919091528482528591810160005b8681101562001909578335620018f481620015ae565b151582529282019290820190600101620018de565b5098975050505050505050565b60018060a01b038316815260006020604081840152835180604085015260005b81811015620019545785810183015185820160600152820162001936565b8181111562001967576000606083870101525b50601f01601f191692909201606001949350505050565b60408152600062001993604083018562001815565b82810360208481019190915284518083528582019282019060005b81811015620019ce578451151583529383019391830191600101620019ae565b5090979650505050505050565b602081526000620019f160208301848662001870565b94935050505056fe60806040526040516108fa3803806108fa83398101604081905261002291610456565b61002e82826000610035565b5050610580565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610516565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610516565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108d3602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b60606001600160a01b0384163b6103495760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610169565b600080856001600160a01b0316856040516103649190610531565b600060405180830381855af49150503d806000811461039f576040519150601f19603f3d011682016040523d82523d6000602084013e6103a4565b606091505b5090925090506103b58282866103bf565b9695505050505050565b606083156103ce5750816102c8565b8251156103de5782518084602001fd5b8160405162461bcd60e51b8152600401610169919061054d565b80516001600160a01b038116811461040f57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044557818101518382015260200161042d565b838111156100f95750506000910152565b6000806040838503121561046957600080fd5b610472836103f8565b60208401519092506001600160401b038082111561048f57600080fd5b818501915085601f8301126104a357600080fd5b8151818111156104b5576104b5610414565b604051601f8201601f19908116603f011681019083821181831017156104dd576104dd610414565b816040528281528860208487010111156104f657600080fd5b61050783602083016020880161042a565b80955050505050509250929050565b60006020828403121561052857600080fd5b6102c8826103f8565b6000825161054381846020870161042a565b9190910192915050565b602081526000825180602084015261056c81604085016020870161042a565b601f01601f19169190910160400192915050565b6103448061058f6000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102e860279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb919061023f565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b60606001600160a01b0384163b6101915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084015b60405180910390fd5b600080856001600160a01b0316856040516101ac9190610298565b600060405180830381855af49150503d80600081146101e7576040519150601f19603f3d011682016040523d82523d6000602084013e6101ec565b606091505b50915091506101fc828286610206565b9695505050505050565b6060831561021557508161004e565b8251156102255782518084602001fd5b8160405162461bcd60e51b815260040161018891906102b4565b60006020828403121561025157600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028357818101518382015260200161026b565b83811115610292576000848401525b50505050565b600082516102aa818460208701610268565b9190910192915050565b60208152600082518060208401526102d3816040850160208701610268565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212206225174df4b558257f66ac9aa53b52c29cdd29a561b03eb6d75a95018aff3e5864736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122076da37a44aafe5d5fc031e547b2f174393a2fbeabf6102f18e09090e854763c664736f6c634300080c0033", + Bin: "0x60a06040523480156200001157600080fd5b50604051620024ae380380620024ae833981016040819052620000349162000114565b6001600160a01b0381166080526200004b62000052565b5062000146565b603354610100900460ff1615620000bf5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60335460ff908116101562000112576033805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200012757600080fd5b81516001600160a01b03811681146200013f57600080fd5b9392505050565b608051612329620001856000396000818161019701528181610829015281816108cc01528181610a1d01528181610d4a015261111101526123296000f3fe60806040523480156200001157600080fd5b5060043610620001455760003560e01c80636b9b622911620000bb578063f0062d9a116200007a578063f0062d9a14620002e1578063f2fde38b14620002f5578063fabc1cbc146200030c578063fe38b32d1462000323578063fe575a87146200033a57600080fd5b80636b9b62291462000283578063715018a6146200029a578063886f119514620002a45780638da5cb5b14620002b8578063be20309414620002ca57600080fd5b8063581dfd651162000108578063581dfd6514620001ed578063595c6a6714620002195780635ac86ab714620002235780635c975abb146200025a578063697d54b4146200026c57600080fd5b806310d67a2f146200014a578063136439dd146200016357806323103c41146200017a57806339b70e3814620001915780634e5a426314620001d6575b600080fd5b620001616200015b366004620014d8565b62000360565b005b6200016162000174366004620014ff565b62000424565b620001616200018b36600462001568565b6200056b565b620001b97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b62000161620001e7366004620015bd565b6200089b565b620001b9620001fe366004620014d8565b6001602052600090815260409020546001600160a01b031681565b620001616200092f565b6200024962000234366004620015fb565b609954600160ff9092169190911b9081161490565b6040519015158152602001620001cd565b609954604051908152602001620001cd565b620001616200027d36600462001620565b620009fc565b620001b962000294366004620014d8565b62000a5a565b6200016162000dc1565b609854620001b9906001600160a01b031681565b6066546001600160a01b0316620001b9565b62000161620002db36600462001693565b62000dd9565b600054620001b9906001600160a01b031681565b6200016162000306366004620014d8565b62000f0f565b620001616200031d366004620014ff565b62000f8b565b620001616200033436600462001568565b620010f0565b620002496200034b366004620014d8565b60026020526000908152604090205460ff1681565b609860009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620003b4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003da9190620016ed565b6001600160a01b0316336001600160a01b031614620004165760405162461bcd60e51b81526004016200040d906200170d565b60405180910390fd5b62000421816200114a565b50565b60985460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156200046d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000493919062001757565b620004b25760405162461bcd60e51b81526004016200040d9062001777565b609954818116146200052d5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016200040d565b609981905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6200057562001243565b60008167ffffffffffffffff811115620005935762000593620017bf565b604051908082528060200260200182016040528015620005bd578160200160208202803683370190505b5090506000805b83811015620008075760026000868684818110620005e657620005e6620017d5565b9050602002016020810190620005fd9190620014d8565b6001600160a01b0316815260208101919091526040016000205460ff16156200069b5760405162461bcd60e51b815260206004820152604360248201527f5374726174656779466163746f72792e626c61636b6c697374546f6b656e733a60448201527f2043616e6e6f7420626c61636b6c697374206465706c6f79656420737472617460648201526265677960e81b608482015260a4016200040d565b600160026000878785818110620006b657620006b6620017d5565b9050602002016020810190620006cd9190620014d8565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f75519c51f39873ec0e27dd3bbc09549e4865a113f505393fb9eab5898f6418b38585838181106200072b576200072b620017d5565b9050602002016020810190620007429190620014d8565b6040516001600160a01b03909116815260200160405180910390a1600060016000878785818110620007785762000778620017d5565b90506020020160208101906200078f9190620014d8565b6001600160a01b0390811682526020820192909252604001600020541690508015620007f35780848481518110620007cb57620007cb620017d5565b6001600160a01b039092166020928302919091019091015282620007ef81620017eb565b9350505b50620007ff81620017eb565b9050620005c4565b50808252801562000895576040516316bb16b760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b5d8b5b890620008609085906004016200185b565b600060405180830381600087803b1580156200087b57600080fd5b505af115801562000890573d6000803e3d6000fd5b505050505b50505050565b620008a562001243565b604051634e5a426360e01b81526001600160a01b03838116600483015282151560248301527f00000000000000000000000000000000000000000000000000000000000000001690634e5a4263906044015b600060405180830381600087803b1580156200091257600080fd5b505af115801562000927573d6000803e3d6000fd5b505050505050565b60985460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa15801562000978573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200099e919062001757565b620009bd5760405162461bcd60e51b81526004016200040d9062001777565b600019609981905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b62000a0662001243565b60405163df5b354760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063df5b35479062000860908790879087908790600401620018b2565b60995460009081906001908116141562000ab75760405162461bcd60e51b815260206004820152601960248201527f5061757361626c653a20696e646578206973207061757365640000000000000060448201526064016200040d565b6001600160a01b03831660009081526002602052604090205460ff161562000b485760405162461bcd60e51b815260206004820152603760248201527f5374726174656779466163746f72792e6465706c6f794e65775374726174656760448201527f793a20546f6b656e20697320626c61636b6c697374656400000000000000000060648201526084016200040d565b6001600160a01b03838116600090815260016020526040902054161562000be65760405162461bcd60e51b8152602060048201526044602482018190527f5374726174656779466163746f72792e6465706c6f794e657753747261746567908201527f793a20537472617465677920616c72656164792065786973747320666f72207460648201526337b5b2b760e11b608482015260a4016200040d565b600080546098546040516001600160a01b038781166024830152918216604482015291169063485cc95560e01b9060640160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905162000c5690620014b4565b62000c6392919062001916565b604051809103906000f08015801562000c80573d6000803e3d6000fd5b50905062000c8f84826200129f565b604080516001808252818301909252600091602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337019050509050828260008151811062000ceb5762000ceb620017d5565b60200260200101906001600160a01b031690816001600160a01b03168152505060008160008151811062000d235762000d23620017d5565b9115156020928302919091019091015260405163df5b354760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063df5b35479062000d8390859085906004016200197e565b600060405180830381600087803b15801562000d9e57600080fd5b505af115801562000db3573d6000803e3d6000fd5b509498975050505050505050565b62000dcb62001243565b62000dd760006200130a565b565b603354610100900460ff161580801562000dfa5750603354600160ff909116105b8062000e165750303b15801562000e16575060335460ff166001145b62000e7b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016200040d565b6033805460ff19166001179055801562000e9f576033805461ff0019166101001790555b62000eaa856200130a565b62000eb684846200135c565b62000ec1826200144b565b801562000f08576033805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b62000f1962001243565b6001600160a01b03811662000f805760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016200040d565b62000421816200130a565b609860009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000fdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620010059190620016ed565b6001600160a01b0316336001600160a01b031614620010385760405162461bcd60e51b81526004016200040d906200170d565b609954198119609954191614620010b85760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016200040d565b609981905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200162000560565b620010fa62001243565b6040516316bb16b760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b5d8b5b890620008f79085908590600401620019db565b6001600160a01b038116620011da5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016200040d565b609854604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1609880546001600160a01b0319166001600160a01b0392909216919091179055565b6066546001600160a01b0316331462000dd75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200040d565b6001600160a01b0382811660008181526001602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527f6852a55230ef089d785bce7ffbf757985de34026df90a87d7b4a6e56f95d251f910160405180910390a15050565b606680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6098546001600160a01b03161580156200137e57506001600160a01b03821615155b620014025760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016200040d565b609981905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a262001447826200114a565b5050565b600054604080516001600160a01b03928316815291831660208301527fe21755962a7d7e100b59b9c3e4d4b54085b146313719955efb6a7a25c5c7feee910160405180910390a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b6108fa80620019fa83390190565b6001600160a01b03811681146200042157600080fd5b600060208284031215620014eb57600080fd5b8135620014f881620014c2565b9392505050565b6000602082840312156200151257600080fd5b5035919050565b60008083601f8401126200152c57600080fd5b50813567ffffffffffffffff8111156200154557600080fd5b6020830191508360208260051b85010111156200156157600080fd5b9250929050565b600080602083850312156200157c57600080fd5b823567ffffffffffffffff8111156200159457600080fd5b620015a28582860162001519565b90969095509350505050565b80151581146200042157600080fd5b60008060408385031215620015d157600080fd5b8235620015de81620014c2565b91506020830135620015f081620015ae565b809150509250929050565b6000602082840312156200160e57600080fd5b813560ff81168114620014f857600080fd5b600080600080604085870312156200163757600080fd5b843567ffffffffffffffff808211156200165057600080fd5b6200165e8883890162001519565b909650945060208701359150808211156200167857600080fd5b50620016878782880162001519565b95989497509550505050565b60008060008060808587031215620016aa57600080fd5b8435620016b781620014c2565b93506020850135620016c981620014c2565b9250604085013591506060850135620016e281620014c2565b939692955090935050565b6000602082840312156200170057600080fd5b8151620014f881620014c2565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b6000602082840312156200176a57600080fd5b8151620014f881620015ae565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006000198214156200180e57634e487b7160e01b600052601160045260246000fd5b5060010190565b600081518084526020808501945080840160005b83811015620018505781516001600160a01b03168752958201959082019060010162001829565b509495945050505050565b602081526000620014f8602083018462001815565b8183526000602080850194508260005b85811015620018505781356200189681620014c2565b6001600160a01b03168752958201959082019060010162001880565b604081526000620018c860408301868862001870565b8281036020848101919091528482528591810160005b8681101562001909578335620018f481620015ae565b151582529282019290820190600101620018de565b5098975050505050505050565b60018060a01b038316815260006020604081840152835180604085015260005b81811015620019545785810183015185820160600152820162001936565b8181111562001967576000606083870101525b50601f01601f191692909201606001949350505050565b60408152600062001993604083018562001815565b82810360208481019190915284518083528582019282019060005b81811015620019ce578451151583529383019391830191600101620019ae565b5090979650505050505050565b602081526000620019f160208301848662001870565b94935050505056fe60806040526040516108fa3803806108fa83398101604081905261002291610456565b61002e82826000610035565b5050610580565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610516565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610516565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108d3602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b60606001600160a01b0384163b6103495760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610169565b600080856001600160a01b0316856040516103649190610531565b600060405180830381855af49150503d806000811461039f576040519150601f19603f3d011682016040523d82523d6000602084013e6103a4565b606091505b5090925090506103b58282866103bf565b9695505050505050565b606083156103ce5750816102c8565b8251156103de5782518084602001fd5b8160405162461bcd60e51b8152600401610169919061054d565b80516001600160a01b038116811461040f57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044557818101518382015260200161042d565b838111156100f95750506000910152565b6000806040838503121561046957600080fd5b610472836103f8565b60208401519092506001600160401b038082111561048f57600080fd5b818501915085601f8301126104a357600080fd5b8151818111156104b5576104b5610414565b604051601f8201601f19908116603f011681019083821181831017156104dd576104dd610414565b816040528281528860208487010111156104f657600080fd5b61050783602083016020880161042a565b80955050505050509250929050565b60006020828403121561052857600080fd5b6102c8826103f8565b6000825161054381846020870161042a565b9190910192915050565b602081526000825180602084015261056c81604085016020870161042a565b601f01601f19169190910160400192915050565b6103448061058f6000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102e860279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb919061023f565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b60606001600160a01b0384163b6101915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084015b60405180910390fd5b600080856001600160a01b0316856040516101ac9190610298565b600060405180830381855af49150503d80600081146101e7576040519150601f19603f3d011682016040523d82523d6000602084013e6101ec565b606091505b50915091506101fc828286610206565b9695505050505050565b6060831561021557508161004e565b8251156102255782518084602001fd5b8160405162461bcd60e51b815260040161018891906102b4565b60006020828403121561025157600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028357818101518382015260200161026b565b83811115610292576000848401525b50505050565b600082516102aa818460208701610268565b9190910192915050565b60208152600082518060208401526102d3816040850160208701610268565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212206225174df4b558257f66ac9aa53b52c29cdd29a561b03eb6d75a95018aff3e5864736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212205ec4c51d66eda3a5cc6c4836684b038a334a62fe205ea7e8aaa91c0a44cd1bb364736f6c634300080c0033", } // StrategyFactoryABI is the input ABI used to generate the binding from. diff --git a/pkg/bindings/StrategyManager/binding.go b/pkg/bindings/StrategyManager/binding.go index abcb759e0..65ecc0fdd 100644 --- a/pkg/bindings/StrategyManager/binding.go +++ b/pkg/bindings/StrategyManager/binding.go @@ -32,7 +32,7 @@ var ( // StrategyManagerMetaData contains all meta data concerning the StrategyManager contract. var StrategyManagerMetaData = &bind.MetaData{ ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_delegation\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"},{\"name\":\"_eigenPodManager\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"},{\"name\":\"_slasher\",\"type\":\"address\",\"internalType\":\"contractISlasher\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"DEPOSIT_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DOMAIN_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addShares\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addStrategiesToDepositWhitelist\",\"inputs\":[{\"name\":\"strategiesToWhitelist\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"thirdPartyTransfersForbiddenValues\",\"type\":\"bool[]\",\"internalType\":\"bool[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"depositIntoStrategy\",\"inputs\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"depositIntoStrategyWithSignature\",\"inputs\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eigenPodManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPodManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getDeposits\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"initialStrategyWhitelister\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"initialPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"nonces\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"removeShares\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeStrategiesFromDepositWhitelist\",\"inputs\":[{\"name\":\"strategiesToRemoveFromWhitelist\",\"type\":\"address[]\",\"internalType\":\"contractIStrategy[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setStrategyWhitelister\",\"inputs\":[{\"name\":\"newStrategyWhitelister\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setThirdPartyTransfersForbidden\",\"inputs\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"value\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slasher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISlasher\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stakerStrategyList\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stakerStrategyListLength\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"stakerStrategyShares\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"strategyIsWhitelistedForDeposit\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"strategyWhitelister\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"thirdPartyTransfersForbidden\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSharesAsTokens\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Deposit\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"token\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIERC20\"},{\"name\":\"strategy\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIStrategy\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StrategyAddedToDepositWhitelist\",\"inputs\":[{\"name\":\"strategy\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIStrategy\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StrategyRemovedFromDepositWhitelist\",\"inputs\":[{\"name\":\"strategy\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIStrategy\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StrategyWhitelisterChanged\",\"inputs\":[{\"name\":\"previousAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"UpdatedThirdPartyTransfersForbidden\",\"inputs\":[{\"name\":\"strategy\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIStrategy\"},{\"name\":\"value\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false}]", - Bin: "0x6101006040523480156200001257600080fd5b506040516200338a3803806200338a833981016040819052620000359162000140565b6001600160a01b0380841660805280831660a052811660c0526200005862000065565b50504660e0525062000194565b600054610100900460ff1615620000d25760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000125576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b03811681146200013d57600080fd5b50565b6000806000606084860312156200015657600080fd5b8351620001638162000127565b6020850151909350620001768162000127565b6040850151909250620001898162000127565b809150509250925092565b60805160a05160c05160e0516131a0620001ea60003960006114bb0152600061046e0152600061028501526000818161051a01528181610b8401528181610ed101528181610f250152611a7101526131a06000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80638da5cb5b1161011a578063c6656702116100ad578063df5cf7231161007c578063df5cf72314610515578063e7a050aa1461053c578063f2fde38b1461054f578063f698da2514610562578063fabc1cbc1461056a57600080fd5b8063c6656702146104c9578063cbc2bd62146104dc578063cf756fdf146104ef578063df5b35471461050257600080fd5b8063b1344271116100e9578063b134427114610469578063b5d8b5b814610490578063c4623ea1146104a3578063c608c7f3146104b657600080fd5b80638da5cb5b1461040157806394f649dd14610412578063967fc0d2146104335780639b4da03d1461044657600080fd5b80635ac86ab71161019d5780637a7e0d921161016c5780637a7e0d92146103675780637ecebe0014610392578063886f1195146103b25780638b8aac3c146103c55780638c80d4e5146103ee57600080fd5b80635ac86ab7146103015780635c975abb14610334578063663c1de41461033c578063715018a61461035f57600080fd5b80634665bcda116101d95780634665bcda1461028057806348825e94146102bf5780634e5a4263146102e6578063595c6a67146102f957600080fd5b806310d67a2f1461020b578063136439dd1461022057806320606b701461023357806332e89ace1461026d575b600080fd5b61021e6102193660046129e8565b61057d565b005b61021e61022e366004612a05565b610639565b61025a7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6040519081526020015b60405180910390f35b61025a61027b366004612a34565b610778565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610264565b61025a7f4337f82d142e41f2a8c10547cd8c859bddb92262a61058e77842e24d9dea922481565b61021e6102f4366004612b3d565b610a66565b61021e610a9e565b61032461030f366004612b76565b609854600160ff9092169190911b9081161490565b6040519015158152602001610264565b60985461025a565b61032461034a3660046129e8565b60d16020526000908152604090205460ff1681565b61021e610b65565b61025a610375366004612b99565b60cd60209081526000928352604080842090915290825290205481565b61025a6103a03660046129e8565b60ca6020526000908152604090205481565b6097546102a7906001600160a01b031681565b61025a6103d33660046129e8565b6001600160a01b0316600090815260ce602052604090205490565b61021e6103fc366004612bc7565b610b79565b6033546001600160a01b03166102a7565b6104256104203660046129e8565b610bd2565b604051610264929190612c08565b60cb546102a7906001600160a01b031681565b6103246104543660046129e8565b60d36020526000908152604090205460ff1681565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b61021e61049e366004612cd1565b610d52565b61021e6104b1366004612d13565b610ec6565b61021e6104c4366004612d64565b610f1a565b61021e6104d73660046129e8565b610fd2565b6102a76104ea366004612db7565b610fe3565b61021e6104fd366004612d13565b61101b565b61021e610510366004612de3565b61114f565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b61025a61054a366004612bc7565b611378565b61021e61055d3660046129e8565b611441565b61025a6114b7565b61021e610578366004612a05565b6114f5565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f49190612e4f565b6001600160a01b0316336001600160a01b03161461062d5760405162461bcd60e51b815260040161062490612e6c565b60405180910390fd5b61063681611651565b50565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610681573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a59190612eb6565b6106c15760405162461bcd60e51b815260040161062490612ed3565b6098548181161461073a5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610624565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6098546000908190600190811614156107cf5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610624565b600260655414156108225760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610624565b60026065556001600160a01b038816600090815260d3602052604090205460ff16156108c95760405162461bcd60e51b815260206004820152604a60248201527f53747261746567794d616e616765722e6465706f736974496e746f537472617460448201527f656779576974685369676e61747572653a207468697264207472616e736665726064820152691cc8191a5cd8589b195960b21b608482015260a401610624565b4284101561094b5760405162461bcd60e51b815260206004820152604360248201527f53747261746567794d616e616765722e6465706f736974496e746f537472617460448201527f656779576974685369676e61747572653a207369676e617475726520657870696064820152621c995960ea1b608482015260a401610624565b6001600160a01b03858116600081815260ca602090815260408083205481517f4337f82d142e41f2a8c10547cd8c859bddb92262a61058e77842e24d9dea922493810193909352908201939093528b84166060820152928a16608084015260a0830189905260c0830182905260e0830187905290916101000160408051601f1981840301815291815281516020928301206001600160a01b038a16600090815260ca9093529082206001850190559150610a036114b7565b60405161190160f01b6020820152602281019190915260428101839052606201604051602081830303815290604052805190602001209050610a46888288611748565b610a52888c8c8c611907565b60016065559b9a5050505050505050505050565b60cb546001600160a01b03163314610a905760405162461bcd60e51b815260040161062490612f1b565b610a9a8282611ad6565b5050565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190612eb6565b610b265760405162461bcd60e51b815260040161062490612ed3565b600019609881905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b610b6d611b44565b610b776000611b9e565b565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610bc15760405162461bcd60e51b815260040161062490612f85565b610bcc838383611bf0565b50505050565b6001600160a01b038116600090815260ce60205260408120546060918291908167ffffffffffffffff811115610c0a57610c0a612a1e565b604051908082528060200260200182016040528015610c33578160200160208202803683370190505b50905060005b82811015610cc4576001600160a01b038616600090815260cd6020908152604080832060ce9092528220805491929184908110610c7857610c78612fe3565b60009182526020808320909101546001600160a01b031683528201929092526040019020548251839083908110610cb157610cb1612fe3565b6020908102919091010152600101610c39565b5060ce6000866001600160a01b03166001600160a01b031681526020019081526020016000208181805480602002602001604051908101604052809291908181526020018280548015610d4057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610d22575b50505050509150935093505050915091565b60cb546001600160a01b03163314610d7c5760405162461bcd60e51b815260040161062490612f1b565b8060005b81811015610bcc5760d16000858584818110610d9e57610d9e612fe3565b9050602002016020810190610db391906129e8565b6001600160a01b0316815260208101919091526040016000205460ff1615610ebe57600060d16000868685818110610ded57610ded612fe3565b9050602002016020810190610e0291906129e8565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f4074413b4b443e4e58019f2855a8765113358c7c72e39509c6af45fc0f5ba030848483818110610e5d57610e5d612fe3565b9050602002016020810190610e7291906129e8565b6040516001600160a01b03909116815260200160405180910390a1610ebe848483818110610ea257610ea2612fe3565b9050602002016020810190610eb791906129e8565b6000611ad6565b600101610d80565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610f0e5760405162461bcd60e51b815260040161062490612f85565b610bcc84848484611d4c565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610f625760405162461bcd60e51b815260040161062490612f85565b604051636ce5768960e11b81526001600160a01b03858116600483015282811660248301526044820184905284169063d9caed1290606401600060405180830381600087803b158015610fb457600080fd5b505af1158015610fc8573d6000803e3d6000fd5b5050505050505050565b610fda611b44565b61063681611fd9565b60ce6020528160005260406000208181548110610fff57600080fd5b6000918252602090912001546001600160a01b03169150829050565b600054610100900460ff161580801561103b5750600054600160ff909116105b806110555750303b158015611055575060005460ff166001145b6110b85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610624565b6000805460ff1916600117905580156110db576000805461ff0019166101001790555b6110e3612042565b60c9556110f083836120d9565b6110f985611b9e565b61110284611fd9565b8015611148576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60cb546001600160a01b031633146111795760405162461bcd60e51b815260040161062490612f1b565b8281146112025760405162461bcd60e51b815260206004820152604b60248201527f53747261746567794d616e616765722e61646453747261746567696573546f4460448201527f65706f73697457686974656c6973743a206172726179206c656e67746873206460648201526a0de40dcdee840dac2e8c6d60ab1b608482015260a401610624565b8260005b818110156113705760d1600087878481811061122457611224612fe3565b905060200201602081019061123991906129e8565b6001600160a01b0316815260208101919091526040016000205460ff1661136857600160d1600088888581811061127257611272612fe3565b905060200201602081019061128791906129e8565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f0c35b17d91c96eb2751cd456e1252f42a386e524ef9ff26ecc9950859fdc04fe8686838181106112e2576112e2612fe3565b90506020020160208101906112f791906129e8565b6040516001600160a01b03909116815260200160405180910390a161136886868381811061132757611327612fe3565b905060200201602081019061133c91906129e8565b85858481811061134e5761134e612fe3565b90506020020160208101906113639190612ff9565b611ad6565b600101611206565b505050505050565b6098546000908190600190811614156113cf5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610624565b600260655414156114225760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610624565b600260655561143333868686611907565b600160655595945050505050565b611449611b44565b6001600160a01b0381166114ae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610624565b61063681611b9e565b60007f00000000000000000000000000000000000000000000000000000000000000004614156114e8575060c95490565b6114f0612042565b905090565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611548573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156c9190612e4f565b6001600160a01b0316336001600160a01b03161461159c5760405162461bcd60e51b815260040161062490612e6c565b60985419811960985419161461161a5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610624565b609881905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161076d565b6001600160a01b0381166116df5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610624565b609754604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1609780546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0383163b1561186757604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e90611788908690869060040161306e565b602060405180830381865afa1580156117a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c99190613087565b6001600160e01b031916146118625760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a401610624565b505050565b826001600160a01b031661187b83836121bf565b6001600160a01b0316146118625760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a401610624565b6001600160a01b038316600090815260d16020526040812054849060ff166119ad5760405162461bcd60e51b815260206004820152604d60248201527f53747261746567794d616e616765722e6f6e6c7953747261746567696573576860448201527f6974656c6973746564466f724465706f7369743a207374726174656779206e6f60648201526c1d081dda1a5d195b1a5cdd1959609a1b608482015260a401610624565b6119c26001600160a01b0385163387866121e3565b6040516311f9fbc960e21b81526001600160a01b038581166004830152602482018590528616906347e7ef24906044016020604051808303816000875af1158015611a11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3591906130b1565b9150611a4386858785611d4c565b604051631452b9d760e11b81526001600160a01b0387811660048301528681166024830152604482018490527f000000000000000000000000000000000000000000000000000000000000000016906328a573ae90606401600060405180830381600087803b158015611ab557600080fd5b505af1158015611ac9573d6000803e3d6000fd5b5050505050949350505050565b604080516001600160a01b038416815282151560208201527f77d930df4937793473a95024d87a98fd2ccb9e92d3c2463b3dacd65d3e6a5786910160405180910390a16001600160a01b0391909116600090815260d360205260409020805460ff1916911515919091179055565b6033546001600160a01b03163314610b775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610624565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081611c655760405162461bcd60e51b815260206004820152603e60248201527f53747261746567794d616e616765722e5f72656d6f76655368617265733a207360448201527f68617265416d6f756e742073686f756c64206e6f74206265207a65726f2100006064820152608401610624565b6001600160a01b03808516600090815260cd602090815260408083209387168352929052205480831115611cf75760405162461bcd60e51b815260206004820152603360248201527f53747261746567794d616e616765722e5f72656d6f76655368617265733a20736044820152720d0c2e4ca82dadeeadce840e8dede40d0d2ced606b1b6064820152608401610624565b6001600160a01b03808616600090815260cd602090815260408083209388168352929052208382039081905590831415611d3f57611d35858561223d565b6001915050611d45565b60009150505b9392505050565b6001600160a01b038416611dc85760405162461bcd60e51b815260206004820152603960248201527f53747261746567794d616e616765722e5f6164645368617265733a207374616b60448201527f65722063616e6e6f74206265207a65726f2061646472657373000000000000006064820152608401610624565b80611e345760405162461bcd60e51b815260206004820152603660248201527f53747261746567794d616e616765722e5f6164645368617265733a207368617260448201527565732073686f756c64206e6f74206265207a65726f2160501b6064820152608401610624565b6001600160a01b03808516600090815260cd6020908152604080832093861683529290522054611f45576001600160a01b038416600090815260ce602090815260409091205410611f065760405162461bcd60e51b815260206004820152605060248201527f53747261746567794d616e616765722e5f6164645368617265733a206465706f60448201527f73697420776f756c6420657863656564204d41585f5354414b45525f5354524160648201526f0a88a8eb2be9892a6a8be988a9c8ea8960831b608482015260a401610624565b6001600160a01b03848116600090815260ce602090815260408220805460018101825590835291200180546001600160a01b0319169184169190911790555b6001600160a01b03808516600090815260cd6020908152604080832093861683529290529081208054839290611f7c9084906130e0565b9091555050604080516001600160a01b03868116825285811660208301528416818301526060810183905290517f7cfff908a4b583f36430b25d75964c458d8ede8a99bd61be750e97ee1b2f3a969181900360800190a150505050565b60cb54604080516001600160a01b03928316815291831660208301527f4264275e593955ff9d6146a51a4525f6ddace2e81db9391abcc9d1ca48047d29910160405180910390a160cb80546001600160a01b0319166001600160a01b0392909216919091179055565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b6097546001600160a01b03161580156120fa57506001600160a01b03821615155b61217c5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610624565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2610a9a82611651565b60008060006121ce858561242f565b915091506121db8161249f565b509392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610bcc90859061265a565b6001600160a01b038216600090815260ce6020526040812054905b81811015612358576001600160a01b03848116600090815260ce602052604090208054918516918390811061228f5761228f612fe3565b6000918252602090912001546001600160a01b03161415612350576001600160a01b038416600090815260ce6020526040902080546122d0906001906130f8565b815481106122e0576122e0612fe3565b60009182526020808320909101546001600160a01b03878116845260ce909252604090922080549190921691908390811061231d5761231d612fe3565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550612358565b600101612258565b818114156123e05760405162461bcd60e51b815260206004820152604960248201527f53747261746567794d616e616765722e5f72656d6f766553747261746567794660448201527f726f6d5374616b657253747261746567794c6973743a207374726174656779206064820152681b9bdd08199bdd5b9960ba1b608482015260a401610624565b6001600160a01b038416600090815260ce602052604090208054806124075761240761310f565b600082815260209020810160001990810180546001600160a01b031916905501905550505050565b6000808251604114156124665760208301516040840151606085015160001a61245a8782858561272c565b94509450505050612498565b8251604014156124905760208301516040840151612485868383612819565b935093505050612498565b506000905060025b9250929050565b60008160048111156124b3576124b3613125565b14156124bc5750565b60018160048111156124d0576124d0613125565b141561251e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610624565b600281600481111561253257612532613125565b14156125805760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610624565b600381600481111561259457612594613125565b14156125ed5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610624565b600481600481111561260157612601613125565b14156106365760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610624565b60006126af826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166128529092919063ffffffff16565b80519091501561186257808060200190518101906126cd9190612eb6565b6118625760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610624565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156127635750600090506003612810565b8460ff16601b1415801561277b57508460ff16601c14155b1561278c5750600090506004612810565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156127e0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661280957600060019250925050612810565b9150600090505b94509492505050565b6000806001600160ff1b0383168161283660ff86901c601b6130e0565b90506128448782888561272c565b935093505050935093915050565b60606128618484600085612869565b949350505050565b6060824710156128ca5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610624565b6001600160a01b0385163b6129215760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610624565b600080866001600160a01b0316858760405161293d919061313b565b60006040518083038185875af1925050503d806000811461297a576040519150601f19603f3d011682016040523d82523d6000602084013e61297f565b606091505b509150915061298f82828661299a565b979650505050505050565b606083156129a9575081611d45565b8251156129b95782518084602001fd5b8160405162461bcd60e51b81526004016106249190613157565b6001600160a01b038116811461063657600080fd5b6000602082840312156129fa57600080fd5b8135611d45816129d3565b600060208284031215612a1757600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c08789031215612a4d57600080fd5b8635612a58816129d3565b95506020870135612a68816129d3565b9450604087013593506060870135612a7f816129d3565b92506080870135915060a087013567ffffffffffffffff80821115612aa357600080fd5b818901915089601f830112612ab757600080fd5b813581811115612ac957612ac9612a1e565b604051601f8201601f19908116603f01168101908382118183101715612af157612af1612a1e565b816040528281528c6020848701011115612b0a57600080fd5b8260208601602083013760006020848301015280955050505050509295509295509295565b801515811461063657600080fd5b60008060408385031215612b5057600080fd5b8235612b5b816129d3565b91506020830135612b6b81612b2f565b809150509250929050565b600060208284031215612b8857600080fd5b813560ff81168114611d4557600080fd5b60008060408385031215612bac57600080fd5b8235612bb7816129d3565b91506020830135612b6b816129d3565b600080600060608486031215612bdc57600080fd5b8335612be7816129d3565b92506020840135612bf7816129d3565b929592945050506040919091013590565b604080825283519082018190526000906020906060840190828701845b82811015612c4a5781516001600160a01b031684529284019290840190600101612c25565b5050508381038285015284518082528583019183019060005b81811015612c7f57835183529284019291840191600101612c63565b5090979650505050505050565b60008083601f840112612c9e57600080fd5b50813567ffffffffffffffff811115612cb657600080fd5b6020830191508360208260051b850101111561249857600080fd5b60008060208385031215612ce457600080fd5b823567ffffffffffffffff811115612cfb57600080fd5b612d0785828601612c8c565b90969095509350505050565b60008060008060808587031215612d2957600080fd5b8435612d34816129d3565b93506020850135612d44816129d3565b92506040850135612d54816129d3565b9396929550929360600135925050565b60008060008060808587031215612d7a57600080fd5b8435612d85816129d3565b93506020850135612d95816129d3565b9250604085013591506060850135612dac816129d3565b939692955090935050565b60008060408385031215612dca57600080fd5b8235612dd5816129d3565b946020939093013593505050565b60008060008060408587031215612df957600080fd5b843567ffffffffffffffff80821115612e1157600080fd5b612e1d88838901612c8c565b90965094506020870135915080821115612e3657600080fd5b50612e4387828801612c8c565b95989497509550505050565b600060208284031215612e6157600080fd5b8151611d45816129d3565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215612ec857600080fd5b8151611d4581612b2f565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b60208082526044908201527f53747261746567794d616e616765722e6f6e6c7953747261746567795768697460408201527f656c69737465723a206e6f742074686520737472617465677957686974656c6960608201526339ba32b960e11b608082015260a00190565b602080825260409082018190527f53747261746567794d616e616765722e6f6e6c7944656c65676174696f6e4d61908201527f6e616765723a206e6f74207468652044656c65676174696f6e4d616e61676572606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561300b57600080fd5b8135611d4581612b2f565b60005b83811015613031578181015183820152602001613019565b83811115610bcc5750506000910152565b6000815180845261305a816020860160208601613016565b601f01601f19169290920160200192915050565b8281526040602082015260006128616040830184613042565b60006020828403121561309957600080fd5b81516001600160e01b031981168114611d4557600080fd5b6000602082840312156130c357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082198211156130f3576130f36130ca565b500190565b60008282101561310a5761310a6130ca565b500390565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b6000825161314d818460208701613016565b9190910192915050565b602081526000611d45602083018461304256fea26469706673582212203e2db651a846bc3ed5aa43529cb263a5d72b401f60f7beca6bee14b366337d9664736f6c634300080c0033", + Bin: "0x6101006040523480156200001257600080fd5b506040516200338a3803806200338a833981016040819052620000359162000140565b6001600160a01b0380841660805280831660a052811660c0526200005862000065565b50504660e0525062000194565b600054610100900460ff1615620000d25760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000125576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b03811681146200013d57600080fd5b50565b6000806000606084860312156200015657600080fd5b8351620001638162000127565b6020850151909350620001768162000127565b6040850151909250620001898162000127565b809150509250925092565b60805160a05160c05160e0516131a0620001ea60003960006114bb0152600061046e0152600061028501526000818161051a01528181610b8401528181610ed101528181610f250152611a7101526131a06000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80638da5cb5b1161011a578063c6656702116100ad578063df5cf7231161007c578063df5cf72314610515578063e7a050aa1461053c578063f2fde38b1461054f578063f698da2514610562578063fabc1cbc1461056a57600080fd5b8063c6656702146104c9578063cbc2bd62146104dc578063cf756fdf146104ef578063df5b35471461050257600080fd5b8063b1344271116100e9578063b134427114610469578063b5d8b5b814610490578063c4623ea1146104a3578063c608c7f3146104b657600080fd5b80638da5cb5b1461040157806394f649dd14610412578063967fc0d2146104335780639b4da03d1461044657600080fd5b80635ac86ab71161019d5780637a7e0d921161016c5780637a7e0d92146103675780637ecebe0014610392578063886f1195146103b25780638b8aac3c146103c55780638c80d4e5146103ee57600080fd5b80635ac86ab7146103015780635c975abb14610334578063663c1de41461033c578063715018a61461035f57600080fd5b80634665bcda116101d95780634665bcda1461028057806348825e94146102bf5780634e5a4263146102e6578063595c6a67146102f957600080fd5b806310d67a2f1461020b578063136439dd1461022057806320606b701461023357806332e89ace1461026d575b600080fd5b61021e6102193660046129e8565b61057d565b005b61021e61022e366004612a05565b610639565b61025a7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6040519081526020015b60405180910390f35b61025a61027b366004612a34565b610778565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610264565b61025a7f4337f82d142e41f2a8c10547cd8c859bddb92262a61058e77842e24d9dea922481565b61021e6102f4366004612b3d565b610a66565b61021e610a9e565b61032461030f366004612b76565b609854600160ff9092169190911b9081161490565b6040519015158152602001610264565b60985461025a565b61032461034a3660046129e8565b60d16020526000908152604090205460ff1681565b61021e610b65565b61025a610375366004612b99565b60cd60209081526000928352604080842090915290825290205481565b61025a6103a03660046129e8565b60ca6020526000908152604090205481565b6097546102a7906001600160a01b031681565b61025a6103d33660046129e8565b6001600160a01b0316600090815260ce602052604090205490565b61021e6103fc366004612bc7565b610b79565b6033546001600160a01b03166102a7565b6104256104203660046129e8565b610bd2565b604051610264929190612c08565b60cb546102a7906001600160a01b031681565b6103246104543660046129e8565b60d36020526000908152604090205460ff1681565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b61021e61049e366004612cd1565b610d52565b61021e6104b1366004612d13565b610ec6565b61021e6104c4366004612d64565b610f1a565b61021e6104d73660046129e8565b610fd2565b6102a76104ea366004612db7565b610fe3565b61021e6104fd366004612d13565b61101b565b61021e610510366004612de3565b61114f565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b61025a61054a366004612bc7565b611378565b61021e61055d3660046129e8565b611441565b61025a6114b7565b61021e610578366004612a05565b6114f5565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f49190612e4f565b6001600160a01b0316336001600160a01b03161461062d5760405162461bcd60e51b815260040161062490612e6c565b60405180910390fd5b61063681611651565b50565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610681573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a59190612eb6565b6106c15760405162461bcd60e51b815260040161062490612ed3565b6098548181161461073a5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610624565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6098546000908190600190811614156107cf5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610624565b600260655414156108225760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610624565b60026065556001600160a01b038816600090815260d3602052604090205460ff16156108c95760405162461bcd60e51b815260206004820152604a60248201527f53747261746567794d616e616765722e6465706f736974496e746f537472617460448201527f656779576974685369676e61747572653a207468697264207472616e736665726064820152691cc8191a5cd8589b195960b21b608482015260a401610624565b4284101561094b5760405162461bcd60e51b815260206004820152604360248201527f53747261746567794d616e616765722e6465706f736974496e746f537472617460448201527f656779576974685369676e61747572653a207369676e617475726520657870696064820152621c995960ea1b608482015260a401610624565b6001600160a01b03858116600081815260ca602090815260408083205481517f4337f82d142e41f2a8c10547cd8c859bddb92262a61058e77842e24d9dea922493810193909352908201939093528b84166060820152928a16608084015260a0830189905260c0830182905260e0830187905290916101000160408051601f1981840301815291815281516020928301206001600160a01b038a16600090815260ca9093529082206001850190559150610a036114b7565b60405161190160f01b6020820152602281019190915260428101839052606201604051602081830303815290604052805190602001209050610a46888288611748565b610a52888c8c8c611907565b60016065559b9a5050505050505050505050565b60cb546001600160a01b03163314610a905760405162461bcd60e51b815260040161062490612f1b565b610a9a8282611ad6565b5050565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190612eb6565b610b265760405162461bcd60e51b815260040161062490612ed3565b600019609881905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b610b6d611b44565b610b776000611b9e565b565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610bc15760405162461bcd60e51b815260040161062490612f85565b610bcc838383611bf0565b50505050565b6001600160a01b038116600090815260ce60205260408120546060918291908167ffffffffffffffff811115610c0a57610c0a612a1e565b604051908082528060200260200182016040528015610c33578160200160208202803683370190505b50905060005b82811015610cc4576001600160a01b038616600090815260cd6020908152604080832060ce9092528220805491929184908110610c7857610c78612fe3565b60009182526020808320909101546001600160a01b031683528201929092526040019020548251839083908110610cb157610cb1612fe3565b6020908102919091010152600101610c39565b5060ce6000866001600160a01b03166001600160a01b031681526020019081526020016000208181805480602002602001604051908101604052809291908181526020018280548015610d4057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610d22575b50505050509150935093505050915091565b60cb546001600160a01b03163314610d7c5760405162461bcd60e51b815260040161062490612f1b565b8060005b81811015610bcc5760d16000858584818110610d9e57610d9e612fe3565b9050602002016020810190610db391906129e8565b6001600160a01b0316815260208101919091526040016000205460ff1615610ebe57600060d16000868685818110610ded57610ded612fe3565b9050602002016020810190610e0291906129e8565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f4074413b4b443e4e58019f2855a8765113358c7c72e39509c6af45fc0f5ba030848483818110610e5d57610e5d612fe3565b9050602002016020810190610e7291906129e8565b6040516001600160a01b03909116815260200160405180910390a1610ebe848483818110610ea257610ea2612fe3565b9050602002016020810190610eb791906129e8565b6000611ad6565b600101610d80565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610f0e5760405162461bcd60e51b815260040161062490612f85565b610bcc84848484611d4c565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610f625760405162461bcd60e51b815260040161062490612f85565b604051636ce5768960e11b81526001600160a01b03858116600483015282811660248301526044820184905284169063d9caed1290606401600060405180830381600087803b158015610fb457600080fd5b505af1158015610fc8573d6000803e3d6000fd5b5050505050505050565b610fda611b44565b61063681611fd9565b60ce6020528160005260406000208181548110610fff57600080fd5b6000918252602090912001546001600160a01b03169150829050565b600054610100900460ff161580801561103b5750600054600160ff909116105b806110555750303b158015611055575060005460ff166001145b6110b85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610624565b6000805460ff1916600117905580156110db576000805461ff0019166101001790555b6110e3612042565b60c9556110f083836120d9565b6110f985611b9e565b61110284611fd9565b8015611148576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60cb546001600160a01b031633146111795760405162461bcd60e51b815260040161062490612f1b565b8281146112025760405162461bcd60e51b815260206004820152604b60248201527f53747261746567794d616e616765722e61646453747261746567696573546f4460448201527f65706f73697457686974656c6973743a206172726179206c656e67746873206460648201526a0de40dcdee840dac2e8c6d60ab1b608482015260a401610624565b8260005b818110156113705760d1600087878481811061122457611224612fe3565b905060200201602081019061123991906129e8565b6001600160a01b0316815260208101919091526040016000205460ff1661136857600160d1600088888581811061127257611272612fe3565b905060200201602081019061128791906129e8565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f0c35b17d91c96eb2751cd456e1252f42a386e524ef9ff26ecc9950859fdc04fe8686838181106112e2576112e2612fe3565b90506020020160208101906112f791906129e8565b6040516001600160a01b03909116815260200160405180910390a161136886868381811061132757611327612fe3565b905060200201602081019061133c91906129e8565b85858481811061134e5761134e612fe3565b90506020020160208101906113639190612ff9565b611ad6565b600101611206565b505050505050565b6098546000908190600190811614156113cf5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610624565b600260655414156114225760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610624565b600260655561143333868686611907565b600160655595945050505050565b611449611b44565b6001600160a01b0381166114ae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610624565b61063681611b9e565b60007f00000000000000000000000000000000000000000000000000000000000000004614156114e8575060c95490565b6114f0612042565b905090565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611548573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156c9190612e4f565b6001600160a01b0316336001600160a01b03161461159c5760405162461bcd60e51b815260040161062490612e6c565b60985419811960985419161461161a5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610624565b609881905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161076d565b6001600160a01b0381166116df5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610624565b609754604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1609780546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0383163b1561186757604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e90611788908690869060040161306e565b602060405180830381865afa1580156117a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c99190613087565b6001600160e01b031916146118625760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a401610624565b505050565b826001600160a01b031661187b83836121bf565b6001600160a01b0316146118625760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a401610624565b6001600160a01b038316600090815260d16020526040812054849060ff166119ad5760405162461bcd60e51b815260206004820152604d60248201527f53747261746567794d616e616765722e6f6e6c7953747261746567696573576860448201527f6974656c6973746564466f724465706f7369743a207374726174656779206e6f60648201526c1d081dda1a5d195b1a5cdd1959609a1b608482015260a401610624565b6119c26001600160a01b0385163387866121e3565b6040516311f9fbc960e21b81526001600160a01b038581166004830152602482018590528616906347e7ef24906044016020604051808303816000875af1158015611a11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3591906130b1565b9150611a4386858785611d4c565b604051631452b9d760e11b81526001600160a01b0387811660048301528681166024830152604482018490527f000000000000000000000000000000000000000000000000000000000000000016906328a573ae90606401600060405180830381600087803b158015611ab557600080fd5b505af1158015611ac9573d6000803e3d6000fd5b5050505050949350505050565b604080516001600160a01b038416815282151560208201527f77d930df4937793473a95024d87a98fd2ccb9e92d3c2463b3dacd65d3e6a5786910160405180910390a16001600160a01b0391909116600090815260d360205260409020805460ff1916911515919091179055565b6033546001600160a01b03163314610b775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610624565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081611c655760405162461bcd60e51b815260206004820152603e60248201527f53747261746567794d616e616765722e5f72656d6f76655368617265733a207360448201527f68617265416d6f756e742073686f756c64206e6f74206265207a65726f2100006064820152608401610624565b6001600160a01b03808516600090815260cd602090815260408083209387168352929052205480831115611cf75760405162461bcd60e51b815260206004820152603360248201527f53747261746567794d616e616765722e5f72656d6f76655368617265733a20736044820152720d0c2e4ca82dadeeadce840e8dede40d0d2ced606b1b6064820152608401610624565b6001600160a01b03808616600090815260cd602090815260408083209388168352929052208382039081905590831415611d3f57611d35858561223d565b6001915050611d45565b60009150505b9392505050565b6001600160a01b038416611dc85760405162461bcd60e51b815260206004820152603960248201527f53747261746567794d616e616765722e5f6164645368617265733a207374616b60448201527f65722063616e6e6f74206265207a65726f2061646472657373000000000000006064820152608401610624565b80611e345760405162461bcd60e51b815260206004820152603660248201527f53747261746567794d616e616765722e5f6164645368617265733a207368617260448201527565732073686f756c64206e6f74206265207a65726f2160501b6064820152608401610624565b6001600160a01b03808516600090815260cd6020908152604080832093861683529290522054611f45576001600160a01b038416600090815260ce602090815260409091205410611f065760405162461bcd60e51b815260206004820152605060248201527f53747261746567794d616e616765722e5f6164645368617265733a206465706f60448201527f73697420776f756c6420657863656564204d41585f5354414b45525f5354524160648201526f0a88a8eb2be9892a6a8be988a9c8ea8960831b608482015260a401610624565b6001600160a01b03848116600090815260ce602090815260408220805460018101825590835291200180546001600160a01b0319169184169190911790555b6001600160a01b03808516600090815260cd6020908152604080832093861683529290529081208054839290611f7c9084906130e0565b9091555050604080516001600160a01b03868116825285811660208301528416818301526060810183905290517f7cfff908a4b583f36430b25d75964c458d8ede8a99bd61be750e97ee1b2f3a969181900360800190a150505050565b60cb54604080516001600160a01b03928316815291831660208301527f4264275e593955ff9d6146a51a4525f6ddace2e81db9391abcc9d1ca48047d29910160405180910390a160cb80546001600160a01b0319166001600160a01b0392909216919091179055565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b6097546001600160a01b03161580156120fa57506001600160a01b03821615155b61217c5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610624565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2610a9a82611651565b60008060006121ce858561242f565b915091506121db8161249f565b509392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610bcc90859061265a565b6001600160a01b038216600090815260ce6020526040812054905b81811015612358576001600160a01b03848116600090815260ce602052604090208054918516918390811061228f5761228f612fe3565b6000918252602090912001546001600160a01b03161415612350576001600160a01b038416600090815260ce6020526040902080546122d0906001906130f8565b815481106122e0576122e0612fe3565b60009182526020808320909101546001600160a01b03878116845260ce909252604090922080549190921691908390811061231d5761231d612fe3565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550612358565b600101612258565b818114156123e05760405162461bcd60e51b815260206004820152604960248201527f53747261746567794d616e616765722e5f72656d6f766553747261746567794660448201527f726f6d5374616b657253747261746567794c6973743a207374726174656779206064820152681b9bdd08199bdd5b9960ba1b608482015260a401610624565b6001600160a01b038416600090815260ce602052604090208054806124075761240761310f565b600082815260209020810160001990810180546001600160a01b031916905501905550505050565b6000808251604114156124665760208301516040840151606085015160001a61245a8782858561272c565b94509450505050612498565b8251604014156124905760208301516040840151612485868383612819565b935093505050612498565b506000905060025b9250929050565b60008160048111156124b3576124b3613125565b14156124bc5750565b60018160048111156124d0576124d0613125565b141561251e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610624565b600281600481111561253257612532613125565b14156125805760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610624565b600381600481111561259457612594613125565b14156125ed5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610624565b600481600481111561260157612601613125565b14156106365760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610624565b60006126af826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166128529092919063ffffffff16565b80519091501561186257808060200190518101906126cd9190612eb6565b6118625760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610624565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156127635750600090506003612810565b8460ff16601b1415801561277b57508460ff16601c14155b1561278c5750600090506004612810565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156127e0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661280957600060019250925050612810565b9150600090505b94509492505050565b6000806001600160ff1b0383168161283660ff86901c601b6130e0565b90506128448782888561272c565b935093505050935093915050565b60606128618484600085612869565b949350505050565b6060824710156128ca5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610624565b6001600160a01b0385163b6129215760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610624565b600080866001600160a01b0316858760405161293d919061313b565b60006040518083038185875af1925050503d806000811461297a576040519150601f19603f3d011682016040523d82523d6000602084013e61297f565b606091505b509150915061298f82828661299a565b979650505050505050565b606083156129a9575081611d45565b8251156129b95782518084602001fd5b8160405162461bcd60e51b81526004016106249190613157565b6001600160a01b038116811461063657600080fd5b6000602082840312156129fa57600080fd5b8135611d45816129d3565b600060208284031215612a1757600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c08789031215612a4d57600080fd5b8635612a58816129d3565b95506020870135612a68816129d3565b9450604087013593506060870135612a7f816129d3565b92506080870135915060a087013567ffffffffffffffff80821115612aa357600080fd5b818901915089601f830112612ab757600080fd5b813581811115612ac957612ac9612a1e565b604051601f8201601f19908116603f01168101908382118183101715612af157612af1612a1e565b816040528281528c6020848701011115612b0a57600080fd5b8260208601602083013760006020848301015280955050505050509295509295509295565b801515811461063657600080fd5b60008060408385031215612b5057600080fd5b8235612b5b816129d3565b91506020830135612b6b81612b2f565b809150509250929050565b600060208284031215612b8857600080fd5b813560ff81168114611d4557600080fd5b60008060408385031215612bac57600080fd5b8235612bb7816129d3565b91506020830135612b6b816129d3565b600080600060608486031215612bdc57600080fd5b8335612be7816129d3565b92506020840135612bf7816129d3565b929592945050506040919091013590565b604080825283519082018190526000906020906060840190828701845b82811015612c4a5781516001600160a01b031684529284019290840190600101612c25565b5050508381038285015284518082528583019183019060005b81811015612c7f57835183529284019291840191600101612c63565b5090979650505050505050565b60008083601f840112612c9e57600080fd5b50813567ffffffffffffffff811115612cb657600080fd5b6020830191508360208260051b850101111561249857600080fd5b60008060208385031215612ce457600080fd5b823567ffffffffffffffff811115612cfb57600080fd5b612d0785828601612c8c565b90969095509350505050565b60008060008060808587031215612d2957600080fd5b8435612d34816129d3565b93506020850135612d44816129d3565b92506040850135612d54816129d3565b9396929550929360600135925050565b60008060008060808587031215612d7a57600080fd5b8435612d85816129d3565b93506020850135612d95816129d3565b9250604085013591506060850135612dac816129d3565b939692955090935050565b60008060408385031215612dca57600080fd5b8235612dd5816129d3565b946020939093013593505050565b60008060008060408587031215612df957600080fd5b843567ffffffffffffffff80821115612e1157600080fd5b612e1d88838901612c8c565b90965094506020870135915080821115612e3657600080fd5b50612e4387828801612c8c565b95989497509550505050565b600060208284031215612e6157600080fd5b8151611d45816129d3565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215612ec857600080fd5b8151611d4581612b2f565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b60208082526044908201527f53747261746567794d616e616765722e6f6e6c7953747261746567795768697460408201527f656c69737465723a206e6f742074686520737472617465677957686974656c6960608201526339ba32b960e11b608082015260a00190565b602080825260409082018190527f53747261746567794d616e616765722e6f6e6c7944656c65676174696f6e4d61908201527f6e616765723a206e6f74207468652044656c65676174696f6e4d616e61676572606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561300b57600080fd5b8135611d4581612b2f565b60005b83811015613031578181015183820152602001613019565b83811115610bcc5750506000910152565b6000815180845261305a816020860160208601613016565b601f01601f19169290920160200192915050565b8281526040602082015260006128616040830184613042565b60006020828403121561309957600080fd5b81516001600160e01b031981168114611d4557600080fd5b6000602082840312156130c357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082198211156130f3576130f36130ca565b500190565b60008282101561310a5761310a6130ca565b500390565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b6000825161314d818460208701613016565b9190910192915050565b602081526000611d45602083018461304256fea2646970667358221220e1eb2321685fb63a9aec2a407059955dbb014f9ba1598fed273d59a1889501d764736f6c634300080c0033", } // StrategyManagerABI is the input ABI used to generate the binding from. diff --git a/script/configs/goerli/M1_deploy_goerli.config.json b/script/configs/goerli/M1_deploy_goerli.config.json deleted file mode 100644 index c454fa4db..000000000 --- a/script/configs/goerli/M1_deploy_goerli.config.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "multisig_addresses": { - "pauserMultisig": "0x040353E9d057689b77DF275c07FFe1A46b98a4a6", - "communityMultisig": "0x37bAFb55BC02056c5fD891DFa503ee84a97d89bF", - "operationsMultisig": "0x040353E9d057689b77DF275c07FFe1A46b98a4a6", - "executorMultisig": "0x3d9C2c2B40d890ad53E27947402e977155CD2808", - "timelock": "0xA7e72a0564ebf25Fa082Fc27020225edeAF1796E" - }, - "strategies": [ - { - "token_address": "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", - "token_name": "Wrapped Ether", - "token_symbol": "WETH" - }, - { - "token_address": "0x6320cd32aa674d2898a68ec82e869385fc5f7e2f", - "token_name": "Wrapped liquid staked Ether 2.0", - "token_symbol": "wstETH" - }, - { - "token_address": "0x178e141a0e3b34152f73ff610437a7bf9b83267a", - "token_name": "Rocket Pool ETH", - "token_symbol": "rETH" - }, - { - "token_address": "0x", - "token_name": "Test Staked Ether", - "token_symbol": "tsETH" - } - ], - "strategyManager": { - "init_paused_status": 0, - "init_withdrawal_delay_blocks": 10 - }, - "eigenPod": { - "PARTIAL_WITHDRAWAL_FRAUD_PROOF_PERIOD_BLOCKS": 50400, - "REQUIRED_BALANCE_WEI": "31000000000000000000" - }, - "eigenPodManager": { - "init_paused_status": 30 - }, - "delayedWithdrawalRouter": { - "init_paused_status": 0, - "init_withdrawal_delay_blocks": 10 - }, - "slasher": { - "init_paused_status": "115792089237316195423570985008687907853269984665640564039457584007913129639935" - }, - "delegation": { - "init_paused_status": "115792089237316195423570985008687907853269984665640564039457584007913129639935" - }, - "ethPOSDepositAddress": "0xff50ed3d0ec03ac01d4c79aad74928bff48a7b2b" -} - diff --git a/script/configs/holesky/Holesky_current_deployment.config.json b/script/configs/holesky/eigenlayer_addresses.config.json similarity index 79% rename from script/configs/holesky/Holesky_current_deployment.config.json rename to script/configs/holesky/eigenlayer_addresses.config.json index 4b7649a42..84948803b 100644 --- a/script/configs/holesky/Holesky_current_deployment.config.json +++ b/script/configs/holesky/eigenlayer_addresses.config.json @@ -11,34 +11,38 @@ "eigenLayerPauserReg": "0x85Ef7299F8311B25642679edBF02B62FA2212F06", "eigenLayerProxyAdmin": "0xDB023566064246399b4AE851197a97729C93A6cf", "eigenPodBeacon": "0x7261C2bd75a7ACE1762f6d7FAe8F63215581832D", - "eigenPodImplementation": "0xe98f9298344527608A1BCC23907B8145F9Cb641c", + "eigenPodImplementation": "0x10ad7e30e3F52076C8462D573530f4461377319c", "eigenPodManager": "0x30770d7E3e71112d7A6b7259542D1f680a70e315", - "eigenPodManagerImplementation": "0x5265C162f7d5F3fE3175a78828ab16bf5E324a7B", + "eigenPodManagerImplementation": "0x91A6525a4a843F5a5B633905300c33F79413CCc5", "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", - "rewardsCoordinator": "0x0000000000000000000000000000000000000000", - "rewardsCoordinatorImplementation": "0x0000000000000000000000000000000000000000", + "rewardsCoordinator": "0xAcc1fb458a1317E886dB376Fc8141540537E68fE", + "rewardsCoordinatorImplementation": "0xe54625095656206AC1B42819875343453c447f97", "slasher": "0xcAe751b75833ef09627549868A04E32679386e7C", "slasherImplementation": "0x99715D255E34a39bE9943b82F281CA734bcF345A", - "numStrategiesDeployed": 8, + "numStrategiesDeployed": 10, "strategies": { "WETH": "0x80528D6e9A2BAbFc766965E0E26d5aB08D9CFaF9", "rETH": "0x3A8fBdf9e77DFc25d09741f51d3E181b25d0c4E0", "stETH": "0x7D704507b76571a51d9caE8AdDAbBFd0ba0e63d3", - "lsETH": "0x05037A81BD7B4C9E0F7B430f1F2A22c31a2FD943", - "frxETH": "0x15F70a41Afe34020B3B16079010D3e88c4A85daf", "ETHx": "0x31B6F59e1627cEfC9fA174aD03859fC337666af7", + "cbETH": "0x70EB4D3c164a6B4A5f908D4FBb5a9cAfFb66bAB6", + "sfrxETH": "0x9281ff96637710Cd9A5CAcce9c6FAD8C9F54631c", + "lsETH": "0x05037A81BD7B4C9E0F7B430f1F2A22c31a2FD943", "osETH": "0x46281E3B7fDcACdBa44CADf069a94a588Fd4C6Ef", - "cbETH": "0x70EB4D3c164a6B4A5f908D4FBb5a9cAfFb66bAB6" + "mETH": "0xaccc5A86732BE85b5012e8614AF237801636F8e5", + "ankrETH" :"0x7673a47463F80c6a3553Db9E54c8cDcd5313d0ac" }, "strategyAddresses": [ - "0x3A8fBdf9e77DFc25d09741f51d3E181b25d0c4E0", "0x80528D6e9A2BAbFc766965E0E26d5aB08D9CFaF9", + "0x3A8fBdf9e77DFc25d09741f51d3E181b25d0c4E0", "0x7D704507b76571a51d9caE8AdDAbBFd0ba0e63d3", - "0x05037A81BD7B4C9E0F7B430f1F2A22c31a2FD943", - "0x15F70a41Afe34020B3B16079010D3e88c4A85daf", "0x31B6F59e1627cEfC9fA174aD03859fC337666af7", + "0x70EB4D3c164a6B4A5f908D4FBb5a9cAfFb66bAB6", + "0x9281ff96637710Cd9A5CAcce9c6FAD8C9F54631c", + "0x05037A81BD7B4C9E0F7B430f1F2A22c31a2FD943", "0x46281E3B7fDcACdBa44CADf069a94a588Fd4C6Ef", - "0x70EB4D3c164a6B4A5f908D4FBb5a9cAfFb66bAB6" + "0xaccc5A86732BE85b5012e8614AF237801636F8e5", + "0x7673a47463F80c6a3553Db9E54c8cDcd5313d0ac" ], "strategyManager": "0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6", "strategyManagerImplementation": "0x59f766A603C53f3AC8Be43bBe158c1519b193a18", @@ -56,10 +60,9 @@ "eigenStrategyImpl": "0x94650e09a471CEF96e7966cabf26718FBf352697" } }, - "numStrategies": 8, "chainInfo": { "chainId": 17000, - "deploymentBlock": 1167041 + "deploymentBlock": 1195642 }, "parameters": { "communityMultisig": "0xCb8d2f9e55Bc7B1FA9d089f9aC80C583D2BDD5F7", @@ -68,5 +71,5 @@ "pauserMultisig": "0x53410249ec7d3a3F9F1ba3912D50D6A3Df6d10A7", "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" } - } + \ No newline at end of file diff --git a/script/configs/holesky/eigenlayer_addresses_preprod.config.json b/script/configs/holesky/eigenlayer_addresses_preprod.config.json new file mode 100644 index 000000000..b515f7abc --- /dev/null +++ b/script/configs/holesky/eigenlayer_addresses_preprod.config.json @@ -0,0 +1,48 @@ +{ + "addresses": { + "avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC", + "avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A", + "baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40", + "beaconOracle": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25", + "delayedWithdrawalRouter": "0xC4BC46a87A67a531eCF7f74338E1FA79533334Fa", + "delayedWithdrawalRouterImplementation": "0x0011FA2c512063C495f77296Af8d195F33A8Dd38", + "delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC", + "delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1", + "eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1", + "eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B", + "eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC", + "eigenPodImplementation": "0x8Da4b953cbFb715624D98C0D2b4a7978462eFd38", + "eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff", + "eigenPodManagerImplementation": "0x10EBa780CCd9E5e9FFBe529C25046c076Be91048", + "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", + "rewardsCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0", + "rewardsCoordinatorImplementation": "0x7C80B0d3aFBeF9Bbd03Aab72cD2d90a12c11D394", + "slasher": "0x12699471dF8dca329C76D72823B1b79d55709384", + "slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0", + "numStrategiesDeployed": 0, + "strategies": {}, + "strategyAddresses": [], + "strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a", + "strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199", + "token": { + "EIGEN": "0xD58f6844f79eB1fbd9f7091d05f7cb30d3363926", + "EIGENImpl": "0x95a7431400F362F3647a69535C5666cA0133CAA0", + "bEIGEN": "0xA72942289a043874249E60469F68f08B8c6ECCe8", + "bEIGENImpl": "0xd5FdabDac3d8ACeAB7BFfDDFA18877A4c5D5Aa82", + "eigenStrategy": "0xdcCF401fD121d8C542E96BC1d0078884422aFAD2", + "eigenStrategyImpl": "0x59D13E7Fb0bC0e57c1fc6594ff701592A6e4dD2B", + "tokenProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B" + } + }, + "chainInfo": { + "chainId": 17000, + "deploymentBlock": 1477016 + }, + "parameters": { + "communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + } +} \ No newline at end of file diff --git a/script/configs/holesky/eigenlayer_preprod.config.json b/script/configs/holesky/eigenlayer_preprod.config.json new file mode 100644 index 000000000..7552f49f4 --- /dev/null +++ b/script/configs/holesky/eigenlayer_preprod.config.json @@ -0,0 +1,56 @@ +{ + "chainInfo": { + "chainId": 17000 + }, + "multisig_addresses": { + "pauserMultisig": "0x53410249ec7d3a3F9F1ba3912D50D6A3Df6d10A7", + "communityMultisig": "0xCb8d2f9e55Bc7B1FA9d089f9aC80C583D2BDD5F7", + "operationsMultisig": "0xfaEF7338b7490b9E272d80A1a39f4657cAf2b97d", + "executorMultisig": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + }, + "strategies": { + "numStrategies": 0, + "MAX_PER_DEPOSIT": 115792089237316195423570985008687907853269984665640564039457584007913129639935, + "MAX_TOTAL_DEPOSITS": 115792089237316195423570985008687907853269984665640564039457584007913129639935, + "strategiesToDeploy": [] + }, + "strategyManager": { + "init_strategy_whitelister": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348", + "init_paused_status": 0 + }, + "delegationManager": { + "init_paused_status": 0, + "init_minWithdrawalDelayBlocks": 10 + }, + "rewardsCoordinator": { + "init_paused_status": 0, + "CALCULATION_INTERVAL_SECONDS": 604800, + "MAX_REWARDS_DURATION": 6048000, + "MAX_RETROACTIVE_LENGTH": 7776000, + "MAX_FUTURE_LENGTH": 2592000, + "GENESIS_REWARDS_TIMESTAMP": 1710979200, + "rewards_updater_address": "0x18a0f92Ad9645385E8A8f3db7d0f6CF7aBBb0aD4", + "activation_delay": 120, + "calculation_interval_seconds": 604800, + "global_operator_commission_bips": 1000 + }, + "avsDirectory": { + "init_paused_status": 0 + }, + "slasher": { + "init_paused_status": 0 + }, + "eigenPod": { + "MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR": 32000000000, + "GENESIS_TIME": 1695902400 + }, + "eigenPodManager": { + "init_paused_status": 0 + }, + "delayedWithdrawalRouter": { + "init_paused_status": 0, + "init_withdrawalDelayBlocks": 10 + }, + "ethPOSDepositAddress": "0x4242424242424242424242424242424242424242" +} \ No newline at end of file diff --git a/script/deploy/devnet/M2_Deploy_From_Scratch.s.sol b/script/deploy/devnet/M2_Deploy_From_Scratch.s.sol index 36a1bd7b8..55510a7c9 100644 --- a/script/deploy/devnet/M2_Deploy_From_Scratch.s.sol +++ b/script/deploy/devnet/M2_Deploy_From_Scratch.s.sol @@ -7,7 +7,6 @@ import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.so import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import "../../../src/contracts/interfaces/IETHPOSDeposit.sol"; -import "../../../src/contracts/interfaces/IBeaconChainOracle.sol"; import "../../../src/contracts/core/StrategyManager.sol"; import "../../../src/contracts/core/Slasher.sol"; @@ -19,7 +18,6 @@ import "../../../src/contracts/strategies/StrategyBaseTVLLimits.sol"; import "../../../src/contracts/pods/EigenPod.sol"; import "../../../src/contracts/pods/EigenPodManager.sol"; -import "../../../src/contracts/pods/DelayedWithdrawalRouter.sol"; import "../../../src/contracts/permissions/PauserRegistry.sol"; @@ -62,8 +60,6 @@ contract Deployer_M2 is Script, Test { AVSDirectory public avsDirectoryImplementation; EigenPodManager public eigenPodManager; EigenPodManager public eigenPodManagerImplementation; - DelayedWithdrawalRouter public delayedWithdrawalRouter; - DelayedWithdrawalRouter public delayedWithdrawalRouterImplementation; UpgradeableBeacon public eigenPodBeacon; EigenPod public eigenPodImplementation; StrategyBase public baseStrategyImplementation; @@ -81,7 +77,6 @@ contract Deployer_M2 is Script, Test { StrategyBaseTVLLimits[] public deployedStrategyArray; // IMMUTABLES TO SET - uint64 MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; uint64 GOERLI_GENESIS_TIME = 1616508000; // OTHER DEPLOYMENT PARAMETERS @@ -89,7 +84,6 @@ contract Deployer_M2 is Script, Test { uint256 SLASHER_INIT_PAUSED_STATUS; uint256 DELEGATION_INIT_PAUSED_STATUS; uint256 EIGENPOD_MANAGER_INIT_PAUSED_STATUS; - uint256 DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS; uint256 REWARDS_COORDINATOR_INIT_PAUSED_STATUS; // RewardsCoordinator @@ -104,7 +98,6 @@ contract Deployer_M2 is Script, Test { // one week in blocks -- 50400 uint32 STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS; - uint32 DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS; uint256 DELEGATION_WITHDRAWAL_DELAY_BLOCKS; function run(string memory configFileName) external { @@ -122,10 +115,6 @@ contract Deployer_M2 is Script, Test { DELEGATION_INIT_PAUSED_STATUS = stdJson.readUint(config_data, ".delegation.init_paused_status"); DELEGATION_WITHDRAWAL_DELAY_BLOCKS = stdJson.readUint(config_data, ".delegation.init_withdrawal_delay_blocks"); EIGENPOD_MANAGER_INIT_PAUSED_STATUS = stdJson.readUint(config_data, ".eigenPodManager.init_paused_status"); - DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS = stdJson.readUint( - config_data, - ".delayedWithdrawalRouter.init_paused_status" - ); REWARDS_COORDINATOR_INIT_PAUSED_STATUS = stdJson.readUint( config_data, ".rewardsCoordinator.init_paused_status" @@ -149,13 +138,6 @@ contract Deployer_M2 is Script, Test { STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS = uint32( stdJson.readUint(config_data, ".strategyManager.init_withdrawal_delay_blocks") ); - DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS = uint32( - stdJson.readUint(config_data, ".strategyManager.init_withdrawal_delay_blocks") - ); - - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = uint64( - stdJson.readUint(config_data, ".eigenPod.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR") - ); // tokens to deploy strategies for StrategyConfig[] memory strategyConfigs; @@ -205,9 +187,6 @@ contract Deployer_M2 is Script, Test { eigenPodManager = EigenPodManager( address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) ); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); rewardsCoordinator = RewardsCoordinator( address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) ); @@ -221,9 +200,7 @@ contract Deployer_M2 is Script, Test { } eigenPodImplementation = new EigenPod( ethPOSDeposit, - delayedWithdrawalRouter, eigenPodManager, - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, GOERLI_GENESIS_TIME ); @@ -241,7 +218,6 @@ contract Deployer_M2 is Script, Test { slasher, delegation ); - delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); rewardsCoordinatorImplementation = new RewardsCoordinator( delegation, strategyManager, @@ -301,24 +277,11 @@ contract Deployer_M2 is Script, Test { address(eigenPodManagerImplementation), abi.encodeWithSelector( EigenPodManager.initialize.selector, - IBeaconChainOracle(address(0)), executorMultisig, eigenLayerPauserReg, EIGENPOD_MANAGER_INIT_PAUSED_STATUS ) ); - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation), - abi.encodeWithSelector( - DelayedWithdrawalRouter.initialize.selector, - executorMultisig, - eigenLayerPauserReg, - DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS, - DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS - ) - ); - eigenLayerProxyAdmin.upgradeAndCall( TransparentUpgradeableProxy(payable(address(rewardsCoordinator))), address(rewardsCoordinatorImplementation), @@ -368,7 +331,6 @@ contract Deployer_M2 is Script, Test { strategyManagerImplementation, slasherImplementation, eigenPodManagerImplementation, - delayedWithdrawalRouterImplementation, rewardsCoordinatorImplementation ); _verifyContractsPointAtOneAnother( @@ -376,7 +338,6 @@ contract Deployer_M2 is Script, Test { strategyManager, slasher, eigenPodManager, - delayedWithdrawalRouter, rewardsCoordinator ); _verifyImplementationsSetCorrectly(); @@ -420,12 +381,6 @@ contract Deployer_M2 is Script, Test { "eigenPodManagerImplementation", address(eigenPodManagerImplementation) ); - vm.serializeAddress(deployed_addresses, "delayedWithdrawalRouter", address(delayedWithdrawalRouter)); - vm.serializeAddress( - deployed_addresses, - "delayedWithdrawalRouterImplementation", - address(delayedWithdrawalRouterImplementation) - ); vm.serializeAddress(deployed_addresses, "rewardsCoordinator", address(rewardsCoordinator)); vm.serializeAddress( deployed_addresses, @@ -464,7 +419,6 @@ contract Deployer_M2 is Script, Test { StrategyManager strategyManagerContract, Slasher /*slasherContract*/, EigenPodManager eigenPodManagerContract, - DelayedWithdrawalRouter delayedWithdrawalRouterContract, RewardsCoordinator rewardsCoordinatorContract ) internal view { require(delegationContract.slasher() == slasher, "delegation: slasher address not set correctly"); @@ -504,11 +458,6 @@ contract Deployer_M2 is Script, Test { "eigenPodManager: slasher contract address not set correctly" ); - require( - delayedWithdrawalRouterContract.eigenPodManager() == eigenPodManager, - "delayedWithdrawalRouterContract: eigenPodManager address not set correctly" - ); - require( rewardsCoordinatorContract.delegationManager() == delegation, "rewardsCoordinator: delegation address not set correctly" @@ -543,12 +492,6 @@ contract Deployer_M2 is Script, Test { ) == address(eigenPodManagerImplementation), "eigenPodManager: implementation set incorrectly" ); - require( - eigenLayerProxyAdmin.getProxyImplementation( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))) - ) == address(delayedWithdrawalRouterImplementation), - "delayedWithdrawalRouter: implementation set incorrectly" - ); require( eigenLayerProxyAdmin.getProxyImplementation( TransparentUpgradeableProxy(payable(address(rewardsCoordinator))) @@ -580,10 +523,6 @@ contract Deployer_M2 is Script, Test { require(eigenLayerProxyAdmin.owner() == executorMultisig, "eigenLayerProxyAdmin: owner not set correctly"); require(eigenPodBeacon.owner() == executorMultisig, "eigenPodBeacon: owner not set correctly"); - require( - delayedWithdrawalRouter.owner() == executorMultisig, - "delayedWithdrawalRouter: owner not set correctly" - ); } function _checkPauserInitializations() internal view { @@ -598,10 +537,6 @@ contract Deployer_M2 is Script, Test { eigenPodManager.pauserRegistry() == eigenLayerPauserReg, "eigenPodManager: pauser registry not set correctly" ); - require( - delayedWithdrawalRouter.pauserRegistry() == eigenLayerPauserReg, - "delayedWithdrawalRouter: pauser registry not set correctly" - ); require( rewardsCoordinator.pauserRegistry() == eigenLayerPauserReg, "rewardsCoordinator: pauser registry not set correctly" @@ -632,43 +567,24 @@ contract Deployer_M2 is Script, Test { // // pause *all of the proof-related functionality* (everything that can be paused other than creation of EigenPods) // uint256 EIGENPOD_MANAGER_INIT_PAUSED_STATUS = (2**1) + (2**2) + (2**3) + (2**4); /* = 30 */ // // pause *nothing* - // uint256 DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS = 0; // require(strategyManager.paused() == 0, "strategyManager: init paused status set incorrectly"); // require(slasher.paused() == type(uint256).max, "slasher: init paused status set incorrectly"); // require(delegation.paused() == type(uint256).max, "delegation: init paused status set incorrectly"); // require(eigenPodManager.paused() == 30, "eigenPodManager: init paused status set incorrectly"); - // require(delayedWithdrawalRouter.paused() == 0, "delayedWithdrawalRouter: init paused status set incorrectly"); } function _verifyInitializationParams() internal { // // one week in blocks -- 50400 // uint32 STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS = 7 days / 12 seconds; - // uint32 DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS = 7 days / 12 seconds; // require(strategyManager.withdrawalDelayBlocks() == 7 days / 12 seconds, // "strategyManager: withdrawalDelayBlocks initialized incorrectly"); - // require(delayedWithdrawalRouter.withdrawalDelayBlocks() == 7 days / 12 seconds, - // "delayedWithdrawalRouter: withdrawalDelayBlocks initialized incorrectly"); // uint256 MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = 32 ether; - require( - eigenPodImplementation.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() == 32 gwei, - "eigenPod: MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR initialized incorrectly" - ); require( strategyManager.strategyWhitelister() == operationsMultisig, "strategyManager: strategyWhitelister address not set correctly" ); - require( - eigenPodManager.beaconChainOracle() == IBeaconChainOracle(address(0)), - "eigenPodManager: eigenPodBeacon contract address not set correctly" - ); - - require( - delayedWithdrawalRouter.eigenPodManager() == eigenPodManager, - "delayedWithdrawalRouter: eigenPodManager set incorrectly" - ); - require( baseStrategyImplementation.strategyManager() == strategyManager, "baseStrategyImplementation: strategyManager set incorrectly" @@ -682,10 +598,6 @@ contract Deployer_M2 is Script, Test { eigenPodImplementation.eigenPodManager() == eigenPodManager, " eigenPodImplementation: eigenPodManager contract address not set correctly" ); - require( - eigenPodImplementation.delayedWithdrawalRouter() == delayedWithdrawalRouter, - " eigenPodImplementation: delayedWithdrawalRouter contract address not set correctly" - ); string memory config_data = vm.readFile(deployConfigPath); for (uint i = 0; i < deployedStrategyArray.length; i++) { diff --git a/script/deploy/goerli/GoerliUpgrade1.s.sol b/script/deploy/goerli/GoerliUpgrade1.s.sol deleted file mode 100644 index 45e1258b5..000000000 --- a/script/deploy/goerli/GoerliUpgrade1.s.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.12; - -import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; - - -import "../../../src/contracts/interfaces/IETHPOSDeposit.sol"; -import "../../../src/contracts/interfaces/IBeaconChainOracle.sol"; - -import "../../../src/contracts/core/StrategyManager.sol"; -import "../../../src/contracts/core/Slasher.sol"; -import "../../../src/contracts/core/DelegationManager.sol"; - -import "../../../src/contracts/strategies/StrategyBase.sol"; - -import "../../../src/contracts/pods/EigenPod.sol"; -import "../../../src/contracts/pods/EigenPodManager.sol"; -import "../../../src/contracts/pods/DelayedWithdrawalRouter.sol"; - - -import "forge-std/Script.sol"; -import "forge-std/Test.sol"; - -// # To load the variables in the .env file -// source .env - -// # To deploy and verify our contract -// forge script script/misc/DeployStrategy.s.sol:DeployStrategy --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vvvv - -// NOTE: ONLY WORKS ON GOERLI -// CommitHash: eccdfd43bb882d66a68cad8875dde2979e204546 -contract GoerliUpgrade1 is Script, Test { - Vm cheats = Vm(HEVM_ADDRESS); - - string public deploymentOutputPath = string(bytes("script/output/M1_deployment_goerli_2023_3_23.json")); - - // EigenLayer Contract - - - function run() external { - // read and log the chainID - uint256 chainId = block.chainid; - emit log_named_uint("You are deploying on ChainID", chainId); - - string memory config_data = vm.readFile(deploymentOutputPath); - IStrategyManager strategyManager = IStrategyManager(stdJson.readAddress(config_data, ".addresses.strategyManager")); - IDelegationManager delegation = IDelegationManager(stdJson.readAddress(config_data, ".addresses.delegation")); - IEigenPodManager eigenPodManager = IEigenPodManager(stdJson.readAddress(config_data, ".addresses.eigenPodManager")); - // IBeacon eigenPodBeacon = IBeacon(stdJson.readAddress(config_data, ".addresses.eigenPodBeacon")); - ISlasher slasher = ISlasher(stdJson.readAddress(config_data, ".addresses.slasher")); - IDelayedWithdrawalRouter delayedWithdrawalRouter = IDelayedWithdrawalRouter(stdJson.readAddress(config_data, ".addresses.delayedWithdrawalRouter")); - - vm.startBroadcast(); - - address strategyManagerImplementation = address( - new StrategyManager( - delegation, - eigenPodManager, - slasher - ) - ); - - address slasherImplementation = address( - new Slasher( - strategyManager, - delegation - ) - ); - - address eigenPodImplementation = address( - new EigenPod( - IETHPOSDeposit(0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b), - delayedWithdrawalRouter, - eigenPodManager, - 32e9, - 1616508000 - ) - ); - - vm.stopBroadcast(); - - emit log_named_address("StrategyManagerImplementation", strategyManagerImplementation); - emit log_named_address("SlasherImplementation", slasherImplementation); - emit log_named_address("EigenPodImplementation", eigenPodImplementation); - - // StrategyManagerImplementation: 0x1b8a566357c21b8b7b7c738a6963e2374718ea94 - // SlasherImplementation: 0x2f82092969d156da92f0b787525042735fc4774a - // EigenPodImplementation: 0x4dd49853a27e3d4a0557876fe225ffce9b6b5d7a - } -} diff --git a/script/deploy/goerli/GoerliUpgrade2.s.sol b/script/deploy/goerli/GoerliUpgrade2.s.sol deleted file mode 100644 index d643634f1..000000000 --- a/script/deploy/goerli/GoerliUpgrade2.s.sol +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.12; - -import "../../../src/contracts/interfaces/IETHPOSDeposit.sol"; - -import "../../../src/contracts/core/StrategyManager.sol"; -import "../../../src/contracts/core/Slasher.sol"; -import "../../../src/contracts/core/DelegationManager.sol"; -import "../../../src/contracts/core/AVSDirectory.sol"; - -import "../../../src/contracts/pods/EigenPod.sol"; -import "../../../src/contracts/pods/EigenPodManager.sol"; -import "../../../src/contracts/pods/DelayedWithdrawalRouter.sol"; - -import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import "../../../src/test/mocks/EmptyContract.sol"; -import "forge-std/Script.sol"; -import "forge-std/Test.sol"; - -// # To load the variables in the .env file -// source .env - -// # To deploy and verify our contract -// forge script script/upgrade/GoerliUpgrade2.s.sol:GoerliUpgrade2 --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vvvv - -// NOTE: ONLY WORKS ON GOERLI -// CommitHash: 6de01c6c16d6df44af15f0b06809dc160eac0ebf -contract GoerliUpgrade2 is Script, Test { - Vm cheats = Vm(HEVM_ADDRESS); - - string public deploymentOutputPath = string(bytes("script/output/M1_deployment_goerli_2023_3_23.json")); - - IDelayedWithdrawalRouter delayedWithdrawalRouter; - IDelegationManager delegation; - IEigenPodManager eigenPodManager; - IStrategyManager strategyManager; - ISlasher slasher; - IBeacon eigenPodBeacon; - EmptyContract emptyContract; - ProxyAdmin eigenLayerProxyAdmin; - - function run() external { - // read and log the chainID - uint256 chainId = block.chainid; - emit log_named_uint("You are deploying on ChainID", chainId); - - string memory config_data = vm.readFile(deploymentOutputPath); - - delayedWithdrawalRouter = IDelayedWithdrawalRouter(stdJson.readAddress(config_data, ".addresses.delayedWithdrawalRouter")); - delegation = IDelegationManager(stdJson.readAddress(config_data, ".addresses.delegation")); - eigenPodManager = IEigenPodManager(stdJson.readAddress(config_data, ".addresses.eigenPodManager")); - strategyManager = IStrategyManager(stdJson.readAddress(config_data, ".addresses.strategyManager")); - slasher = ISlasher(stdJson.readAddress(config_data, ".addresses.slasher")); - eigenPodBeacon = IBeacon(stdJson.readAddress(config_data, ".addresses.eigenPodBeacon")); - emptyContract = EmptyContract(stdJson.readAddress(config_data, ".addresses.emptyContract")); - eigenLayerProxyAdmin = ProxyAdmin(stdJson.readAddress(config_data, ".addresses.eigenLayerProxyAdmin")); - - vm.startBroadcast(); - - address delegationImplementation = address( - new DelegationManager( - strategyManager, - slasher, - eigenPodManager - ) - ); - - address slasherImplementation = address( - new Slasher( - strategyManager, - delegation - ) - ); - - address strategyManagerImplementation = address( - new StrategyManager( - delegation, - eigenPodManager, - slasher - ) - ); - - address delayedWithdrawalRouterImplementation = address( - new DelayedWithdrawalRouter( - eigenPodManager - ) - ); - - address eigenPodImplementation = address( - new EigenPod( - IETHPOSDeposit(0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b), - delayedWithdrawalRouter, - eigenPodManager, - 32e9, - 1616508000 - ) - ); - - address eigenPodManagerImplementation = address( - new EigenPodManager( - IETHPOSDeposit(0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b), - eigenPodBeacon, - strategyManager, - slasher, - delegation - ) - ); - - vm.stopBroadcast(); - - emit log_named_address("DelegationImplementation", delegationImplementation); - emit log_named_address("SlasherImplementation", slasherImplementation); - emit log_named_address("StrategyManagerImplementation", strategyManagerImplementation); - emit log_named_address("DelayedWithdrawalRouterImplementation", delayedWithdrawalRouterImplementation); - emit log_named_address("EigenPodImplementation", eigenPodImplementation); - emit log_named_address("EigenPodManagerImplementation", eigenPodManagerImplementation); - - /* - == Logs == - You are deploying on ChainID: 5 - DelegationImplementation: 0x56652542926444Ebce46Fd97aFd80824ed51e58C - SlasherImplementation: 0x89C5e6e98f79be658e830Ec66b61ED3EE910D262 - StrategyManagerImplementation: 0x506C21f43e81D9d231d8A13831b42A2a2B5540E4 - DelayedWithdrawalRouterImplementation: 0xE576731194EC3d8Ba92E7c2B578ea74238772878 - EigenPodImplementation: 0x16a0d8aD2A2b12f3f47d0e8F5929F9840e29a426 - EigenPodManagerImplementation: 0xDA9B60D3dC7adD40C0e35c628561Ff71C13a189f - */ - } -} diff --git a/script/deploy/holesky/Deploy_Preprod_RewardsCoordinator.s.sol b/script/deploy/holesky/Deploy_Preprod_RewardsCoordinator.s.sol index 2c4eaad65..c534efea1 100644 --- a/script/deploy/holesky/Deploy_Preprod_RewardsCoordinator.s.sol +++ b/script/deploy/holesky/Deploy_Preprod_RewardsCoordinator.s.sol @@ -45,7 +45,7 @@ contract Deploy_Preprod_RewardsCoordinator is Deploy_Test_RewardsCoordinator { // Sanity Checks _verifyContractPointers(); _verifyImplementations(); - _verifyContractsInitialized({isInitialDeployment: true}); + _verifyContractsInitialized(); _verifyInitializationParams(); logAndOutputContractAddresses("script/output/holesky/Deploy_RewardsCoordinator_Preprod.holesky.config.json"); diff --git a/script/deploy/holesky/Deploy_Test_RewardsCoordinator.s.sol b/script/deploy/holesky/Deploy_Test_RewardsCoordinator.s.sol index 74fce373b..d7776b454 100644 --- a/script/deploy/holesky/Deploy_Test_RewardsCoordinator.s.sol +++ b/script/deploy/holesky/Deploy_Test_RewardsCoordinator.s.sol @@ -32,7 +32,7 @@ contract Deploy_Test_RewardsCoordinator is ExistingDeploymentParser { // Sanity Checks _verifyContractPointers(); _verifyImplementations(); - _verifyContractsInitialized({isInitialDeployment: true}); + _verifyContractsInitialized(); _verifyInitializationParams(); logAndOutputContractAddresses("script/output/holesky/Deploy_RewardsCoordinator.holesky.config.json"); diff --git a/script/deploy/holesky/Eigen_Token_Deploy.s.sol b/script/deploy/holesky/Eigen_Token_Deploy.s.sol index 6ce776682..bd130a034 100644 --- a/script/deploy/holesky/Eigen_Token_Deploy.s.sol +++ b/script/deploy/holesky/Eigen_Token_Deploy.s.sol @@ -96,7 +96,7 @@ contract Eigen_Token_Deploy is Script, Test { tokenProxyAdmin.transferOwnership(operationsMultisig); } - function _verifyDeployment() internal { + function _verifyDeployment() internal view { require(EIGEN.totalSupply() == TOTAL_SUPPLY, "Eigen_Token_Deploy: total supply mismatch"); require(bEIGEN.totalSupply() == TOTAL_SUPPLY, "Eigen_Token_Deploy: total supply mismatch"); diff --git a/script/deploy/holesky/M2_Deploy_From_Scratch.s.sol b/script/deploy/holesky/M2_Deploy_From_Scratch.s.sol index 626626b49..1e7e371ea 100644 --- a/script/deploy/holesky/M2_Deploy_From_Scratch.s.sol +++ b/script/deploy/holesky/M2_Deploy_From_Scratch.s.sol @@ -26,7 +26,7 @@ contract M2_Deploy_Holesky_From_Scratch is ExistingDeploymentParser { // Sanity Checks _verifyContractPointers(); _verifyImplementations(); - _verifyContractsInitialized({isInitialDeployment: true}); + _verifyContractsInitialized(); _verifyInitializationParams(); logAndOutputContractAddresses("script/output/holesky/M2_deploy_from_scratch.holesky.config.json"); @@ -67,16 +67,10 @@ contract M2_Deploy_Holesky_From_Scratch is ExistingDeploymentParser { eigenPodManager = EigenPodManager( address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) ); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - // Deploy EigenPod Contracts eigenPodImplementation = new EigenPod( IETHPOSDeposit(ETHPOSDepositAddress), - delayedWithdrawalRouter, eigenPodManager, - EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, EIGENPOD_GENESIS_TIME ); @@ -92,7 +86,6 @@ contract M2_Deploy_Holesky_From_Scratch is ExistingDeploymentParser { slasher, delegationManager ); - delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); // Third, upgrade the proxy contracts to point to the implementations IStrategy[] memory initializeStrategiesToSetDelayBlocks = new IStrategy[](0); @@ -151,24 +144,11 @@ contract M2_Deploy_Holesky_From_Scratch is ExistingDeploymentParser { address(eigenPodManagerImplementation), abi.encodeWithSelector( EigenPodManager.initialize.selector, - beaconOracle, msg.sender, // initialOwner is msg.sender for now to set forktimestamp later eigenLayerPauserReg, EIGENPOD_MANAGER_INIT_PAUSED_STATUS ) ); - // Delayed Withdrawal Router - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation), - abi.encodeWithSelector( - DelayedWithdrawalRouter.initialize.selector, - executorMultisig, // initialOwner - eigenLayerPauserReg, - DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS, - DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS - ) - ); // Deploy Strategies baseStrategyImplementation = new StrategyBaseTVLLimits(strategyManager); @@ -206,9 +186,6 @@ contract M2_Deploy_Holesky_From_Scratch is ExistingDeploymentParser { strategyManager.addStrategiesToDepositWhitelist(strategiesToWhitelist, thirdPartyTransfersForbiddenValues); strategyManager.setStrategyWhitelister(STRATEGY_MANAGER_WHITELISTER); - // Fork timestamp config - eigenPodManager.setDenebForkTimestamp(EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP); - // Transfer ownership strategyManager.transferOwnership(executorMultisig); eigenLayerProxyAdmin.transferOwnership(executorMultisig); diff --git a/script/deploy/holesky/M2_Deploy_Preprod.s.sol b/script/deploy/holesky/M2_Deploy_Preprod.s.sol index d58059955..8dde5dde7 100644 --- a/script/deploy/holesky/M2_Deploy_Preprod.s.sol +++ b/script/deploy/holesky/M2_Deploy_Preprod.s.sol @@ -42,7 +42,7 @@ contract M2_Deploy_Holesky_Preprod is M2_Deploy_Holesky_From_Scratch { // Sanity Checks _verifyContractPointers(); _verifyImplementations(); - _verifyContractsInitialized({isInitialDeployment: true}); + _verifyContractsInitialized(); _verifyInitializationParams(); // override to check contract.owner() is EOAowner instead logAndOutputContractAddresses("script/output/holesky/M2_deploy_preprod.holesky.config.json"); diff --git a/script/deploy/holesky/v040-holesky-pepe.s.sol b/script/deploy/holesky/v040-holesky-pepe.s.sol new file mode 100644 index 000000000..6baa09e16 --- /dev/null +++ b/script/deploy/holesky/v040-holesky-pepe.s.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "../../utils/ExistingDeploymentParser.sol"; + +/** + * @notice Script used for upgrading EigenPod and EPM Implementation for Holesky preprod + * anvil --fork-url $RPC_HOLESKY + * forge script script/deploy/holesky/v040-holesky-pepe.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv + * forge script script/deploy/holesky/v040-holesky-pepe.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --verify --broadcast -vvvv + */ +contract PEPE_Deploy_Preprod is ExistingDeploymentParser { + + address testAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + address initOwner = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + + function run() external virtual { + _parseInitialDeploymentParams( + "script/configs/holesky/Deploy_RewardsCoordinator.holesky.config.json" + ); + _parseDeployedContracts( + "script/configs/holesky/eigenlayer_addresses.config.json" + ); + + emit log_named_address("Deployer Address", msg.sender); + + emit log("PRIOR IMPLEMENTATION"); + emit log_named_address("current pod impl", address(eigenPodImplementation)); + emit log_named_address("- pod.ethPOS", address(eigenPodImplementation.ethPOS())); + emit log_named_address("- pod.eigenPodManager", address(eigenPodImplementation.eigenPodManager())); + emit log_named_uint("- pod.GENESIS_TIME", eigenPodImplementation.GENESIS_TIME()); + emit log_named_address("current manager impl", address(eigenPodManagerImplementation)); + emit log_named_address("- epm.ethPOS", address(eigenPodManagerImplementation.ethPOS())); + emit log_named_address("- epm.eigenPodBeacon", address(eigenPodManagerImplementation.eigenPodBeacon())); + emit log_named_address("- epm.strategyManager", address(eigenPodManagerImplementation.strategyManager())); + emit log_named_address("- epm.slasher", address(eigenPodManagerImplementation.slasher())); + emit log_named_address("- epm.delegationManager", address(eigenPodManagerImplementation.delegationManager())); + + // START RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.startBroadcast(); + + _deployPEPE(); + + // STOP RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.stopBroadcast(); + + logAndOutputContractAddresses("script/output/holesky/v040.output.json"); + } + + function _deployPEPE() internal { + // Deploy EigenPod + eigenPodImplementation = new EigenPod( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodManager, + EIGENPOD_GENESIS_TIME + ); + + // Deploy EigenPodManager + eigenPodManagerImplementation = new EigenPodManager( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodBeacon, + strategyManager, + slasher, + delegationManager + ); + } + + function _upgradePEPE() internal { + // upgrade UpgradeableBeacon + eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); + + // upgrade TUPS + eigenLayerProxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(eigenPodManager))), + address(eigenPodManagerImplementation) + ); + } +} diff --git a/script/deploy/holesky/v040-rc0-holesky-preprod-pepe.s.sol b/script/deploy/holesky/v040-rc0-holesky-preprod-pepe.s.sol new file mode 100644 index 000000000..fe173c6bb --- /dev/null +++ b/script/deploy/holesky/v040-rc0-holesky-preprod-pepe.s.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "../../utils/ExistingDeploymentParser.sol"; + +/** + * @notice Script used for upgrading EigenPod and EPM Implementation for Holesky preprod + * anvil --fork-url $RPC_HOLESKY + * forge script script/deploy/holesky/EigenPod_Checkpoint_Deploy_Preprod.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv + * forge script script/deploy/holesky/EigenPod_Checkpoint_Deploy_Preprod.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --verify --broadcast -vvvv + */ +contract EigenPod_Checkpoint_Deploy_Preprod is ExistingDeploymentParser { + + address testAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + address initOwner = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + + function run() external virtual { + _parseInitialDeploymentParams( + "script/configs/holesky/eigenlayer_preprod.config.json" + ); + _parseDeployedContracts( + "script/configs/holesky/eigenlayer_addresses_preprod.config.json" + ); + + // START RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.startBroadcast(); + + emit log_named_address("Deployer Address", msg.sender); + + _upgradeEigenPodAndEPM(); + + // STOP RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.stopBroadcast(); + + // Sanity Checks + _verifyContractPointers(); + _verifyImplementations(); + _verifyContractsInitialized(); + _verifyInitializationParams(); + + logAndOutputContractAddresses("script/output/holesky/v040-rc0.output.json"); + } + + /** + * @notice Deploy EigenPod and EPM Implementation for Holesky preprod and upgrade the beacon/proxy + */ + function _upgradeEigenPodAndEPM() internal { + // Deploy implementations + eigenPodManagerImplementation = new EigenPodManager( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodBeacon, + strategyManager, + slasher, + delegationManager + ); + eigenPodImplementation = new EigenPod( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodManager, + EIGENPOD_GENESIS_TIME + ); + + // upgrade TUPS and UpgradeableBeacon + eigenLayerProxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(eigenPodManager))), + address(eigenPodManagerImplementation) + ); + eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); + } +} diff --git a/script/deploy/holesky/v040-rc1-holesky-preprod-pepe.s.sol b/script/deploy/holesky/v040-rc1-holesky-preprod-pepe.s.sol new file mode 100644 index 000000000..a09b67599 --- /dev/null +++ b/script/deploy/holesky/v040-rc1-holesky-preprod-pepe.s.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "../../utils/ExistingDeploymentParser.sol"; + +/** + * @notice Script used for upgrading EigenPod and EPM Implementation for Holesky preprod + * anvil --fork-url $RPC_HOLESKY + * forge script script/deploy/holesky/v040-rc1-holesky-preprod-pepe.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv + * forge script script/deploy/holesky/v040-rc1-holesky-preprod-pepe.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --verify --broadcast -vvvv + */ +contract EigenPod_Checkpoint_Deploy_Preprod is ExistingDeploymentParser { + + address testAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + address initOwner = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + + function run() external virtual { + _parseInitialDeploymentParams( + "script/configs/holesky/eigenlayer_preprod.config.json" + ); + _parseDeployedContracts( + "script/configs/holesky/eigenlayer_addresses_preprod.config.json" + ); + + emit log_named_address("Deployer Address", msg.sender); + + // START RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.startBroadcast(); + + _upgradeEigenPods(); + + // STOP RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.stopBroadcast(); + + // Sanity Checks + _verifyContractPointers(); + _verifyImplementations(); + _verifyContractsInitialized(); + _verifyInitializationParams(); + + logAndOutputContractAddresses("script/output/holesky/v040-rc1.output.json"); + } + + /** + * @notice Deploy EigenPod Implementation for Holesky preprod and upgrade the beacon + */ + function _upgradeEigenPods() internal { + // Deploy implementation + eigenPodImplementation = new EigenPod( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodManager, + EIGENPOD_GENESIS_TIME + ); + + // upgrade UpgradeableBeacon + eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); + } +} diff --git a/script/deploy/holesky/v040-rc2-holesky-preprod-pepe.s.sol b/script/deploy/holesky/v040-rc2-holesky-preprod-pepe.s.sol new file mode 100644 index 000000000..0f0be39f6 --- /dev/null +++ b/script/deploy/holesky/v040-rc2-holesky-preprod-pepe.s.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "../../utils/ExistingDeploymentParser.sol"; + +/** + * @notice Script used for upgrading EigenPod and EPM Implementation for Holesky preprod + * anvil --fork-url $RPC_HOLESKY + * forge script script/deploy/holesky/v040-rc2-holesky-preprod-pepe.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv + * forge script script/deploy/holesky/v040-rc2-holesky-preprod-pepe.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --verify --broadcast -vvvv + */ +contract EigenPod_Checkpoint_Deploy_Preprod is ExistingDeploymentParser { + + address testAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + address initOwner = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + + function run() external virtual { + _parseInitialDeploymentParams( + "script/configs/holesky/eigenlayer_preprod.config.json" + ); + _parseDeployedContracts( + "script/configs/holesky/eigenlayer_addresses_preprod.config.json" + ); + + emit log_named_address("Deployer Address", msg.sender); + + // START RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.startBroadcast(); + + _upgradeEigenPods(); + + // STOP RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.stopBroadcast(); + + // Sanity Checks + _verifyContractPointers(); + _verifyImplementations(); + _verifyContractsInitialized(); + _verifyInitializationParams(); + + logAndOutputContractAddresses("script/output/holesky/v040-rc2.output.json"); + } + + /** + * @notice Deploy EigenPod Implementation for Holesky preprod and upgrade the beacon + */ + function _upgradeEigenPods() internal { + // Deploy implementation + eigenPodImplementation = new EigenPod( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodManager, + EIGENPOD_GENESIS_TIME + ); + + // upgrade UpgradeableBeacon + eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); + } +} diff --git a/script/deploy/holesky/v040-rc3-holesky-preprod-pepe.s.sol b/script/deploy/holesky/v040-rc3-holesky-preprod-pepe.s.sol new file mode 100644 index 000000000..1b740a214 --- /dev/null +++ b/script/deploy/holesky/v040-rc3-holesky-preprod-pepe.s.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "../../utils/ExistingDeploymentParser.sol"; + +/** + * @notice Script used for upgrading EigenPod and EPM Implementation for Holesky preprod + * anvil --fork-url $RPC_HOLESKY + * forge script script/deploy/holesky/v040-rc3-holesky-preprod-pepe.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv + * forge script script/deploy/holesky/v040-rc3-holesky-preprod-pepe.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --verify --broadcast -vvvv + */ +contract EigenPod_Checkpoint_Deploy_Preprod is ExistingDeploymentParser { + + address testAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + address initOwner = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + + function run() external virtual { + _parseInitialDeploymentParams( + "script/configs/holesky/eigenlayer_preprod.config.json" + ); + _parseDeployedContracts( + "script/configs/holesky/eigenlayer_addresses_preprod.config.json" + ); + + emit log_named_address("Deployer Address", msg.sender); + + // START RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.startBroadcast(); + + _upgradeEigenPods(); + + // STOP RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.stopBroadcast(); + + // Sanity Checks + _verifyContractPointers(); + _verifyImplementations(); + _verifyContractsInitialized(); + _verifyInitializationParams(); + + logAndOutputContractAddresses("script/output/holesky/v040-rc3.output.json"); + } + + /** + * @notice Deploy EigenPod Implementation for Holesky preprod and upgrade the beacon + */ + function _upgradeEigenPods() internal { + // Deploy implementation + eigenPodImplementation = new EigenPod( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodManager, + EIGENPOD_GENESIS_TIME + ); + + // upgrade UpgradeableBeacon + eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); + } +} diff --git a/script/deploy/holesky/v040-rc4-holesky-preprod-pepe.s.sol b/script/deploy/holesky/v040-rc4-holesky-preprod-pepe.s.sol new file mode 100644 index 000000000..be8c74a57 --- /dev/null +++ b/script/deploy/holesky/v040-rc4-holesky-preprod-pepe.s.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "../../utils/ExistingDeploymentParser.sol"; + +/** + * @notice Script used for upgrading EigenPod and EPM Implementation for Holesky preprod + * anvil --fork-url $RPC_HOLESKY + * forge script script/deploy/holesky/v040-rc4-holesky-preprod-pepe.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv + * forge script script/deploy/holesky/v040-rc4-holesky-preprod-pepe.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --verify --broadcast -vvvv + */ +contract EigenPod_Checkpoint_Deploy_Preprod is ExistingDeploymentParser { + + address testAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + address initOwner = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + + function run() external virtual { + _parseInitialDeploymentParams( + "script/configs/holesky/eigenlayer_preprod.config.json" + ); + _parseDeployedContracts( + "script/configs/holesky/eigenlayer_addresses_preprod.config.json" + ); + + emit log_named_address("Deployer Address", msg.sender); + + // START RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.startBroadcast(); + + _upgradeEigenPods(); + _upgradeEigenPodManager(); + + // STOP RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.stopBroadcast(); + + // Sanity Checks + _verifyContractPointers(); + _verifyImplementations(); + _verifyContractsInitialized(); + _verifyInitializationParams(); + + logAndOutputContractAddresses("script/output/holesky/v040-rc4.output.json"); + } + + /** + * @notice Deploy EigenPod Implementation for Holesky preprod and upgrade the beacon + */ + function _upgradeEigenPods() internal { + // Deploy implementation + eigenPodImplementation = new EigenPod( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodManager, + EIGENPOD_GENESIS_TIME + ); + + // upgrade UpgradeableBeacon + eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); + } + + /** + * @notice Deploy EPM Implementation for Holesky preprod and upgrade its proxy + */ + function _upgradeEigenPodManager() internal { + // Deploy implementation + eigenPodManagerImplementation = new EigenPodManager( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodBeacon, + strategyManager, + slasher, + delegationManager + ); + + // upgrade TUPS + eigenLayerProxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(eigenPodManager))), + address(eigenPodManagerImplementation) + ); + } +} diff --git a/script/deploy/holesky/v040-rc5-holesky-preprod-pepe.s.sol b/script/deploy/holesky/v040-rc5-holesky-preprod-pepe.s.sol new file mode 100644 index 000000000..1506d96e6 --- /dev/null +++ b/script/deploy/holesky/v040-rc5-holesky-preprod-pepe.s.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "../../utils/ExistingDeploymentParser.sol"; + +/** + * @notice Script used for upgrading EigenPod and EPM Implementation for Holesky preprod + * anvil --fork-url $RPC_HOLESKY + * forge script script/deploy/holesky/v040-rc5-holesky-preprod-pepe.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv + * forge script script/deploy/holesky/v040-rc5-holesky-preprod-pepe.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --verify --broadcast -vvvv + */ +contract EigenPod_Checkpoint_Deploy_Preprod is ExistingDeploymentParser { + + address testAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + address initOwner = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + + function run() external virtual { + _parseInitialDeploymentParams( + "script/configs/holesky/eigenlayer_preprod.config.json" + ); + _parseDeployedContracts( + "script/configs/holesky/eigenlayer_addresses_preprod.config.json" + ); + + emit log_named_address("Deployer Address", msg.sender); + + // START RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.startBroadcast(); + + _upgradeEigenPods(); + _upgradeEigenPodManager(); + + // STOP RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.stopBroadcast(); + + // Sanity Checks + _verifyContractPointers(); + _verifyImplementations(); + _verifyContractsInitialized(); + _verifyInitializationParams(); + + logAndOutputContractAddresses("script/output/holesky/v040-rc5.output.json"); + } + + /** + * @notice Deploy EigenPod Implementation for Holesky preprod and upgrade the beacon + */ + function _upgradeEigenPods() internal { + // Deploy implementation + eigenPodImplementation = new EigenPod( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodManager, + EIGENPOD_GENESIS_TIME + ); + + // upgrade UpgradeableBeacon + eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); + } + + /** + * @notice Deploy EPM Implementation for Holesky preprod and upgrade its proxy + */ + function _upgradeEigenPodManager() internal { + // Deploy implementation + eigenPodManagerImplementation = new EigenPodManager( + IETHPOSDeposit(ETHPOSDepositAddress), + eigenPodBeacon, + strategyManager, + slasher, + delegationManager + ); + + // upgrade TUPS + eigenLayerProxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(eigenPodManager))), + address(eigenPodManagerImplementation) + ); + } +} diff --git a/script/deploy/mainnet/EigenPod_Minor_Upgrade_Deploy.s.sol b/script/deploy/mainnet/EigenPod_Minor_Upgrade_Deploy.s.sol index 78123a7bf..774e85dc8 100644 --- a/script/deploy/mainnet/EigenPod_Minor_Upgrade_Deploy.s.sol +++ b/script/deploy/mainnet/EigenPod_Minor_Upgrade_Deploy.s.sol @@ -7,7 +7,6 @@ import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.so import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import "../../../src/contracts/interfaces/IETHPOSDeposit.sol"; -import "../../../src/contracts/interfaces/IBeaconChainOracle.sol"; import "../../../src/contracts/core/StrategyManager.sol"; import "../../../src/contracts/core/Slasher.sol"; @@ -15,7 +14,6 @@ import "../../../src/contracts/core/DelegationManager.sol"; import "../../../src/contracts/pods/EigenPod.sol"; import "../../../src/contracts/pods/EigenPodManager.sol"; -import "../../../src/contracts/pods/DelayedWithdrawalRouter.sol"; import "../../../src/contracts/permissions/PauserRegistry.sol"; @@ -41,16 +39,14 @@ contract EigenPod_Minor_Upgrade_Deploy is Script, Test { StrategyManager public strategyManagerImplementation; IEigenPodManager public eigenPodManager; EigenPodManager public eigenPodManagerImplementation; - IDelayedWithdrawalRouter public delayedWithdrawalRouter; IBeacon public eigenPodBeacon; EigenPod public eigenPodImplementation; // Eigenlayer Proxy Admin ProxyAdmin public eigenLayerProxyAdmin; - // BeaconChain deposit contract & beacon chain oracle + // BeaconChain deposit contract IETHPOSDeposit public ethPOS; - address public beaconChainOracle; // RPC url to fork from for pre-upgrade state change tests string public rpcUrl; @@ -84,8 +80,7 @@ contract EigenPod_Minor_Upgrade_Deploy is Script, Test { eigenLayerProxyAdmin = ProxyAdmin(stdJson.readAddress(deployment_data, ".addresses.eigenLayerProxyAdmin")); genesisTimeBefore = EigenPod(payable(eigenPodBeacon.implementation())).GENESIS_TIME(); - maxRestakedBalanceBefore = EigenPod(payable(eigenPodBeacon.implementation())).MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR(); - delayedWithdrawalRouter = EigenPod(payable(eigenPodBeacon.implementation())).delayedWithdrawalRouter(); + // maxRestakedBalanceBefore = EigenPod(payable(eigenPodBeacon.implementation())).MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR(); // Begin deployment vm.startBroadcast(); @@ -93,9 +88,8 @@ contract EigenPod_Minor_Upgrade_Deploy is Script, Test { // Deploy new implmementation contracts eigenPodImplementation = new EigenPod({ _ethPOS: ethPOS, - _delayedWithdrawalRouter: delayedWithdrawalRouter, _eigenPodManager: eigenPodManager, - _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR: maxRestakedBalanceBefore, + // _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR: maxRestakedBalanceBefore, _GENESIS_TIME: genesisTimeBefore }); @@ -143,25 +137,22 @@ contract EigenPod_Minor_Upgrade_Deploy is Script, Test { // Check that state is correct require(eigenPodBeacon.implementation() == address(eigenPodImplementation), "implementation set incorrectly"); - require(eigenPodImplementation.delayedWithdrawalRouter() == delayedWithdrawalRouter, - "delayedWithdrawalRouter set incorrectly"); require(eigenPodImplementation.ethPOS() == ethPOS, "ethPOS set incorrectly"); require(eigenPodImplementation.eigenPodManager() == eigenPodManager, "eigenPodManager set incorrectly"); // check that values are unchanged - require(eigenPodImplementation.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() == maxRestakedBalanceBefore, - "MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR set incorrectly"); + // require(eigenPodImplementation.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() == maxRestakedBalanceBefore, + // "MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR set incorrectly"); require(eigenPodImplementation.GENESIS_TIME() == genesisTimeBefore, "GENESIS_TIME set incorrectly"); // redundant checks on correct values - require(eigenPodImplementation.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() == 32 gwei, - "MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR set incorrectly"); + // require(eigenPodImplementation.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() == 32 gwei, + // "MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR set incorrectly"); require(eigenPodImplementation.GENESIS_TIME() == 1606824023, "GENESIS_TIME set incorrectly"); - require(address(EigenPod(payable(eigenPodBeacon.implementation())).delayedWithdrawalRouter()) == 0x7Fe7E9CC0F274d2435AD5d56D5fa73E47F6A23D8); require(address(EigenPod(payable(eigenPodBeacon.implementation())).eigenPodManager()) == 0x91E677b07F7AF907ec9a428aafA9fc14a0d3A338); require(address(EigenPod(payable(eigenPodBeacon.implementation())).ethPOS()) == 0x00000000219ab540356cBB839Cbe05303d7705Fa); } diff --git a/script/deploy/mainnet/M1_Deploy.s.sol b/script/deploy/mainnet/M1_Deploy.s.sol index 48a7db712..d765774a6 100644 --- a/script/deploy/mainnet/M1_Deploy.s.sol +++ b/script/deploy/mainnet/M1_Deploy.s.sol @@ -7,7 +7,6 @@ import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.so import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import "../../../src/contracts/interfaces/IETHPOSDeposit.sol"; -import "../../../src/contracts/interfaces/IBeaconChainOracle.sol"; import "../../../src/contracts/core/StrategyManager.sol"; import "../../../src/contracts/core/Slasher.sol"; @@ -17,7 +16,6 @@ import "../../../src/contracts/strategies/StrategyBaseTVLLimits.sol"; import "../../../src/contracts/pods/EigenPod.sol"; import "../../../src/contracts/pods/EigenPodManager.sol"; -import "../../../src/contracts/pods/DelayedWithdrawalRouter.sol"; import "../../../src/contracts/permissions/PauserRegistry.sol"; @@ -56,8 +54,6 @@ contract Deployer_M1 is Script, Test { StrategyManager public strategyManagerImplementation; EigenPodManager public eigenPodManager; EigenPodManager public eigenPodManagerImplementation; - DelayedWithdrawalRouter public delayedWithdrawalRouter; - DelayedWithdrawalRouter public delayedWithdrawalRouterImplementation; UpgradeableBeacon public eigenPodBeacon; EigenPod public eigenPodImplementation; StrategyBase public baseStrategyImplementation; @@ -85,11 +81,9 @@ contract Deployer_M1 is Script, Test { uint256 DELEGATION_INIT_PAUSED_STATUS; uint256 EIGENPOD_MANAGER_INIT_PAUSED_STATUS; uint256 EIGENPOD_MANAGER_MAX_PODS; - uint256 DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS; // one week in blocks -- 50400 uint32 STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS; - uint32 DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS; function run() external { // read and log the chainID @@ -105,17 +99,10 @@ contract Deployer_M1 is Script, Test { DELEGATION_INIT_PAUSED_STATUS = stdJson.readUint(config_data, ".delegation.init_paused_status"); EIGENPOD_MANAGER_MAX_PODS = stdJson.readUint(config_data, ".eigenPodManager.max_pods"); EIGENPOD_MANAGER_INIT_PAUSED_STATUS = stdJson.readUint(config_data, ".eigenPodManager.init_paused_status"); - DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS = stdJson.readUint( - config_data, - ".delayedWithdrawalRouter.init_paused_status" - ); STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS = uint32( stdJson.readUint(config_data, ".strategyManager.init_withdrawal_delay_blocks") ); - DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS = uint32( - stdJson.readUint(config_data, ".strategyManager.init_withdrawal_delay_blocks") - ); REQUIRED_BALANCE_WEI = stdJson.readUint(config_data, ".eigenPod.REQUIRED_BALANCE_WEI"); MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = stdJson.readUint( @@ -168,9 +155,6 @@ contract Deployer_M1 is Script, Test { eigenPodManager = EigenPodManager( address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) ); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); // if on mainnet, use the ETH2 deposit contract address if (chainId == 1) { @@ -181,9 +165,7 @@ contract Deployer_M1 is Script, Test { } eigenPodImplementation = new EigenPod( ethPOSDeposit, - delayedWithdrawalRouter, eigenPodManager, - uint64(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR), GOERLI_GENESIS_TIME ); @@ -200,7 +182,6 @@ contract Deployer_M1 is Script, Test { slasher, delegation ); - delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. eigenLayerProxyAdmin.upgradeAndCall( @@ -239,24 +220,11 @@ contract Deployer_M1 is Script, Test { address(eigenPodManagerImplementation), abi.encodeWithSelector( EigenPodManager.initialize.selector, - EIGENPOD_MANAGER_MAX_PODS, - IBeaconChainOracle(address(0)), executorMultisig, eigenLayerPauserReg, EIGENPOD_MANAGER_INIT_PAUSED_STATUS ) ); - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation), - abi.encodeWithSelector( - DelayedWithdrawalRouter.initialize.selector, - executorMultisig, - eigenLayerPauserReg, - DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS, - DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS - ) - ); // deploy StrategyBaseTVLLimits contract implementation baseStrategyImplementation = new StrategyBaseTVLLimits(strategyManager); @@ -292,15 +260,13 @@ contract Deployer_M1 is Script, Test { delegationImplementation, strategyManagerImplementation, slasherImplementation, - eigenPodManagerImplementation, - delayedWithdrawalRouterImplementation + eigenPodManagerImplementation ); _verifyContractsPointAtOneAnother( delegation, strategyManager, slasher, - eigenPodManager, - delayedWithdrawalRouter + eigenPodManager ); _verifyImplementationsSetCorrectly(); _verifyInitialOwners(); @@ -339,12 +305,6 @@ contract Deployer_M1 is Script, Test { "eigenPodManagerImplementation", address(eigenPodManagerImplementation) ); - vm.serializeAddress(deployed_addresses, "delayedWithdrawalRouter", address(delayedWithdrawalRouter)); - vm.serializeAddress( - deployed_addresses, - "delayedWithdrawalRouterImplementation", - address(delayedWithdrawalRouterImplementation) - ); vm.serializeAddress(deployed_addresses, "eigenPodBeacon", address(eigenPodBeacon)); vm.serializeAddress(deployed_addresses, "eigenPodImplementation", address(eigenPodImplementation)); vm.serializeAddress(deployed_addresses, "baseStrategyImplementation", address(baseStrategyImplementation)); @@ -374,8 +334,7 @@ contract Deployer_M1 is Script, Test { DelegationManager delegationContract, StrategyManager strategyManagerContract, Slasher slasherContract, - EigenPodManager eigenPodManagerContract, - DelayedWithdrawalRouter delayedWithdrawalRouterContract + EigenPodManager eigenPodManagerContract ) internal view { require(delegationContract.slasher() == slasher, "delegation: slasher address not set correctly"); require( @@ -412,11 +371,6 @@ contract Deployer_M1 is Script, Test { eigenPodManagerContract.slasher() == slasher, "eigenPodManager: slasher contract address not set correctly" ); - - require( - delayedWithdrawalRouterContract.eigenPodManager() == eigenPodManager, - "delayedWithdrawalRouterContract: eigenPodManager address not set correctly" - ); } function _verifyImplementationsSetCorrectly() internal view { @@ -442,12 +396,6 @@ contract Deployer_M1 is Script, Test { ) == address(eigenPodManagerImplementation), "eigenPodManager: implementation set incorrectly" ); - require( - eigenLayerProxyAdmin.getProxyImplementation( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))) - ) == address(delayedWithdrawalRouterImplementation), - "delayedWithdrawalRouter: implementation set incorrectly" - ); for (uint256 i = 0; i < deployedStrategyArray.length; ++i) { require( @@ -472,10 +420,6 @@ contract Deployer_M1 is Script, Test { require(eigenLayerProxyAdmin.owner() == executorMultisig, "eigenLayerProxyAdmin: owner not set correctly"); require(eigenPodBeacon.owner() == executorMultisig, "eigenPodBeacon: owner not set correctly"); - require( - delayedWithdrawalRouter.owner() == executorMultisig, - "delayedWithdrawalRouter: owner not set correctly" - ); } function _checkPauserInitializations() internal view { @@ -489,10 +433,6 @@ contract Deployer_M1 is Script, Test { eigenPodManager.pauserRegistry() == eigenLayerPauserReg, "eigenPodManager: pauser registry not set correctly" ); - require( - delayedWithdrawalRouter.pauserRegistry() == eigenLayerPauserReg, - "delayedWithdrawalRouter: pauser registry not set correctly" - ); require(eigenLayerPauserReg.isPauser(operationsMultisig), "pauserRegistry: operationsMultisig is not pauser"); require(eigenLayerPauserReg.isPauser(executorMultisig), "pauserRegistry: executorMultisig is not pauser"); @@ -519,22 +459,17 @@ contract Deployer_M1 is Script, Test { // // pause *all of the proof-related functionality* (everything that can be paused other than creation of EigenPods) // uint256 EIGENPOD_MANAGER_INIT_PAUSED_STATUS = (2**1) + (2**2) + (2**3) + (2**4); /* = 30 */ // // pause *nothing* - // uint256 DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS = 0; require(strategyManager.paused() == 0, "strategyManager: init paused status set incorrectly"); require(slasher.paused() == type(uint256).max, "slasher: init paused status set incorrectly"); require(delegation.paused() == type(uint256).max, "delegation: init paused status set incorrectly"); require(eigenPodManager.paused() == 30, "eigenPodManager: init paused status set incorrectly"); - require(delayedWithdrawalRouter.paused() == 0, "delayedWithdrawalRouter: init paused status set incorrectly"); } function _verifyInitializationParams() internal { // // one week in blocks -- 50400 // uint32 STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS = 7 days / 12 seconds; - // uint32 DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS = 7 days / 12 seconds; // require(strategyManager.withdrawalDelayBlocks() == 7 days / 12 seconds, // "strategyManager: withdrawalDelayBlocks initialized incorrectly"); - // require(delayedWithdrawalRouter.withdrawalDelayBlocks() == 7 days / 12 seconds, - // "delayedWithdrawalRouter: withdrawalDelayBlocks initialized incorrectly"); // uint256 REQUIRED_BALANCE_WEI = 32 ether; require( @@ -542,16 +477,6 @@ contract Deployer_M1 is Script, Test { "strategyManager: strategyWhitelister address not set correctly" ); - require( - eigenPodManager.beaconChainOracle() == IBeaconChainOracle(address(0)), - "eigenPodManager: eigenPodBeacon contract address not set correctly" - ); - - require( - delayedWithdrawalRouter.eigenPodManager() == eigenPodManager, - "delayedWithdrawalRouter: eigenPodManager set incorrectly" - ); - require( baseStrategyImplementation.strategyManager() == strategyManager, "baseStrategyImplementation: strategyManager set incorrectly" @@ -565,10 +490,6 @@ contract Deployer_M1 is Script, Test { eigenPodImplementation.eigenPodManager() == eigenPodManager, " eigenPodImplementation: eigenPodManager contract address not set correctly" ); - require( - eigenPodImplementation.delayedWithdrawalRouter() == delayedWithdrawalRouter, - " eigenPodImplementation: delayedWithdrawalRouter contract address not set correctly" - ); string memory config_data = vm.readFile(deployConfigPath); for (uint i = 0; i < deployedStrategyArray.length; i++) { diff --git a/script/deploy/mainnet/M2Deploy.s.sol b/script/deploy/mainnet/M2Deploy.s.sol index 45e765b4b..4a6c0daa3 100644 --- a/script/deploy/mainnet/M2Deploy.s.sol +++ b/script/deploy/mainnet/M2Deploy.s.sol @@ -7,7 +7,6 @@ import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.so import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import "../../../src/contracts/interfaces/IETHPOSDeposit.sol"; -import "../../../src/contracts/interfaces/IBeaconChainOracle.sol"; import "../../../src/contracts/core/StrategyManager.sol"; import "../../../src/contracts/core/Slasher.sol"; @@ -15,7 +14,6 @@ import "../../../src/contracts/core/DelegationManager.sol"; import "../../../src/contracts/pods/EigenPod.sol"; import "../../../src/contracts/pods/EigenPodManager.sol"; -import "../../../src/contracts/pods/DelayedWithdrawalRouter.sol"; import "../../../src/contracts/permissions/PauserRegistry.sol"; @@ -41,16 +39,14 @@ contract M2Deploy is Script, Test { StrategyManager public strategyManagerImplementation; IEigenPodManager public eigenPodManager; EigenPodManager public eigenPodManagerImplementation; - IDelayedWithdrawalRouter public delayedWithdrawalRouter; IBeacon public eigenPodBeacon; EigenPod public eigenPodImplementation; // Eigenlayer Proxy Admin ProxyAdmin public eigenLayerProxyAdmin; - // BeaconChain deposit contract & beacon chain oracle + // BeaconChain deposit contract IETHPOSDeposit public ethPOS; - address public beaconChainOracle; // RPC url to fork from for pre-upgrade state change tests string public rpcUrl; @@ -95,9 +91,6 @@ contract M2Deploy is Script, Test { revert("Chain not supported"); } - // Set beacon chain oracle, currently 0 address - beaconChainOracle = 0x0000000000000000000000000000000000000000; - // Read json data string memory deployment_data = vm.readFile(m1DeploymentOutputPath); slasher = Slasher(stdJson.readAddress(deployment_data, ".addresses.slasher")); @@ -113,7 +106,6 @@ contract M2Deploy is Script, Test { strategyWhitelister = strategyManager.strategyWhitelister(); delegationManagerDomainSeparator = IDelegationManagerV0(address(delegation)).DOMAIN_SEPARATOR(); numPods = eigenPodManager.numPods(); - delayedWithdrawalRouter = EigenPod(payable(eigenPodBeacon.implementation())).delayedWithdrawalRouter(); // Set chain-specific values IStrategy[] memory strategyArray = new IStrategy[](1); @@ -159,9 +151,7 @@ contract M2Deploy is Script, Test { ); eigenPodImplementation = new EigenPod({ _ethPOS: ethPOS, - _delayedWithdrawalRouter: delayedWithdrawalRouter, _eigenPodManager: eigenPodManager, - _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR: 32 gwei, _GENESIS_TIME: 1616508000 }); @@ -175,7 +165,6 @@ contract M2Deploy is Script, Test { vm.serializeAddress(deployed_addresses, "slasher", address(slasher)); vm.serializeAddress(deployed_addresses, "delegation", address(delegation)); vm.serializeAddress(deployed_addresses, "strategyManager", address(strategyManager)); - vm.serializeAddress(deployed_addresses, "delayedWithdrawalRouter", address(delayedWithdrawalRouter)); vm.serializeAddress(deployed_addresses, "eigenPodManager", address(eigenPodManager)); vm.serializeAddress(deployed_addresses, "eigenPodBeacon", address(eigenPodBeacon)); vm.serializeAddress(deployed_addresses, "ethPOS", address(ethPOS)); @@ -247,7 +236,7 @@ contract M2Deploy is Script, Test { // Call contracts to ensure that all simple view functions return the same values (e.g. the return value of `StrategyManager.delegation()` hasn’t changed) // StrategyManager: delegation, eigenPodManager, slasher, strategyWhitelister, withdrawalDelayBlocks all unchanged // DelegationManager: DOMAIN_SEPARATOR, strategyManager, slasher, eigenPodManager all unchanged - // EigenPodManager: ethPOS, eigenPodBeacon, strategyManager, slasher, beaconChainOracle, numPods all unchanged + // EigenPodManager: ethPOS, eigenPodBeacon, strategyManager, slasher, numPods all unchanged // delegationManager is now correct (added immutable) // Call contracts to make sure they are still “initialized” (ensure that trying to call initializer reverts) function _verifyStorageSlots() internal view { @@ -276,10 +265,6 @@ contract M2Deploy is Script, Test { require(eigenPodManager.eigenPodBeacon() == eigenPodBeacon, "eigenPodManager.eigenPodBeacon incorrect"); require(eigenPodManager.strategyManager() == strategyManager, "eigenPodManager.strategyManager incorrect"); require(eigenPodManager.slasher() == slasher, "eigenPodManager.slasher incorrect"); - require( - address(eigenPodManager.beaconChainOracle()) == beaconChainOracle, - "eigenPodManager.beaconChainOracle incorrect" - ); require(eigenPodManager.numPods() == numPods, "eigenPodManager.numPods incorrect"); require(EigenPodManagerStorage(address(eigenPodManager)).delegationManager() == delegation, "eigenPodManager.delegationManager incorrect"); } @@ -308,7 +293,6 @@ contract M2Deploy is Script, Test { cheats.expectRevert(bytes("Initializable: contract is already initialized")); EigenPodManager(address(eigenPodManager)).initialize( - IBeaconChainOracle(address(this)), address(this), PauserRegistry(address(this)), 0 @@ -323,69 +307,15 @@ contract M2Deploy is Script, Test { ); require(eigenPodManager.hasPod(eigenPodDepositor) == hasPod, "eigenPodManager.hasPod incorrect"); require(eigenPod.podOwner() == eigenPodOwner, "eigenPod.podOwner incorrect"); - require( - eigenPod.mostRecentWithdrawalTimestamp() == mostRecentWithdrawalBlock, - "eigenPod.mostRecentWithdrawalTimestamp incorrect" - ); // Timestmap replace by block number in storage - require(!eigenPod.hasRestaked(), "eigenPod.hasRestaked incorrect"); // Unpause eigenpods verify credentials uint256 paused = IPausable(address(eigenPodManager)).paused(); cheats.prank(IPauserRegistry(IPausable(address(eigenPodManager)).pauserRegistry()).unpauser()); IPausable(address(eigenPodManager)).unpause(paused ^ (1 << 2)); // eigenpods verify credentials on 2nd bit - // Get values to check post activating restaking - uint256 podBalanceBefore = address(eigenPod).balance; - uint256 userWithdrawalsLength = delayedWithdrawalRouter.userWithdrawalsLength(eigenPodDepositor); - - // Activate restaking and expect emit cheats.prank(eigenPodOwner); - cheats.expectEmit(true, true, true, true); - emit RestakingActivated(eigenPodOwner); - eigenPod.activateRestaking(); - - // Check updated storage values - require(eigenPod.hasRestaked(), "eigenPod.hasRestaked not set to true"); - require(address(eigenPod).balance == 0, "eigenPod balance not 0 after activating restaking"); - require(eigenPod.nonBeaconChainETHBalanceWei() == 0, "non beacon chain eth balance not 0"); - require( - eigenPod.mostRecentWithdrawalTimestamp() == block.timestamp, - "eigenPod.mostRecentWithdrawalTimestamp not updated" - ); - require( - eigenPod.mostRecentWithdrawalTimestamp() > mostRecentWithdrawalBlock, - "eigenPod.mostRecentWithdrawalTimestamp not updated" - ); - - // Check that delayed withdrawal has been created - require( - delayedWithdrawalRouter.userWithdrawalsLength(eigenPodDepositor) == userWithdrawalsLength + 1, - "delayedWithdrawalRouter.userWithdrawalsLength not incremented" - ); - IDelayedWithdrawalRouter.DelayedWithdrawal memory delayedWithdrawal = delayedWithdrawalRouter - .userDelayedWithdrawalByIndex(eigenPodDepositor, userWithdrawalsLength); - require(delayedWithdrawal.amount == podBalanceBefore, "delayedWithdrawal.amount incorrect"); - require(delayedWithdrawal.blockCreated == block.number, "delayedWithdrawal.blockCreated incorrect"); + eigenPod.startCheckpoint(false); } - - // Existing LST depositor – ensure that strategy length and shares are all identical - // Existing LST depositor – ensure that an existing queued withdrawal remains queued - // Check from stored root, and recalculate root and make sure it matches - // Check that completing the withdrawal results in the same behavior (same transfer of ERC20 tokens) - // Check that staker nonce & numWithdrawalsQueued remains the same as before the upgrade - // Existing LST depositor – queuing a withdrawal before/after the upgrade has the same effects (same decrease in shares, resultant withdrawal root) - // Existing EigenPod owner – EigenPodManager.ownerToPod remains the same - // Existing EigenPod owner – EigenPodManager.hasPod remains the same - // Existing EigenPod owner – EigenPod.podOwner remains the same - // Existing EigenPod owner – EigenPod.mostRecentWithdrawalTimestamp (after upgrade) == EigenPod.mostRecentWithdrawalBlock (before upgrade) - // Existing EigenPod owner – EigenPod.hasRestaked remains false - // Can call EigenPod.activateRestaking and it correctly: - // Sends all funds in EigenPod (need to make sure it has nonzero balance beforehand) - // Sets `hasRestaked` to ‘true’ - // Emits a ‘RestakingActivated’ event - // EigenPod.mostRecentWithdrawalTimestamp updates correctly - // EigenPod: ethPOS, delayedWithdrawalRouter, eigenPodManager - event RestakingActivated(address indexed podOwner); } interface IDelegationManagerV0 { diff --git a/script/deploy/mainnet/M2_Mainnet_Upgrade.s.sol b/script/deploy/mainnet/M2_Mainnet_Upgrade.s.sol index daa042db5..c69bbe108 100644 --- a/script/deploy/mainnet/M2_Mainnet_Upgrade.s.sol +++ b/script/deploy/mainnet/M2_Mainnet_Upgrade.s.sol @@ -34,7 +34,7 @@ contract M2_Mainnet_Upgrade is ExistingDeploymentParser { // Sanity Checks _verifyContractPointers(); _verifyImplementations(); - _verifyContractsInitialized({isInitialDeployment: true}); + _verifyContractsInitialized(); _verifyInitializationParams(); logAndOutputContractAddresses("script/output/mainnet/M2_mainnet_upgrade.output.json"); @@ -64,9 +64,7 @@ contract M2_Mainnet_Upgrade is ExistingDeploymentParser { // 2. Deploy Implementations eigenPodImplementation = new EigenPod( IETHPOSDeposit(ETHPOSDepositAddress), - delayedWithdrawalRouter, eigenPodManager, - EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, EIGENPOD_GENESIS_TIME ); delegationManagerImplementation = new DelegationManager(strategyManager, slasher, eigenPodManager); @@ -79,7 +77,6 @@ contract M2_Mainnet_Upgrade is ExistingDeploymentParser { slasher, delegationManager ); - delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); } function _simulateUpgrade() internal { @@ -112,19 +109,12 @@ contract M2_Mainnet_Upgrade is ExistingDeploymentParser { TransparentUpgradeableProxy(payable(address(eigenPodManager))), address(eigenPodManagerImplementation) ); - // Delayed Withdrawal Router - eigenLayerProxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation) - ); // Second, configure additional settings and paused statuses delegationManager.setMinWithdrawalDelayBlocks(DELEGATION_MANAGER_MIN_WITHDRAWAL_DELAY_BLOCKS); delegationManager.unpause(0); eigenPodManager.unpause(0); - eigenPodManager.setDenebForkTimestamp(EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP); - eigenPodManager.updateBeaconChainOracle(beaconOracle); eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); vm.stopPrank(); @@ -174,15 +164,15 @@ contract Queue_M2_Upgrade is M2_Mainnet_Upgrade, TimelockEncoding { ) ); - txs[3] = Tx( - address(eigenLayerProxyAdmin), - 0, - abi.encodeWithSelector( - ProxyAdmin.upgrade.selector, - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - delayedWithdrawalRouterImplementation - ) - ); + // txs[3] = Tx( + // address(eigenLayerProxyAdmin), + // 0, + // abi.encodeWithSelector( + // ProxyAdmin.upgrade.selector, + // TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), + // delayedWithdrawalRouterImplementation + // ) + // ); txs[4] = Tx( address(eigenLayerProxyAdmin), @@ -211,18 +201,18 @@ contract Queue_M2_Upgrade is M2_Mainnet_Upgrade, TimelockEncoding { ); // set beacon chain oracle on EigenPodManager - txs[7] = Tx( - address(eigenPodManager), - 0, // value - abi.encodeWithSelector(EigenPodManager.updateBeaconChainOracle.selector, beaconOracle) - ); + // txs[7] = Tx( + // address(eigenPodManager), + // 0, // value + // abi.encodeWithSelector(EigenPodManager.updateBeaconChainOracle.selector, beaconOracle) + // ); // set Deneb fork timestamp on EigenPodManager - txs[8] = Tx( - address(eigenPodManager), - 0, // value - abi.encodeWithSelector(EigenPodManager.setDenebForkTimestamp.selector, EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP) - ); + // txs[8] = Tx( + // address(eigenPodManager), + // 0, // value + // abi.encodeWithSelector(EigenPodManager.setDenebForkTimestamp.selector, EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP) + // ); // unpause everything on DelegationManager txs[9] = Tx( @@ -288,7 +278,7 @@ contract Queue_M2_Upgrade is M2_Mainnet_Upgrade, TimelockEncoding { // Check correctness after upgrade _verifyContractPointers(); _verifyImplementations(); - _verifyContractsInitialized({isInitialDeployment: true}); + _verifyContractsInitialized(); _verifyInitializationParams(); _postUpgradeChecks(); } @@ -325,7 +315,7 @@ contract Queue_M2_Upgrade is M2_Mainnet_Upgrade, TimelockEncoding { bytes[] memory validatorFieldsProofs; bytes32[][] memory validatorFields; cheats.startPrank(existingEigenPod.podOwner()); - existingEigenPod.activateRestaking(); + existingEigenPod.startCheckpoint(false); cheats.expectRevert("EigenPodManager.getBlockRootAtTimestamp: state root at timestamp not yet finalized"); existingEigenPod.verifyWithdrawalCredentials( uint64(block.timestamp), diff --git a/script/deploy/mainnet/v0.3.0-mainnet-rewards.s.sol b/script/deploy/mainnet/v0.3.0-mainnet-rewards.s.sol index a91ff4873..1fe59bed4 100644 --- a/script/deploy/mainnet/v0.3.0-mainnet-rewards.s.sol +++ b/script/deploy/mainnet/v0.3.0-mainnet-rewards.s.sol @@ -36,7 +36,7 @@ contract MainnetRewardsCoordinatorDeploy is ExistingDeploymentParser { // Sanity Checks _verifyContractPointers(); _verifyImplementations(); - _verifyContractsInitialized({isInitialDeployment: true}); + _verifyContractsInitialized(); _verifyInitializationParams(); logAndOutputContractAddresses("script/output/mainnet/v0.3.0-mainnet-rewards.output.json"); diff --git a/script/output/goerli/GV2_deployment_2024_6_2.json b/script/output/goerli/GV2_deployment_2024_6_2.json deleted file mode 100644 index e68db2428..000000000 --- a/script/output/goerli/GV2_deployment_2024_6_2.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "addresses": { - "baseStrategyImplementation": "0x81E94e16949AC397d508B5C2557a272faD2F8ebA", - "delayedWithdrawalRouter": "0x89581561f1F98584F88b0d57c2180fb89225388f", - "delayedWithdrawalRouterImplementation": "0xE576731194EC3d8Ba92E7c2B578ea74238772878", - "delegation": "0x1b7b8F6b258f95Cf9596EabB9aa18B62940Eb0a8", - "delegationImplementation": "0x56652542926444Ebce46Fd97aFd80824ed51e58C", - "eigenLayerPauserReg": "0x7cB9c5D6b9702f2f680e4d35cb1fC945D08208F6", - "eigenLayerProxyAdmin": "0x28ceac2ff82B2E00166e46636e2A4818C29902e2", - "eigenPodBeacon": "0x3093F3B560352F896F0e9567019902C9Aff8C9a5", - "eigenPodImplementation": "0x16a0d8aD2A2b12f3f47d0e8F5929F9840e29a426", - "eigenPodManager": "0xa286b84C96aF280a49Fe1F40B9627C2A2827df41", - "eigenPodManagerImplementation": "0xDA9B60D3dC7adD40C0e35c628561Ff71C13a189f", - "emptyContract": "0xa04bf5170D86833294b5c21c712C69C0Fb5735A4", - "slasher": "0xD11d60b669Ecf7bE10329726043B3ac07B380C22", - "slasherImplementation": "0x89C5e6e98f79be658e830Ec66b61ED3EE910D262", - "strategyManager": "0x779d1b5315df083e3F9E94cB495983500bA8E907", - "strategyManagerImplementation": "0x506C21f43e81D9d231d8A13831b42A2a2B5540E4", - "avsDirectory": "0x0AC9694c271eFbA6059e9783769e515E8731f935", - "avsDirectoryImplementation": "0x871cD8f6CFec8b2EB1ac64d58F6D9e1D36a88cb3" - }, - "chainInfo": { - "chainId": 5, - "deploymentBlock": 10497389 - }, - "parameters": { - "executorMultisig": "0x3d9C2c2B40d890ad53E27947402e977155CD2808", - "operationsMultisig": "0x040353E9d057689b77DF275c07FFe1A46b98a4a6" - } -} \ No newline at end of file diff --git a/script/output/goerli/GV2_preprod_deployment_2024_30_1.json b/script/output/goerli/GV2_preprod_deployment_2024_30_1.json deleted file mode 100644 index f705e6f9f..000000000 --- a/script/output/goerli/GV2_preprod_deployment_2024_30_1.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "addresses": { - "baseStrategyImplementation": "0xA548BF0106108A0c14779F3f1d8981517b8fA9D0", - "delayedWithdrawalRouter": "0x9572e46797B7A07257314e587061dC46c4dfCE0E", - "delayedWithdrawalRouterImplementation": "0x44a40C60857b4B420Ad3D8b9646FefEBF2D0dB86", - "delegation": "0x45b4c4DAE69393f62e1d14C5fe375792DF4E6332", - "delegationImplementation": "0x934eB3E2b6D5C2E1601B29B7180026D71438F20D", - "eigenLayerPauserReg": "0x94A2679B6A87ADb4e0CabA8E3E40f463C6062DeC", - "eigenLayerProxyAdmin": "0x555573Ff2B3b2731e69eeBAfb40a4EEA7fBaC54A", - "eigenPodBeacon": "0x38cBD4e08eA1840B91dA42fE02B55Abc89083bFB", - "eigenPodImplementation": "0x83cbB48391F428878Bc5DD97C9792a8dbCAa0729", - "eigenPodManager": "0x33e42d539abFe9b387B27b0e467374Bbb76cf925", - "eigenPodManagerImplementation": "0xEEdCC9dB001fB8429721FE21426F51f0Cdd329EC", - "emptyContract": "0xb23633b2240D78502fA308B817C892b2d5778469", - "slasher": "0xF751E8C37ACd3AD5a35D5db03E57dB6F9AD0bDd0", - "slasherImplementation": "0x05c235183e8b9dFb7113Cf92bbDc3f5085324158", - "strategyManager": "0xD309ADd2B269d522112DcEe0dCf0b0f04a09C29e", - "strategyManagerImplementation": "0xb9B69504f1a727E783F4B4248A115D56F4080DF8", - "avsDirectory": "0x47eFB8e38656a805BC6B3b13FA331d34dcDeB374", - "avsDirectoryImplementation": "0x728111B10227F44E5e389e5650725948d1DCcE7A" - }, - "chainInfo": { - "chainId": 5, - "deploymentBlock": 10469472 - }, - "parameters": { - "executorMultisig": "0x27977e6E4426A525d055A587d2a0537b4cb376eA", - "operationsMultisig": "0x27977e6E4426A525d055A587d2a0537b4cb376eA" - } -} \ No newline at end of file diff --git a/script/output/goerli/M1_deployment_goerli_2023_3_23.json b/script/output/goerli/M1_deployment_goerli_2023_3_23.json deleted file mode 100644 index 11d0d1184..000000000 --- a/script/output/goerli/M1_deployment_goerli_2023_3_23.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "addresses": { - "baseStrategyImplementation": "0x2c836f44207A732bC951df98f0cAcE4704432B7E", - "delayedWithdrawalRouter": "0x89581561f1F98584F88b0d57c2180fb89225388f", - "delayedWithdrawalRouterImplementation": "0x6854c0eF4A8dF70a5E832cC3b3b4C5a500063837", - "delegation": "0x1b7b8F6b258f95Cf9596EabB9aa18B62940Eb0a8", - "delegationImplementation": "0xeBea7B291b6631806244Ed0E3d1E585e76BB37fb", - "eigenLayerPauserReg": "0x7cB9c5D6b9702f2f680e4d35cb1fC945D08208F6", - "eigenLayerProxyAdmin": "0x28ceac2ff82B2E00166e46636e2A4818C29902e2", - "eigenPodBeacon": "0x3093F3B560352F896F0e9567019902C9Aff8C9a5", - "eigenPodImplementation": "0x0062645382Af44593bA2E453F51604833277F371", - "eigenPodManager": "0xa286b84C96aF280a49Fe1F40B9627C2A2827df41", - "eigenPodManagerImplementation": "0xad46772384CFec11d140E255e6d240949A194f17", - "emptyContract": "0xa04bf5170D86833294b5c21c712C69C0Fb5735A4", - "slasher": "0xD11d60b669Ecf7bE10329726043B3ac07B380C22", - "slasherImplementation": "0x7dcbcb83f7e744ffa1a94f508419cee8279f469e", - "strategies": { - "WETH": "0x7CA911E83dabf90C90dD3De5411a10F1A6112184", - "rETH": "0x879944A8cB437a5f8061361f82A6d4EED59070b5", - "tsETH": "0xcFA9da720682bC4BCb55116675f16F503093ba13", - "wstETH": "0x13760F50a9d7377e4F20CB8CF9e4c26586c658ff", - "stETH": "0xB613E78E2068d7489bb66419fB1cfa11275d14da" - }, - "strategyManager": "0x779d1b5315df083e3F9E94cB495983500bA8E907", - "strategyManagerImplementation": "0xcf19a2e2d1d83994ad9c89807d4173519aef72a0" - }, - "chainInfo": { - "chainId": 5, - "deploymentBlock": 8705851 - }, - "parameters": { - "communityMultisig": "0x37bAFb55BC02056c5fD891DFa503ee84a97d89bF", - "operationsMultisig": "0x040353E9d057689b77DF275c07FFe1A46b98a4a6", - "executorMultisig": "0x3d9C2c2B40d890ad53E27947402e977155CD2808", - "timelock": "0xA7e72a0564ebf25Fa082Fc27020225edeAF1796E" - } -} \ No newline at end of file diff --git a/script/output/goerli/M2_deployment_data_goerli.json b/script/output/goerli/M2_deployment_data_goerli.json deleted file mode 100644 index 45acc38f2..000000000 --- a/script/output/goerli/M2_deployment_data_goerli.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "addresses": { - "delayedWithdrawalRouter": "0x89581561f1F98584F88b0d57c2180fb89225388f", - "delegation": "0x1b7b8F6b258f95Cf9596EabB9aa18B62940Eb0a8", - "delegationImplementation": "0x9b7980a32ceCe2Aa936DD2E43AF74af62581A99d", - "eigenPodBeacon": "0x3093F3B560352F896F0e9567019902C9Aff8C9a5", - "eigenPodImplementation": "0x86bf376E0C0c9c6D332E13422f35Aca75C106CcA", - "eigenPodManager": "0xa286b84C96aF280a49Fe1F40B9627C2A2827df41", - "eigenPodManagerImplementation": "0xdD09d95bD25299EDBF4f33d76F84dBc77b0B901b", - "ethPOS": "0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b", - "slasher": "0xD11d60b669Ecf7bE10329726043B3ac07B380C22", - "strategyManager": "0x779d1b5315df083e3F9E94cB495983500bA8E907", - "strategyManagerImplementation": "0x8676bb5f792ED407a237234Fe422aC6ed3540055" - }, - "chainInfo": { - "chainId": 5, - "deploymentBlock": 10002668 - } -} \ No newline at end of file diff --git a/script/output/goerli/M2_preprod_deployment_from_scratch.json b/script/output/goerli/M2_preprod_deployment_from_scratch.json deleted file mode 100644 index 0ac97a9e9..000000000 --- a/script/output/goerli/M2_preprod_deployment_from_scratch.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "addresses": { - "baseStrategyImplementation": "0xA548BF0106108A0c14779F3f1d8981517b8fA9D0", - "blsPublicKeyCompendium": "0x663F1f6A8E4417b9dB3117821068DAD862395aF0", - "delayedWithdrawalRouter": "0x9572e46797B7A07257314e587061dC46c4dfCE0E", - "delayedWithdrawalRouterImplementation": "0xaDd6b52E063bE5CdeF6450F28D9CA038bDAB9A49", - "delegation": "0x45b4c4DAE69393f62e1d14C5fe375792DF4E6332", - "delegationImplementation": "0x679cf51e303827c99e924bea05331101bF90B126", - "eigenLayerPauserReg": "0x94A2679B6A87ADb4e0CabA8E3E40f463C6062DeC", - "eigenLayerProxyAdmin": "0x555573Ff2B3b2731e69eeBAfb40a4EEA7fBaC54A", - "eigenPodBeacon": "0x38cBD4e08eA1840B91dA42fE02B55Abc89083bFB", - "eigenPodImplementation": "0x9CeE917f0f5d4123585A4B12906a8A65cFac1ac8", - "eigenPodManager": "0x33e42d539abFe9b387B27b0e467374Bbb76cf925", - "eigenPodManagerImplementation": "0x6A4855ab9a3924c8169f20a189272FFF3cd00b68", - "emptyContract": "0xb23633b2240D78502fA308B817C892b2d5778469", - "slasher": "0xF751E8C37ACd3AD5a35D5db03E57dB6F9AD0bDd0", - "slasherImplementation": "0xa02171440AfD8d5f09BaAB74Cd48b1401C47F2f9", - "strategies": { - "Liquid staked Ether 2.0": "0xed6DE3f2916d20Cb427fe7255194a05061319FFB", - "Rocket Pool ETH": "0xd421b2a340497545dA68AE53089d99b9Fe0493cD" - }, - "strategyManager": "0xD309ADd2B269d522112DcEe0dCf0b0f04a09C29e", - "strategyManagerImplementation": "0xC10133A329A210f8DEbf597C8eF5907c95D673e9" - }, - "chainInfo": { - "chainId": 5, - "deploymentBlock": 9729808 - }, - "parameters": { - "executorMultisig": "0x27977e6E4426A525d055A587d2a0537b4cb376eA", - "operationsMultisig": "0x27977e6E4426A525d055A587d2a0537b4cb376eA" - } - } \ No newline at end of file diff --git a/script/output/goerli/deployment_output.json b/script/output/goerli/deployment_output.json deleted file mode 100644 index 9f362dbd1..000000000 --- a/script/output/goerli/deployment_output.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "addresses": { - "ERC20Mock": "0x7ad75e99869026FE521f34d1239AD633463bA520", - "ERC20MockStrategy": "0x3FF9067f06c7833560d2d669fa58D6b1b788EcF0", - "ERC20MockStrategyImplementation": "0xE0411693E86760840B6Ee90004b0C248ab5c9631", - "delayedWithdrawalRouter": "0x91BbcEd2DB7778c569Fbab34A3957f5ded92bb2d", - "delayedWithdrawalRouterImplementation": "0x007F25A938173F0995daB8e7806aC8b6EbfB7808", - "delegation": "0x1b0870C6a7472ED9Da774b4Ca0Fe1b5fd6B6D61E", - "delegationImplementation": "0x9cCb6f6BC4e7641Cd6d5E7BD7e97f55D9914AaAb", - "eigenLayerPauserReg": "0x18E5227d0E8D8053579d5c1eD6bbd7DD55139454", - "eigenLayerProxyAdmin": "0x81048ca94171C7B97ff0fE590eF67f4B442eD548", - "eigenPodBeacon": "0x4BE52ac49121421A9AF33c476f7f6511Fbf4fCc7", - "eigenPodImplementation": "0xeb873028bA8d079768F11C71b05564D1590238A5", - "eigenPodManager": "0x83622B4e84Daadd0AF1382caE2F8Aa2C67839D9e", - "eigenPodManagerImplementation": "0x009030ab40Db41F9D9336DfED1698D8FFeB6a604", - "emptyContract": "0xbeC65eD486c151202EF673A456e6d8e446726Df6", - "slasher": "0x5B617a19d39Ed8c0754fA31Ef86e6c398Ba1a24E", - "slasherImplementation": "0x8122eD67A26D835349438286FBd0A9cbA6841332", - "strategyManager": "0x5d55B8fDC847c1DF56d1dDd8E278424124199EC3", - "strategyManagerImplementation": "0xC69229bf9E6bb82FfB31fA2fdcEF5431b3a81453" - }, - "chainInfo": { - "chainId": 5, - "deploymentBlock": 9548171 - }, - "parameters": { - "alphaMultisig": "0x95C7A3F90e80329C97A6493142Ab7923E15b8083" - } -} \ No newline at end of file diff --git a/script/output/holesky/v040-rc0.output.json b/script/output/holesky/v040-rc0.output.json new file mode 100644 index 000000000..a43d651b2 --- /dev/null +++ b/script/output/holesky/v040-rc0.output.json @@ -0,0 +1,34 @@ +{ + "addresses": { + "avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC", + "avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A", + "baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40", + "delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC", + "delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1", + "eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1", + "eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B", + "eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC", + "eigenPodImplementation": "0x537A9Ce71928C9377823ef72C7F898b8d092f520", + "eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff", + "eigenPodManagerImplementation": "0x378C459ea6F026D8BF045404d2f3e3451682c6a2", + "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", + "rewardsCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0", + "rewardsCoordinatorImplementation": "0x7C80B0d3aFBeF9Bbd03Aab72cD2d90a12c11D394", + "slasher": "0x12699471dF8dca329C76D72823B1b79d55709384", + "slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0", + "strategies": "", + "strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a", + "strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199" + }, + "chainInfo": { + "chainId": 17000, + "deploymentBlock": 1805992 + }, + "parameters": { + "communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + } +} \ No newline at end of file diff --git a/script/output/holesky/v040-rc1.output.json b/script/output/holesky/v040-rc1.output.json new file mode 100644 index 000000000..283b214ab --- /dev/null +++ b/script/output/holesky/v040-rc1.output.json @@ -0,0 +1,34 @@ +{ + "addresses": { + "avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC", + "avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A", + "baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40", + "delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC", + "delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1", + "eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1", + "eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B", + "eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC", + "eigenPodImplementation": "0xcd327c3f4C866dA3F3F83218ebA7c478567E7a9E", + "eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff", + "eigenPodManagerImplementation": "0x378C459ea6F026D8BF045404d2f3e3451682c6a2", + "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", + "rewardsCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0", + "rewardsCoordinatorImplementation": "0x7C80B0d3aFBeF9Bbd03Aab72cD2d90a12c11D394", + "slasher": "0x12699471dF8dca329C76D72823B1b79d55709384", + "slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0", + "strategies": "", + "strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a", + "strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199" + }, + "chainInfo": { + "chainId": 17000, + "deploymentBlock": 1851043 + }, + "parameters": { + "communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + } +} \ No newline at end of file diff --git a/script/output/holesky/v040-rc2.output.json b/script/output/holesky/v040-rc2.output.json new file mode 100644 index 000000000..1aa28e587 --- /dev/null +++ b/script/output/holesky/v040-rc2.output.json @@ -0,0 +1,34 @@ +{ + "addresses": { + "avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC", + "avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A", + "baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40", + "delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC", + "delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1", + "eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1", + "eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B", + "eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC", + "eigenPodImplementation": "0xd4bbD235e25B44856927aD845611808040EfAb1c", + "eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff", + "eigenPodManagerImplementation": "0x378C459ea6F026D8BF045404d2f3e3451682c6a2", + "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", + "rewardsCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0", + "rewardsCoordinatorImplementation": "0x7C80B0d3aFBeF9Bbd03Aab72cD2d90a12c11D394", + "slasher": "0x12699471dF8dca329C76D72823B1b79d55709384", + "slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0", + "strategies": "", + "strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a", + "strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199" + }, + "chainInfo": { + "chainId": 17000, + "deploymentBlock": 1851632 + }, + "parameters": { + "communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + } +} \ No newline at end of file diff --git a/script/output/holesky/v040-rc3.output.json b/script/output/holesky/v040-rc3.output.json new file mode 100644 index 000000000..a57217440 --- /dev/null +++ b/script/output/holesky/v040-rc3.output.json @@ -0,0 +1,34 @@ +{ + "addresses": { + "avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC", + "avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A", + "baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40", + "delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC", + "delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1", + "eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1", + "eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B", + "eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC", + "eigenPodImplementation": "0x703de9e45801a93bB1Da6DF0865e6B178c438daE", + "eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff", + "eigenPodManagerImplementation": "0x378C459ea6F026D8BF045404d2f3e3451682c6a2", + "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", + "rewardsCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0", + "rewardsCoordinatorImplementation": "0x7C80B0d3aFBeF9Bbd03Aab72cD2d90a12c11D394", + "slasher": "0x12699471dF8dca329C76D72823B1b79d55709384", + "slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0", + "strategies": "", + "strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a", + "strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199" + }, + "chainInfo": { + "chainId": 17000, + "deploymentBlock": 1987496 + }, + "parameters": { + "communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + } +} \ No newline at end of file diff --git a/script/output/holesky/v040-rc4.output.json b/script/output/holesky/v040-rc4.output.json new file mode 100644 index 000000000..2ebaf0c24 --- /dev/null +++ b/script/output/holesky/v040-rc4.output.json @@ -0,0 +1,34 @@ +{ + "addresses": { + "avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC", + "avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A", + "baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40", + "delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC", + "delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1", + "eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1", + "eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B", + "eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC", + "eigenPodImplementation": "0xcB0858aA14d27FE8D255CF0Fa0b8e8977785169a", + "eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff", + "eigenPodManagerImplementation": "0xE59f0a991600788E2bc08c31817124be00520F48", + "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", + "rewardsCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0", + "rewardsCoordinatorImplementation": "0x7C80B0d3aFBeF9Bbd03Aab72cD2d90a12c11D394", + "slasher": "0x12699471dF8dca329C76D72823B1b79d55709384", + "slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0", + "strategies": "", + "strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a", + "strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199" + }, + "chainInfo": { + "chainId": 17000, + "deploymentBlock": 2027960 + }, + "parameters": { + "communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + } +} \ No newline at end of file diff --git a/script/output/holesky/v040-rc5.output.json b/script/output/holesky/v040-rc5.output.json new file mode 100644 index 000000000..22835e972 --- /dev/null +++ b/script/output/holesky/v040-rc5.output.json @@ -0,0 +1,34 @@ +{ + "addresses": { + "avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC", + "avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A", + "baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40", + "delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC", + "delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1", + "eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1", + "eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B", + "eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC", + "eigenPodImplementation": "0x8Da4b953cbFb715624D98C0D2b4a7978462eFd38", + "eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff", + "eigenPodManagerImplementation": "0x10EBa780CCd9E5e9FFBe529C25046c076Be91048", + "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", + "rewardsCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0", + "rewardsCoordinatorImplementation": "0x7C80B0d3aFBeF9Bbd03Aab72cD2d90a12c11D394", + "slasher": "0x12699471dF8dca329C76D72823B1b79d55709384", + "slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0", + "strategies": "", + "strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a", + "strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199" + }, + "chainInfo": { + "chainId": 17000, + "deploymentBlock": 2100862 + }, + "parameters": { + "communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + } +} \ No newline at end of file diff --git a/script/output/holesky/v040.output.json b/script/output/holesky/v040.output.json new file mode 100644 index 000000000..47a20c740 --- /dev/null +++ b/script/output/holesky/v040.output.json @@ -0,0 +1,34 @@ +{ + "addresses": { + "avsDirectory": "0x055733000064333CaDDbC92763c58BF0192fFeBf", + "avsDirectoryImplementation": "0xEF5BA995Bc7722fd1e163edF8Dc09375de3d3e3a", + "baseStrategyImplementation": "0xFb83e1D133D0157775eC4F19Ff81478Df1103305", + "delegationManager": "0xA44151489861Fe9e3055d95adC98FbD462B948e7", + "delegationManagerImplementation": "0x83f8F8f0BB125F7870F6bfCf76853f874C330D76", + "eigenLayerPauserReg": "0x85Ef7299F8311B25642679edBF02B62FA2212F06", + "eigenLayerProxyAdmin": "0xDB023566064246399b4AE851197a97729C93A6cf", + "eigenPodBeacon": "0x7261C2bd75a7ACE1762f6d7FAe8F63215581832D", + "eigenPodImplementation": "0x10ad7e30e3F52076C8462D573530f4461377319c", + "eigenPodManager": "0x30770d7E3e71112d7A6b7259542D1f680a70e315", + "eigenPodManagerImplementation": "0x91A6525a4a843F5a5B633905300c33F79413CCc5", + "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", + "rewardsCoordinator": "0xAcc1fb458a1317E886dB376Fc8141540537E68fE", + "rewardsCoordinatorImplementation": "0xe54625095656206AC1B42819875343453c447f97", + "slasher": "0xcAe751b75833ef09627549868A04E32679386e7C", + "slasherImplementation": "0x99715D255E34a39bE9943b82F281CA734bcF345A", + "strategies": "", + "strategyManager": "0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6", + "strategyManagerImplementation": "0x59f766A603C53f3AC8Be43bBe158c1519b193a18" + }, + "chainInfo": { + "chainId": 17000, + "deploymentBlock": 2101150 + }, + "parameters": { + "communityMultisig": "0xCb8d2f9e55Bc7B1FA9d089f9aC80C583D2BDD5F7", + "executorMultisig": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348", + "operationsMultisig": "0xfaEF7338b7490b9E272d80A1a39f4657cAf2b97d", + "pauserMultisig": "0x53410249ec7d3a3F9F1ba3912D50D6A3Df6d10A7", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + } +} \ No newline at end of file diff --git a/script/utils/ExistingDeploymentParser.sol b/script/utils/ExistingDeploymentParser.sol index a16bde6af..cef8880b9 100644 --- a/script/utils/ExistingDeploymentParser.sol +++ b/script/utils/ExistingDeploymentParser.sol @@ -18,7 +18,6 @@ import "../../src/contracts/strategies/EigenStrategy.sol"; import "../../src/contracts/pods/EigenPod.sol"; import "../../src/contracts/pods/EigenPodManager.sol"; -import "../../src/contracts/pods/DelayedWithdrawalRouter.sol"; import "../../src/contracts/permissions/PauserRegistry.sol"; @@ -58,9 +57,6 @@ contract ExistingDeploymentParser is Script, Test { RewardsCoordinator public rewardsCoordinatorImplementation; EigenPodManager public eigenPodManager; EigenPodManager public eigenPodManagerImplementation; - DelayedWithdrawalRouter public delayedWithdrawalRouter; - DelayedWithdrawalRouter public delayedWithdrawalRouterImplementation; - IBeaconChainOracle beaconOracle; UpgradeableBeacon public eigenPodBeacon; EigenPod public eigenPodImplementation; StrategyBase public baseStrategyImplementation; @@ -122,15 +118,10 @@ contract ExistingDeploymentParser is Script, Test { uint32 REWARDS_COORDINATOR_GLOBAL_OPERATOR_COMMISSION_BIPS; // EigenPodManager uint256 EIGENPOD_MANAGER_INIT_PAUSED_STATUS; - uint64 EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP; // EigenPod uint64 EIGENPOD_GENESIS_TIME; uint64 EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; address ETHPOSDepositAddress; - uint256 DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS; - - // one week in blocks -- 50400 - uint32 DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS; // Strategy Deployment uint256 STRATEGY_MAX_PER_DEPOSIT; @@ -190,13 +181,6 @@ contract ExistingDeploymentParser is Script, Test { eigenPodManagerImplementation = EigenPodManager( stdJson.readAddress(existingDeploymentData, ".addresses.eigenPodManagerImplementation") ); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - stdJson.readAddress(existingDeploymentData, ".addresses.delayedWithdrawalRouter") - ); - delayedWithdrawalRouterImplementation = DelayedWithdrawalRouter( - stdJson.readAddress(existingDeploymentData, ".addresses.delayedWithdrawalRouterImplementation") - ); - beaconOracle = IBeaconChainOracle(stdJson.readAddress(existingDeploymentData, ".addresses.beaconOracle")); eigenPodBeacon = UpgradeableBeacon(stdJson.readAddress(existingDeploymentData, ".addresses.eigenPodBeacon")); eigenPodImplementation = EigenPod( payable(stdJson.readAddress(existingDeploymentData, ".addresses.eigenPodImplementation")) @@ -262,9 +246,6 @@ contract ExistingDeploymentParser is Script, Test { uint256 configChainId = stdJson.readUint(initialDeploymentData, ".chainInfo.chainId"); require(configChainId == currentChainId, "You are on the wrong chain for this config"); - // read beacon oracle - beaconOracle = IBeaconChainOracle(stdJson.readAddress(initialDeploymentData, ".beaconOracleAddress")); - // read all of the deployed addresses executorMultisig = stdJson.readAddress(initialDeploymentData, ".multisig_addresses.executorMultisig"); operationsMultisig = stdJson.readAddress(initialDeploymentData, ".multisig_addresses.operationsMultisig"); @@ -333,26 +314,12 @@ contract ExistingDeploymentParser is Script, Test { initialDeploymentData, ".eigenPodManager.init_paused_status" ); - EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP = uint64( - stdJson.readUint(initialDeploymentData, ".eigenPodManager.deneb_fork_timestamp") - ); - // EigenPod EIGENPOD_GENESIS_TIME = uint64(stdJson.readUint(initialDeploymentData, ".eigenPod.GENESIS_TIME")); EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = uint64( stdJson.readUint(initialDeploymentData, ".eigenPod.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR") ); ETHPOSDepositAddress = stdJson.readAddress(initialDeploymentData, ".ethPOSDepositAddress"); - // DelayedWithdrawalRouter - DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS = stdJson.readUint( - initialDeploymentData, - ".delayedWithdrawalRouter.init_paused_status" - ); - - // both set to one week in blocks 50400 - DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS = uint32( - stdJson.readUint(initialDeploymentData, ".delayedWithdrawalRouter.init_withdrawalDelayBlocks") - ); logInitialDeploymentParams(); } @@ -411,11 +378,6 @@ contract ExistingDeploymentParser is Script, Test { eigenPodManager.delegationManager() == delegationManager, "eigenPodManager: delegationManager contract address not set correctly" ); - // DelayedWithdrawalRouter - require( - delayedWithdrawalRouter.eigenPodManager() == eigenPodManager, - "delayedWithdrawalRouterContract: eigenPodManager address not set correctly" - ); } /// @notice verify implementations for Transparent Upgradeable Proxies @@ -454,12 +416,6 @@ contract ExistingDeploymentParser is Script, Test { ) == address(eigenPodManagerImplementation), "eigenPodManager: implementation set incorrectly" ); - require( - eigenLayerProxyAdmin.getProxyImplementation( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))) - ) == address(delayedWithdrawalRouterImplementation), - "delayedWithdrawalRouter: implementation set incorrectly" - ); for (uint256 i = 0; i < deployedStrategyArray.length; ++i) { require( @@ -479,9 +435,8 @@ contract ExistingDeploymentParser is Script, Test { /** * @notice Verify initialization of Transparent Upgradeable Proxies. Also check * initialization params if this is the first deployment. - * @param isInitialDeployment True if this is the first deployment of contracts from scratch */ - function _verifyContractsInitialized(bool isInitialDeployment) internal virtual { + function _verifyContractsInitialized() internal virtual { // AVSDirectory vm.expectRevert(bytes("Initializable: contract is already initialized")); avsDirectory.initialize(address(0), eigenLayerPauserReg, AVS_DIRECTORY_INIT_PAUSED_STATUS); @@ -512,14 +467,10 @@ contract ExistingDeploymentParser is Script, Test { strategyManager.initialize(address(0), address(0), eigenLayerPauserReg, STRATEGY_MANAGER_INIT_PAUSED_STATUS); // EigenPodManager vm.expectRevert(bytes("Initializable: contract is already initialized")); - eigenPodManager.initialize(beaconOracle, address(0), eigenLayerPauserReg, EIGENPOD_MANAGER_INIT_PAUSED_STATUS); - // DelayedWithdrawalRouter - vm.expectRevert(bytes("Initializable: contract is already initialized")); - delayedWithdrawalRouter.initialize( + eigenPodManager.initialize( address(0), eigenLayerPauserReg, - DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS, - DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS + EIGENPOD_MANAGER_INIT_PAUSED_STATUS ); // Strategies for (uint256 i = 0; i < deployedStrategyArray.length; ++i) { @@ -550,10 +501,10 @@ contract ExistingDeploymentParser is Script, Test { rewardsCoordinator.pauserRegistry() == eigenLayerPauserReg, "rewardsCoordinator: pauser registry not set correctly" ); - require( - rewardsCoordinator.owner() == executorMultisig, - "rewardsCoordinator: owner not set correctly" - ); + // require( + // rewardsCoordinator.owner() == executorMultisig, + // "rewardsCoordinator: owner not set correctly" + // ); require( rewardsCoordinator.paused() == REWARDS_COORDINATOR_INIT_PAUSED_STATUS, "rewardsCoordinator: init paused status set incorrectly" @@ -574,10 +525,10 @@ contract ExistingDeploymentParser is Script, Test { rewardsCoordinator.GENESIS_REWARDS_TIMESTAMP() == REWARDS_COORDINATOR_GENESIS_REWARDS_TIMESTAMP, "rewardsCoordinator: genesisRewardsTimestamp not set correctly" ); - require( - rewardsCoordinator.rewardsUpdater() == REWARDS_COORDINATOR_UPDATER, - "rewardsCoordinator: rewardsUpdater not set correctly" - ); + // require( + // rewardsCoordinator.rewardsUpdater() == REWARDS_COORDINATOR_UPDATER, + // "rewardsCoordinator: rewardsUpdater not set correctly" + // ); require( rewardsCoordinator.activationDelay() == REWARDS_COORDINATOR_ACTIVATION_DELAY, "rewardsCoordinator: activationDelay not set correctly" @@ -621,10 +572,10 @@ contract ExistingDeploymentParser is Script, Test { ); } else if (block.chainid == 17000) { // On holesky, for ease of whitelisting we set to executorMultisig - require( - strategyManager.strategyWhitelister() == executorMultisig, - "strategyManager: strategyWhitelister not set correctly" - ); + // require( + // strategyManager.strategyWhitelister() == executorMultisig, + // "strategyManager: strategyWhitelister not set correctly" + // ); } // EigenPodManager require( @@ -636,14 +587,6 @@ contract ExistingDeploymentParser is Script, Test { eigenPodManager.paused() == EIGENPOD_MANAGER_INIT_PAUSED_STATUS, "eigenPodManager: init paused status set incorrectly" ); - require( - eigenPodManager.denebForkTimestamp() == EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP, - "eigenPodManager: denebForkTimestamp not set correctly" - ); - require( - eigenPodManager.beaconChainOracle() == beaconOracle, - "eigenPodManager: beaconChainOracle not set correctly" - ); require( eigenPodManager.ethPOS() == IETHPOSDeposit(ETHPOSDepositAddress), "eigenPodManager: ethPOS not set correctly" @@ -655,33 +598,10 @@ contract ExistingDeploymentParser is Script, Test { eigenPodImplementation.GENESIS_TIME() == EIGENPOD_GENESIS_TIME, "eigenPodImplementation: GENESIS TIME not set correctly" ); - require( - eigenPodImplementation.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() == - EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR && - EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR % 1 gwei == 0, - "eigenPodImplementation: MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR not set correctly" - ); require( eigenPodImplementation.ethPOS() == IETHPOSDeposit(ETHPOSDepositAddress), "eigenPodImplementation: ethPOS not set correctly" ); - // DelayedWithdrawalRouter - require( - delayedWithdrawalRouter.pauserRegistry() == eigenLayerPauserReg, - "delayedWithdrawalRouter: pauser registry not set correctly" - ); - require( - delayedWithdrawalRouter.owner() == executorMultisig, - "delayedWithdrawalRouter: owner not set correctly" - ); - require( - delayedWithdrawalRouter.paused() == DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS, - "delayedWithdrawalRouter: init paused status set incorrectly" - ); - require( - delayedWithdrawalRouter.withdrawalDelayBlocks() == DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS, - "delayedWithdrawalRouter: withdrawalDelayBlocks not set correctly" - ); // Strategies for (uint256 i = 0; i < deployedStrategyArray.length; ++i) { require( @@ -725,21 +645,12 @@ contract ExistingDeploymentParser is Script, Test { emit log_named_uint("REWARDS_COORDINATOR_INIT_PAUSED_STATUS", REWARDS_COORDINATOR_INIT_PAUSED_STATUS); // todo log all rewards coordinator params emit log_named_uint("EIGENPOD_MANAGER_INIT_PAUSED_STATUS", EIGENPOD_MANAGER_INIT_PAUSED_STATUS); - emit log_named_uint("EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP", EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP); emit log_named_uint("EIGENPOD_GENESIS_TIME", EIGENPOD_GENESIS_TIME); emit log_named_uint( "EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR", EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR ); emit log_named_address("ETHPOSDepositAddress", ETHPOSDepositAddress); - emit log_named_uint( - "DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS", - DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS - ); - emit log_named_uint( - "DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS", - DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS - ); emit log_string("==== Strategies to Deploy ===="); for (uint256 i = 0; i < numStrategiesToDeploy; ++i) { @@ -807,13 +718,6 @@ contract ExistingDeploymentParser is Script, Test { "eigenPodManagerImplementation", address(eigenPodManagerImplementation) ); - vm.serializeAddress(deployed_addresses, "delayedWithdrawalRouter", address(delayedWithdrawalRouter)); - vm.serializeAddress( - deployed_addresses, - "delayedWithdrawalRouterImplementation", - address(delayedWithdrawalRouterImplementation) - ); - vm.serializeAddress(deployed_addresses, "beaconOracle", address(beaconOracle)); vm.serializeAddress(deployed_addresses, "eigenPodBeacon", address(eigenPodBeacon)); vm.serializeAddress(deployed_addresses, "eigenPodImplementation", address(eigenPodImplementation)); vm.serializeAddress(deployed_addresses, "baseStrategyImplementation", address(baseStrategyImplementation)); diff --git a/src/contracts/interfaces/IBeaconChainOracle.sol b/src/contracts/interfaces/IBeaconChainOracle.sol deleted file mode 100644 index 5f1afabdc..000000000 --- a/src/contracts/interfaces/IBeaconChainOracle.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -/** - * @title Interface for the BeaconStateOracle contract. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - */ -interface IBeaconChainOracle { - /// @notice The block number to state root mapping. - function timestampToBlockRoot(uint256 timestamp) external view returns (bytes32); -} diff --git a/src/contracts/interfaces/IDelayedWithdrawalRouter.sol b/src/contracts/interfaces/IDelayedWithdrawalRouter.sol deleted file mode 100644 index 81400ddab..000000000 --- a/src/contracts/interfaces/IDelayedWithdrawalRouter.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -interface IDelayedWithdrawalRouter { - // struct used to pack data into a single storage slot - struct DelayedWithdrawal { - uint224 amount; - uint32 blockCreated; - } - - // struct used to store a single users delayedWithdrawal data - struct UserDelayedWithdrawals { - uint256 delayedWithdrawalsCompleted; - DelayedWithdrawal[] delayedWithdrawals; - } - - /// @notice event for delayedWithdrawal creation - event DelayedWithdrawalCreated(address podOwner, address recipient, uint256 amount, uint256 index); - - /// @notice event for the claiming of delayedWithdrawals - event DelayedWithdrawalsClaimed(address recipient, uint256 amountClaimed, uint256 delayedWithdrawalsCompleted); - - /// @notice Emitted when the `withdrawalDelayBlocks` variable is modified from `previousValue` to `newValue`. - event WithdrawalDelayBlocksSet(uint256 previousValue, uint256 newValue); - - /** - * @notice Creates an delayed withdrawal for `msg.value` to the `recipient`. - * @dev Only callable by the `podOwner`'s EigenPod contract. - */ - function createDelayedWithdrawal(address podOwner, address recipient) external payable; - - /** - * @notice Called in order to withdraw delayed withdrawals made to the `recipient` that have passed the `withdrawalDelayBlocks` period. - * @param recipient The address to claim delayedWithdrawals for. - * @param maxNumberOfWithdrawalsToClaim Used to limit the maximum number of withdrawals to loop through claiming. - */ - function claimDelayedWithdrawals(address recipient, uint256 maxNumberOfWithdrawalsToClaim) external; - - /** - * @notice Called in order to withdraw delayed withdrawals made to the caller that have passed the `withdrawalDelayBlocks` period. - * @param maxNumberOfWithdrawalsToClaim Used to limit the maximum number of withdrawals to loop through claiming. - */ - function claimDelayedWithdrawals(uint256 maxNumberOfWithdrawalsToClaim) external; - - /// @notice Owner-only function for modifying the value of the `withdrawalDelayBlocks` variable. - function setWithdrawalDelayBlocks(uint256 newValue) external; - - /// @notice Getter function for the mapping `_userWithdrawals` - function userWithdrawals(address user) external view returns (UserDelayedWithdrawals memory); - - /// @notice Getter function to get all delayedWithdrawals of the `user` - function getUserDelayedWithdrawals(address user) external view returns (DelayedWithdrawal[] memory); - - /// @notice Getter function to get all delayedWithdrawals that are currently claimable by the `user` - function getClaimableUserDelayedWithdrawals(address user) external view returns (DelayedWithdrawal[] memory); - - /// @notice Getter function for fetching the delayedWithdrawal at the `index`th entry from the `_userWithdrawals[user].delayedWithdrawals` array - function userDelayedWithdrawalByIndex( - address user, - uint256 index - ) external view returns (DelayedWithdrawal memory); - - /// @notice Getter function for fetching the length of the delayedWithdrawals array of a specific user - function userWithdrawalsLength(address user) external view returns (uint256); - - /// @notice Convenience function for checking whether or not the delayedWithdrawal at the `index`th entry from the `_userWithdrawals[user].delayedWithdrawals` array is currently claimable - function canClaimDelayedWithdrawal(address user, uint256 index) external view returns (bool); - - /** - * @notice Delay enforced by this contract for completing any delayedWithdrawal. 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 withdrawalDelayBlocks() external view returns (uint256); -} diff --git a/src/contracts/interfaces/IEigenPod.sol b/src/contracts/interfaces/IEigenPod.sol index 511f3b82e..be96da52c 100644 --- a/src/contracts/interfaces/IEigenPod.sol +++ b/src/contracts/interfaces/IEigenPod.sol @@ -9,17 +9,15 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; * @title The implementation contract used for restaking beacon chain ETH on EigenLayer * @author Layr Labs, Inc. * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice The main functionalities are: - * - creating new ETH validators with their withdrawal credentials pointed to this contract - * - proving from beacon chain state roots that withdrawal credentials are pointed to this contract - * - proving from beacon chain state roots the balances of ETH validators with their withdrawal credentials - * pointed to this contract - * - updating aggregate balances in the EigenPodManager - * - withdrawing eth when withdrawals are initiated * @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 { + /** + * + * STRUCTS / ENUMS + * + */ enum VALIDATOR_STATUS { INACTIVE, // doesnt exist ACTIVE, // staked on ethpos and withdrawal credentials are pointed to the EigenPod @@ -33,31 +31,30 @@ interface IEigenPod { // amount of beacon chain ETH restaked on EigenLayer in gwei uint64 restakedBalanceGwei; //timestamp of the validator's most recent balance update - uint64 mostRecentBalanceUpdateTimestamp; + uint64 lastCheckpointedAt; // status of the validator VALIDATOR_STATUS status; } - /** - * @notice struct used to store amounts related to proven withdrawals in memory. Used to help - * manage stack depth and optimize the number of external calls, when batching withdrawal operations. - */ - struct VerifiedWithdrawal { - // amount to send to a podOwner from a proven withdrawal - uint256 amountToSendGwei; - // difference in shares to be recorded in the eigenPodManager, as a result of the withdrawal - int256 sharesDeltaGwei; + struct Checkpoint { + bytes32 beaconBlockRoot; + uint24 proofsRemaining; + uint64 podBalanceGwei; + int128 balanceDeltasGwei; } - enum PARTIAL_WITHDRAWAL_CLAIM_STATUS { - REDEEMED, - PENDING, - FAILED - } + /** + * + * EVENTS + * + */ /// @notice Emitted when an ETH validator stakes via this eigenPod event EigenPodStaked(bytes pubkey); + /// @notice Emitted when a pod owner updates the proof submitter address + event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter); + /// @notice Emitted when an ETH validator's withdrawal credentials are successfully verified to be pointed to this eigenPod event ValidatorRestaked(uint40 validatorIndex); @@ -65,36 +62,31 @@ interface IEigenPod { // is the validator's balance that is credited on EigenLayer. event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei); - /// @notice Emitted when an ETH validator is prove to have withdrawn from the beacon chain - event FullWithdrawalRedeemed( - uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 withdrawalAmountGwei - ); - - /// @notice Emitted when a partial withdrawal claim is successfully redeemed - event PartialWithdrawalRedeemed( - uint40 validatorIndex, uint64 withdrawalTimestamp, address indexed recipient, uint64 partialWithdrawalAmountGwei - ); - /// @notice Emitted when restaked beacon chain ETH is withdrawn from the eigenPod. event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount); - /// @notice Emitted when podOwner enables restaking - event RestakingActivated(address indexed podOwner); - /// @notice Emitted when ETH is received via the `receive` fallback event NonBeaconChainETHReceived(uint256 amountReceived); - /// @notice Emitted when ETH that was previously received via the `receive` fallback is withdrawn - event NonBeaconChainETHWithdrawn(address indexed recipient, uint256 amountWithdrawn); + /// @notice Emitted when a checkpoint is created + event CheckpointCreated( + uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount + ); - /// @notice The max amount of eth, in gwei, that can be restaked per validator - function MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() external view returns (uint64); + /// @notice Emitted when a checkpoint is finalized + event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei); - /// @notice the amount of execution layer ETH in this contract that is staked in EigenLayer (i.e. withdrawn from beaconchain but not EigenLayer), - function withdrawableRestakedExecutionLayerGwei() external view returns (uint64); + /// @notice Emitted when a validator is proven for a given checkpoint + event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex); + + /// @notice Emitted when a validaor is proven to have 0 balance at a given checkpoint + event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex); - /// @notice any ETH deposited into the EigenPod contract via the `receive` fallback function - function nonBeaconChainETHBalanceWei() external view returns (uint256); + /** + * + * EXTERNAL STATE-CHANGING METHODS + * + */ /// @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; @@ -111,104 +103,183 @@ interface IEigenPod { */ function withdrawRestakedBeaconChainETH(address recipient, uint256 amount) external; - /// @notice The single EigenPodManager for EigenLayer - function eigenPodManager() external view returns (IEigenPodManager); - - /// @notice The owner of this EigenPod - function podOwner() external view returns (address); - - /// @notice an indicator of whether or not the podOwner has ever "fully restaked" by successfully calling `verifyCorrectWithdrawalCredentials`. - function hasRestaked() external view returns (bool); - /** - * @notice The latest timestamp at which the pod owner withdrew the balance of the pod, via calling `withdrawBeforeRestaking`. - * @dev This variable is only updated when the `withdrawBeforeRestaking` function is called, which can only occur before `hasRestaked` is set to true for this pod. - * Proofs for this pod are only valid against Beacon Chain state roots corresponding to timestamps after the stored `mostRecentWithdrawalTimestamp`. + * @dev Create a checkpoint used to prove this pod's active validator set. Checkpoints are completed + * by submitting one checkpoint proof per ACTIVE validator. During the checkpoint process, the total + * change in ACTIVE validator balance is tracked, and any validators with 0 balance are marked `WITHDRAWN`. + * @dev Once finalized, the pod owner is awarded shares corresponding to: + * - the total change in their ACTIVE validator balances + * - any ETH in the pod not already awarded shares + * @dev A checkpoint cannot be created if the pod already has an outstanding checkpoint. If + * this is the case, the pod owner MUST complete the existing checkpoint before starting a new one. + * @param revertIfNoBalance Forces a revert if the pod ETH balance is 0. This allows the pod owner + * to prevent accidentally starting a checkpoint that will not increase their shares */ - function mostRecentWithdrawalTimestamp() external view returns (uint64); - - /// @notice Returns the validatorInfo struct for the provided pubkeyHash - function validatorPubkeyHashToInfo(bytes32 validatorPubkeyHash) external view returns (ValidatorInfo memory); - - /// @notice Returns the validatorInfo struct for the provided pubkey - function validatorPubkeyToInfo(bytes calldata validatorPubkey) external view returns (ValidatorInfo memory); - - ///@notice mapping that tracks proven withdrawals - function provenWithdrawal(bytes32 validatorPubkeyHash, uint64 slot) external view returns (bool); - - /// @notice This returns the status of a given validator - function validatorStatus(bytes32 pubkeyHash) external view returns (VALIDATOR_STATUS); - - /// @notice This returns the status of a given validator pubkey - function validatorStatus(bytes calldata validatorPubkey) external view returns (VALIDATOR_STATUS); + function startCheckpoint(bool revertIfNoBalance) external; /** - * @notice This function verifies that the withdrawal credentials of validator(s) owned by the podOwner are pointed to - * this contract. It also verifies the effective balance of the validator. It verifies the provided proof of the ETH validator against the beacon chain state - * root, marks the validator as 'active' in EigenLayer, and credits the restaked ETH in Eigenlayer. - * @param oracleTimestamp is the Beacon Chain timestamp whose state root the `proof` will be proven against. - * @param validatorIndices is the list of indices of the validators being proven, refer to consensus specs - * @param withdrawalCredentialProofs is an array of proofs, where each proof proves each ETH validator's balance and withdrawal credentials - * against a beacon chain state root - * @param validatorFields are the fields of the "Validator Container", refer to consensus specs - * for details: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator + * @dev Progress the current checkpoint towards completion by submitting one or more validator + * checkpoint proofs. Anyone can call this method to submit proofs towards the current checkpoint. + * For each validator proven, the current checkpoint's `proofsRemaining` decreases. + * @dev If the checkpoint's `proofsRemaining` reaches 0, the checkpoint is finalized. + * (see `_updateCheckpoint` for more details) + * @dev This method can only be called when there is a currently-active checkpoint. + * @param balanceContainerProof proves the beacon's current balance container root against a checkpoint's `beaconBlockRoot` + * @param proofs Proofs for one or more validator current balances against the `balanceContainerRoot` */ - function verifyWithdrawalCredentials( - uint64 oracleTimestamp, - BeaconChainProofs.StateRootProof calldata stateRootProof, - uint40[] calldata validatorIndices, - bytes[] calldata withdrawalCredentialProofs, - bytes32[][] calldata validatorFields + function verifyCheckpointProofs( + BeaconChainProofs.BalanceContainerProof calldata balanceContainerProof, + BeaconChainProofs.BalanceProof[] calldata proofs ) external; /** - * @notice This function records an update (either increase or decrease) in the pod's balance in the StrategyManager. - * It also verifies a merkle proof of the validator's current beacon chain balance. - * @param oracleTimestamp The oracleTimestamp whose state root the `proof` will be proven against. - * Must be within `VERIFY_BALANCE_UPDATE_WINDOW_SECONDS` of the current block. - * @param validatorIndices is the list of indices of the validators being proven, refer to consensus specs - * @param validatorFieldsProofs proofs against the `beaconStateRoot` for each validator in `validatorFields` - * @param validatorFields are the fields of the "Validator Container", refer to consensus specs - * @dev For more details on the Beacon Chain spec, see: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator + * @dev Verify one or more validators have their withdrawal credentials pointed at this EigenPod, and award + * shares based on their effective balance. Proven validators are marked `ACTIVE` within the EigenPod, and + * future checkpoint proofs will need to include them. + * @dev Withdrawal credential proofs MUST NOT be older than `currentCheckpointTimestamp`. + * @dev Validators proven via this method MUST NOT have an exit epoch set already. + * @param beaconTimestamp the beacon chain timestamp sent to the 4788 oracle contract. Corresponds + * to the parent beacon block root against which the proof is verified. + * @param stateRootProof proves a beacon state root against a beacon block root + * @param validatorIndices a list of validator indices being proven + * @param validatorFieldsProofs proofs of each validator's `validatorFields` against the beacon state root + * @param validatorFields the fields of the beacon chain "Validator" container. See consensus specs for + * details: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator */ - function verifyBalanceUpdates( - uint64 oracleTimestamp, - uint40[] calldata validatorIndices, + function verifyWithdrawalCredentials( + uint64 beaconTimestamp, BeaconChainProofs.StateRootProof calldata stateRootProof, + uint40[] calldata validatorIndices, bytes[] calldata validatorFieldsProofs, bytes32[][] calldata validatorFields ) external; /** - * @notice This function records full and partial withdrawals on behalf of one of the Ethereum validators for this EigenPod - * @param oracleTimestamp is the timestamp of the oracle slot that the withdrawal is being proven against - * @param withdrawalProofs is the information needed to check the veracity of the block numbers and withdrawals being proven - * @param validatorFieldsProofs is the proof of the validator's fields' in the validator tree - * @param withdrawalFields are the fields of the withdrawals being proven - * @param validatorFields are the fields of the validators being proven + * @dev Prove that one of this pod's active validators was slashed on the beacon chain. A successful + * staleness proof allows the caller to start a checkpoint. + * + * @dev Note that in order to start a checkpoint, any existing checkpoint must already be completed! + * (See `_startCheckpoint` for details) + * + * @dev Note that this method allows anyone to start a checkpoint as soon as a slashing occurs on the beacon + * chain. This is intended to make it easier to external watchers to keep a pod's balance up to date. + * + * @dev Note too that beacon chain slashings are not instant. There is a delay between the initial slashing event + * and the validator's final exit back to the execution layer. During this time, the validator's balance may or + * may not drop further due to a correlation penalty. This method allows proof of a slashed validator + * to initiate a checkpoint for as long as the validator remains on the beacon chain. Once the validator + * has exited and been checkpointed at 0 balance, they are no longer "checkpoint-able" and cannot be proven + * "stale" via this method. + * See https://eth2book.info/capella/part3/transition/epoch/#slashings for more info. + * + * @param beaconTimestamp the beacon chain timestamp sent to the 4788 oracle contract. Corresponds + * to the parent beacon block root against which the proof is verified. + * @param stateRootProof proves a beacon state root against a beacon block root + * @param proof the fields of the beacon chain "Validator" container, along with a merkle proof against + * the beacon state root. See the consensus specs for more details: + * https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator + * + * @dev Staleness conditions: + * - Validator's last checkpoint is older than `beaconTimestamp` + * - Validator MUST be in `ACTIVE` status in the pod + * - Validator MUST be slashed on the beacon chain */ - function verifyAndProcessWithdrawals( - uint64 oracleTimestamp, + function verifyStaleBalance( + uint64 beaconTimestamp, BeaconChainProofs.StateRootProof calldata stateRootProof, - BeaconChainProofs.WithdrawalProof[] calldata withdrawalProofs, - bytes[] calldata validatorFieldsProofs, - bytes32[][] calldata validatorFields, - bytes32[][] calldata withdrawalFields + BeaconChainProofs.ValidatorProof calldata proof ) external; + /// @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`. + /// @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` + function setProofSubmitter(address newProofSubmitter) external; + /** - * @notice Called by the pod owner to activate restaking by withdrawing - * all existing ETH from the pod and preventing further withdrawals via - * "withdrawBeforeRestaking()" + * + * VIEW METHODS + * */ - function activateRestaking() external; - /// @notice Called by the pod owner to withdraw the balance of the pod when `hasRestaked` is set to false - function withdrawBeforeRestaking() external; + /// @notice An address with permissions to call `startCheckpoint` and `verifyWithdrawalCredentials`, set + /// by the podOwner. This role exists to allow a podOwner to designate a hot wallet that can call + /// these methods, allowing the podOwner to remain a cold wallet that is only used to manage funds. + /// @dev If this address is NOT set, only the podOwner can call `startCheckpoint` and `verifyWithdrawalCredentials` + function proofSubmitter() external view returns (address); - /// @notice Called by the pod owner to withdraw the nonBeaconChainETHBalanceWei - function withdrawNonBeaconChainETHBalanceWei(address recipient, uint256 amountToWithdraw) external; + /// @notice the amount of execution layer ETH in this contract that is staked in EigenLayer (i.e. withdrawn from beaconchain but not EigenLayer), + function withdrawableRestakedExecutionLayerGwei() external view returns (uint64); - /// @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 The single EigenPodManager for EigenLayer + function eigenPodManager() external view returns (IEigenPodManager); + + /// @notice The owner of this EigenPod + function podOwner() external view returns (address); + + /// @notice Returns the validatorInfo struct for the provided pubkeyHash + function validatorPubkeyHashToInfo(bytes32 validatorPubkeyHash) external view returns (ValidatorInfo memory); + + /// @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 + function validatorStatus(bytes32 pubkeyHash) external view returns (VALIDATOR_STATUS); + + /// @notice This returns the status of 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 + function activeValidatorCount() external view returns (uint256); + + /// @notice The timestamp of the last checkpoint finalized + function lastCheckpointTimestamp() external view returns (uint64); + + /// @notice The timestamp of the currently-active checkpoint. Will be 0 if there is not active checkpoint + function currentCheckpointTimestamp() external view returns (uint64); + + /// @notice Returns the currently-active checkpoint + function currentCheckpoint() external view returns (Checkpoint memory); + + /// @notice For each checkpoint, the total balance attributed to exited validators, in gwei + /// + /// NOTE that the values added to this mapping are NOT guaranteed to capture the entirety of a validator's + /// exit - rather, they capture the total change in a validator's balance when a checkpoint shows their + /// balance change from nonzero to zero. While a change from nonzero to zero DOES guarantee that a validator + /// has been fully exited, it is possible that the magnitude of this change does not capture what is + /// typically thought of as a "full exit." + /// + /// For example: + /// 1. Consider a validator was last checkpointed at 32 ETH before exiting. Once the exit has been processed, + /// it is expected that the validator's exited balance is calculated to be `32 ETH`. + /// 2. However, before `startCheckpoint` is called, a deposit is made to the validator for 1 ETH. The beacon + /// chain will automatically withdraw this ETH, but not until the withdrawal sweep passes over the validator + /// again. Until this occurs, the validator's current balance (used for checkpointing) is 1 ETH. + /// 3. If `startCheckpoint` is called at this point, the balance delta calculated for this validator will be + /// `-31 ETH`, and because the validator has a nonzero balance, it is not marked WITHDRAWN. + /// 4. After the exit is processed by the beacon chain, a subsequent `startCheckpoint` and checkpoint proof + /// will calculate a balance delta of `-1 ETH` and attribute a 1 ETH exit to the validator. + /// + /// If this edge case impacts your usecase, it should be possible to mitigate this by monitoring for deposits + /// to your exited validators, and waiting to call `startCheckpoint` until those deposits have been automatically + /// exited. + /// + /// Additional edge cases this mapping does not cover: + /// - If a validator is slashed, their balance exited will reflect their original balance rather than the slashed amount + /// - The final partial withdrawal for an exited validator will be likely be included in this mapping. + /// i.e. if a validator was last checkpointed at 32.1 ETH before exiting, the next checkpoint will calculate their + /// "exited" amount to be 32.1 ETH rather than 32 ETH. + function checkpointBalanceExitedGwei(uint64) external view returns (uint64); + + /// @notice Query the 4788 oracle to get the parent block root of the slot with the given `timestamp` + /// @param timestamp of the block for which the parent block root will be returned. MUST correspond + /// 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); } diff --git a/src/contracts/interfaces/IEigenPodManager.sol b/src/contracts/interfaces/IEigenPodManager.sol index 0785585a3..cbe253382 100644 --- a/src/contracts/interfaces/IEigenPodManager.sol +++ b/src/contracts/interfaces/IEigenPodManager.sol @@ -5,7 +5,6 @@ import "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import "./IETHPOSDeposit.sol"; import "./IStrategyManager.sol"; import "./IEigenPod.sol"; -import "./IBeaconChainOracle.sol"; import "./IPausable.sol"; import "./ISlasher.sol"; import "./IStrategy.sol"; @@ -16,9 +15,6 @@ import "./IStrategy.sol"; * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service */ interface IEigenPodManager is IPausable { - /// @notice Emitted to notify the update of the beaconChainOracle address - event BeaconOracleUpdated(address indexed newOracleAddress); - /// @notice Emitted to notify the deployment of an EigenPod event PodDeployed(address indexed eigenPod, address indexed podOwner); @@ -28,6 +24,9 @@ interface IEigenPodManager is IPausable { /// @notice Emitted when the balance of an EigenPod is updated event PodSharesUpdated(address indexed podOwner, int256 sharesDelta); + /// @notice Emitted every time the total shares of a pod are updated + event NewTotalShares(address indexed podOwner, int256 newTotalShares); + /// @notice Emitted when a withdrawal of beacon chain ETH is completed event BeaconChainETHWithdrawalCompleted( address indexed podOwner, @@ -38,8 +37,6 @@ interface IEigenPodManager is IPausable { bytes32 withdrawalRoot ); - event DenebForkTimestampUpdated(uint64 newValue); - /** * @notice Creates an EigenPod for the sender. * @dev Function will revert if the `msg.sender` already has an EigenPod. @@ -66,13 +63,6 @@ interface IEigenPodManager is IPausable { */ function recordBeaconChainETHBalanceUpdate(address podOwner, int256 sharesDelta) external; - /** - * @notice Updates the oracle contract that provides the beacon chain state root - * @param newBeaconChainOracle is the new oracle contract being pointed to - * @dev Callable only by the owner of this contract (i.e. governance) - */ - function updateBeaconChainOracle(IBeaconChainOracle newBeaconChainOracle) external; - /// @notice Returns the address of the `podOwner`'s EigenPod if it has been deployed. function ownerToPod(address podOwner) external view returns (IEigenPod); @@ -85,12 +75,6 @@ interface IEigenPodManager is IPausable { /// @notice Beacon proxy to which the EigenPods point function eigenPodBeacon() external view returns (IBeacon); - /// @notice Oracle contract that provides updates to the beacon chain's state - function beaconChainOracle() external view returns (IBeaconChainOracle); - - /// @notice Returns the beacon block root at `timestamp`. Reverts if the Beacon block root at `timestamp` has not yet been finalized. - function getBlockRootAtTimestamp(uint64 timestamp) external view returns (bytes32); - /// @notice EigenLayer's StrategyManager contract function strategyManager() external view returns (IStrategyManager); @@ -141,17 +125,4 @@ interface IEigenPodManager is IPausable { * @dev Reverts if `shares` is not a whole Gwei amount */ function withdrawSharesAsTokens(address podOwner, address destination, uint256 shares) external; - - /** - * @notice the deneb hard fork timestamp used to determine which proof path to use for proving a withdrawal - */ - function denebForkTimestamp() external view returns (uint64); - - /** - * setting the deneb hard fork timestamp by the eigenPodManager owner - * @dev this function is designed to be called twice. Once, it is set to type(uint64).max - * prior to the actual deneb fork timestamp being set, and then the second time it is set - * to the actual deneb fork timestamp. - */ - function setDenebForkTimestamp(uint64 newDenebForkTimestamp) external; } diff --git a/src/contracts/libraries/BeaconChainProofs.sol b/src/contracts/libraries/BeaconChainProofs.sol index eb4ee8860..9d0caa8d9 100644 --- a/src/contracts/libraries/BeaconChainProofs.sol +++ b/src/contracts/libraries/BeaconChainProofs.sol @@ -10,105 +10,125 @@ import "../libraries/Endian.sol"; //BeaconBlockHeader Spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblockheader //BeaconState Spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconstate library BeaconChainProofs { - // constants are the number of fields and the heights of the different merkle trees used in merkleizing beacon chain containers - uint256 internal constant BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT = 3; - - uint256 internal constant BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT = 4; - - uint256 internal constant BEACON_STATE_FIELD_TREE_HEIGHT = 5; - - uint256 internal constant VALIDATOR_FIELD_TREE_HEIGHT = 3; - - //Note: changed in the deneb hard fork from 4->5 - uint256 internal constant EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_DENEB = 5; - uint256 internal constant EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_CAPELLA = 4; - - // SLOTS_PER_HISTORICAL_ROOT = 2**13, so tree height is 13 - uint256 internal constant BLOCK_ROOTS_TREE_HEIGHT = 13; - - //HISTORICAL_ROOTS_LIMIT = 2**24, so tree height is 24 - uint256 internal constant HISTORICAL_SUMMARIES_TREE_HEIGHT = 24; - - //Index of block_summary_root in historical_summary container - uint256 internal constant BLOCK_SUMMARY_ROOT_INDEX = 0; - - // tree height for hash tree of an individual withdrawal container - uint256 internal constant WITHDRAWAL_FIELD_TREE_HEIGHT = 2; - + /// @notice Heights of various merkle trees in the beacon chain + /// - beaconBlockRoot + /// | HEIGHT: BEACON_BLOCK_HEADER_TREE_HEIGHT + /// -- beaconStateRoot + /// | HEIGHT: BEACON_STATE_TREE_HEIGHT + /// validatorContainerRoot, balanceContainerRoot + /// | | HEIGHT: BALANCE_TREE_HEIGHT + /// | individual balances + /// | HEIGHT: VALIDATOR_TREE_HEIGHT + /// individual validators + uint256 internal constant BEACON_BLOCK_HEADER_TREE_HEIGHT = 3; + uint256 internal constant BEACON_STATE_TREE_HEIGHT = 5; + uint256 internal constant BALANCE_TREE_HEIGHT = 38; uint256 internal constant VALIDATOR_TREE_HEIGHT = 40; - // MAX_WITHDRAWALS_PER_PAYLOAD = 2**4, making tree height = 4 - uint256 internal constant WITHDRAWALS_TREE_HEIGHT = 4; + /// @notice Index of the beaconStateRoot in the `BeaconBlockHeader` container + /// + /// BeaconBlockHeader = [..., state_root, ...] + /// 0... 3 + /// + /// (See https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblockheader) + uint256 internal constant STATE_ROOT_INDEX = 3; - //in beacon block body https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#beaconblockbody - uint256 internal constant EXECUTION_PAYLOAD_INDEX = 9; + /// @notice Indices for fields in the `BeaconState` container + /// + /// BeaconState = [..., validators, balances, ...] + /// 0... 11 12 + /// + /// (See https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#beaconstate) + uint256 internal constant VALIDATOR_CONTAINER_INDEX = 11; + uint256 internal constant BALANCE_CONTAINER_INDEX = 12; - // in beacon block header https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblockheader - uint256 internal constant SLOT_INDEX = 0; - uint256 internal constant STATE_ROOT_INDEX = 3; - uint256 internal constant BODY_ROOT_INDEX = 4; - // in beacon state https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#beaconstate - uint256 internal constant VALIDATOR_TREE_ROOT_INDEX = 11; - uint256 internal constant HISTORICAL_SUMMARIES_INDEX = 27; + /// @notice Number of fields in the `Validator` container + /// (See https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator) + uint256 internal constant VALIDATOR_FIELDS_LENGTH = 8; - // in validator https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator + /// @notice Indices for fields in the `Validator` container uint256 internal constant VALIDATOR_PUBKEY_INDEX = 0; uint256 internal constant VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX = 1; uint256 internal constant VALIDATOR_BALANCE_INDEX = 2; - uint256 internal constant VALIDATOR_WITHDRAWABLE_EPOCH_INDEX = 7; - - // in execution payload header - uint256 internal constant TIMESTAMP_INDEX = 9; - - //in execution payload - uint256 internal constant WITHDRAWALS_INDEX = 14; - - // in withdrawal - uint256 internal constant WITHDRAWAL_VALIDATOR_INDEX_INDEX = 1; - uint256 internal constant WITHDRAWAL_VALIDATOR_AMOUNT_INDEX = 3; + uint256 internal constant VALIDATOR_SLASHED_INDEX = 3; + uint256 internal constant VALIDATOR_ACTIVATION_EPOCH_INDEX = 5; + uint256 internal constant VALIDATOR_EXIT_EPOCH_INDEX = 6; - //Misc Constants - - /// @notice The number of slots each epoch in the beacon chain - uint64 internal constant SLOTS_PER_EPOCH = 32; - - /// @notice The number of seconds in a slot in the beacon chain + /// @notice Slot/Epoch timings uint64 internal constant SECONDS_PER_SLOT = 12; - - /// @notice Number of seconds per epoch: 384 == 32 slots/epoch * 12 seconds/slot + uint64 internal constant SLOTS_PER_EPOCH = 32; uint64 internal constant SECONDS_PER_EPOCH = SLOTS_PER_EPOCH * SECONDS_PER_SLOT; + /// @notice `FAR_FUTURE_EPOCH` is used as the default value for certain `Validator` + /// fields when a `Validator` is first created on the beacon chain + uint64 internal constant FAR_FUTURE_EPOCH = type(uint64).max; bytes8 internal constant UINT64_MASK = 0xffffffffffffffff; - /// @notice This struct contains the merkle proofs and leaves needed to verify a partial/full withdrawal - struct WithdrawalProof { - bytes withdrawalProof; - bytes slotProof; - bytes executionPayloadProof; - bytes timestampProof; - bytes historicalSummaryBlockRootProof; - uint64 blockRootIndex; - uint64 historicalSummaryIndex; - uint64 withdrawalIndex; - bytes32 blockRoot; - bytes32 slotRoot; - bytes32 timestampRoot; - bytes32 executionPayloadRoot; - } - - /// @notice This struct contains the root and proof for verifying the state root against the oracle block root + /// @notice Contains a beacon state root and a merkle proof verifying its inclusion under a beacon block root struct StateRootProof { bytes32 beaconStateRoot; bytes proof; } + /// @notice Contains a validator's fields and a merkle proof of their inclusion under a beacon state root + struct ValidatorProof { + bytes32[] validatorFields; + bytes proof; + } + + /// @notice Contains a beacon balance container root and a proof of this root under a beacon block root + struct BalanceContainerProof { + bytes32 balanceContainerRoot; + bytes proof; + } + + /// @notice Contains a validator balance root and a proof of its inclusion under a balance container root + struct BalanceProof { + bytes32 pubkeyHash; + bytes32 balanceRoot; + bytes proof; + } + /** - * @notice This function verifies merkle proofs of the fields of a certain validator against a beacon chain state root - * @param validatorIndex the index of the proven validator - * @param beaconStateRoot is the beacon chain state root to be proven against. - * @param validatorFieldsProof is the data used in proving the validator's fields - * @param validatorFields the claimed fields of the validator + * + * VALIDATOR FIELDS -> BEACON STATE ROOT -> BEACON BLOCK ROOT + * */ + + /// @notice Verify a merkle proof of the beacon state root against a beacon block root + /// @param beaconBlockRoot merkle root of the beacon block + /// @param proof the beacon state root and merkle proof of its inclusion under `beaconBlockRoot` + function verifyStateRoot(bytes32 beaconBlockRoot, StateRootProof calldata proof) internal view { + require( + proof.proof.length == 32 * (BEACON_BLOCK_HEADER_TREE_HEIGHT), + "BeaconChainProofs.verifyStateRoot: Proof has incorrect length" + ); + + /// This merkle proof verifies the `beaconStateRoot` under the `beaconBlockRoot` + /// - beaconBlockRoot + /// | HEIGHT: BEACON_BLOCK_HEADER_TREE_HEIGHT + /// -- beaconStateRoot + require( + Merkle.verifyInclusionSha256({ + proof: proof.proof, + root: beaconBlockRoot, + leaf: proof.beaconStateRoot, + index: STATE_ROOT_INDEX + }), + "BeaconChainProofs.verifyStateRoot: Invalid state root merkle proof" + ); + } + + /// @notice Verify a merkle proof of a validator container against a `beaconStateRoot` + /// @dev This proof starts at a validator's container root, proves through the validator container root, + /// and continues proving to the root of the `BeaconState` + /// @dev See https://eth2book.info/capella/part3/containers/dependencies/#validator for info on `Validator` containers + /// @dev See https://eth2book.info/capella/part3/containers/state/#beaconstate for info on `BeaconState` containers + /// @param beaconStateRoot merkle root of the `BeaconState` container + /// @param validatorFields an individual validator's fields. These are merklized to form a `validatorRoot`, + /// which is used as the leaf to prove against `beaconStateRoot` + /// @param validatorFieldsProof a merkle proof of inclusion of `validatorFields` under `beaconStateRoot` + /// @param validatorIndex the validator's unique index function verifyValidatorFields( bytes32 beaconStateRoot, bytes32[] calldata validatorFields, @@ -116,23 +136,28 @@ library BeaconChainProofs { uint40 validatorIndex ) internal view { require( - validatorFields.length == 2 ** VALIDATOR_FIELD_TREE_HEIGHT, + validatorFields.length == VALIDATOR_FIELDS_LENGTH, "BeaconChainProofs.verifyValidatorFields: Validator fields has incorrect length" ); - /** - * Note: the length of the validator merkle proof is BeaconChainProofs.VALIDATOR_TREE_HEIGHT + 1. - * There is an additional layer added by hashing the root with the length of the validator list - */ + /// Note: the reason we use `VALIDATOR_TREE_HEIGHT + 1` here is because the merklization process for + /// this container includes hashing the root of the validator tree with the length of the validator list require( - validatorFieldsProof.length == 32 * ((VALIDATOR_TREE_HEIGHT + 1) + BEACON_STATE_FIELD_TREE_HEIGHT), + validatorFieldsProof.length == 32 * ((VALIDATOR_TREE_HEIGHT + 1) + BEACON_STATE_TREE_HEIGHT), "BeaconChainProofs.verifyValidatorFields: Proof has incorrect length" ); - uint256 index = (VALIDATOR_TREE_ROOT_INDEX << (VALIDATOR_TREE_HEIGHT + 1)) | uint256(validatorIndex); - // merkleize the validatorFields to get the leaf to prove + + // Merkleize `validatorFields` to get the leaf to prove bytes32 validatorRoot = Merkle.merkleizeSha256(validatorFields); - // verify the proof of the validatorRoot against the beaconStateRoot + /// This proof combines two proofs, so its index accounts for the relative position of leaves in two trees: + /// - beaconStateRoot + /// | HEIGHT: BEACON_STATE_TREE_HEIGHT + /// -- validatorContainerRoot + /// | HEIGHT: VALIDATOR_TREE_HEIGHT + 1 + /// ---- validatorRoot + uint256 index = (VALIDATOR_CONTAINER_INDEX << (VALIDATOR_TREE_HEIGHT + 1)) | uint256(validatorIndex); + require( Merkle.verifyInclusionSha256({ proof: validatorFieldsProof, @@ -145,255 +170,136 @@ library BeaconChainProofs { } /** - * @notice This function verifies the latestBlockHeader against the state root. the latestBlockHeader is - * a tracked in the beacon state. - * @param beaconStateRoot is the beacon chain state root to be proven against. - * @param stateRootProof is the provided merkle proof - * @param latestBlockRoot is hashtree root of the latest block header in the beacon state - */ - function verifyStateRootAgainstLatestBlockRoot( - bytes32 latestBlockRoot, - bytes32 beaconStateRoot, - bytes calldata stateRootProof - ) internal view { - require( - stateRootProof.length == 32 * (BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT), - "BeaconChainProofs.verifyStateRootAgainstLatestBlockRoot: Proof has incorrect length" - ); - //Next we verify the slot against the blockRoot - require( - Merkle.verifyInclusionSha256({ - proof: stateRootProof, - root: latestBlockRoot, - leaf: beaconStateRoot, - index: STATE_ROOT_INDEX - }), - "BeaconChainProofs.verifyStateRootAgainstLatestBlockRoot: Invalid latest block header root merkle proof" - ); - } - - /** - * @notice This function verifies the slot and the withdrawal fields for a given withdrawal - * @param withdrawalProof is the provided set of merkle proofs - * @param withdrawalFields is the serialized withdrawal container to be proven + * + * VALIDATOR BALANCE -> BALANCE CONTAINER ROOT -> BEACON BLOCK ROOT + * */ - function verifyWithdrawal( - bytes32 beaconStateRoot, - bytes32[] calldata withdrawalFields, - WithdrawalProof calldata withdrawalProof, - uint64 denebForkTimestamp - ) internal view { - require( - withdrawalFields.length == 2 ** WITHDRAWAL_FIELD_TREE_HEIGHT, - "BeaconChainProofs.verifyWithdrawal: withdrawalFields has incorrect length" - ); + /// @notice Verify a merkle proof of the beacon state's balances container against the beacon block root + /// @dev This proof starts at the balance container root, proves through the beacon state root, and + /// continues proving through the beacon block root. As a result, this proof will contain elements + /// of a `StateRootProof` under the same block root, with the addition of proving the balances field + /// within the beacon state. + /// @dev This is used to make checkpoint proofs more efficient, as a checkpoint will verify multiple balances + /// against the same balance container root. + /// @param beaconBlockRoot merkle root of the beacon block + /// @param proof a beacon balance container root and merkle proof of its inclusion under `beaconBlockRoot` + function verifyBalanceContainer(bytes32 beaconBlockRoot, BalanceContainerProof calldata proof) internal view { require( - withdrawalProof.blockRootIndex < 2 ** BLOCK_ROOTS_TREE_HEIGHT, - "BeaconChainProofs.verifyWithdrawal: blockRootIndex is too large" - ); - require( - withdrawalProof.withdrawalIndex < 2 ** WITHDRAWALS_TREE_HEIGHT, - "BeaconChainProofs.verifyWithdrawal: withdrawalIndex is too large" + proof.proof.length == 32 * (BEACON_BLOCK_HEADER_TREE_HEIGHT + BEACON_STATE_TREE_HEIGHT), + "BeaconChainProofs.verifyBalanceContainer: Proof has incorrect length" ); - require( - withdrawalProof.historicalSummaryIndex < 2 ** HISTORICAL_SUMMARIES_TREE_HEIGHT, - "BeaconChainProofs.verifyWithdrawal: historicalSummaryIndex is too large" - ); - - //Note: post deneb hard fork, the number of exection payload header fields increased from 15->17, adding an extra level to the tree height - uint256 executionPayloadHeaderFieldTreeHeight = (getWithdrawalTimestamp(withdrawalProof) < denebForkTimestamp) - ? EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_CAPELLA - : EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_DENEB; - require( - withdrawalProof.withdrawalProof.length - == 32 * (executionPayloadHeaderFieldTreeHeight + WITHDRAWALS_TREE_HEIGHT + 1), - "BeaconChainProofs.verifyWithdrawal: withdrawalProof has incorrect length" - ); - require( - withdrawalProof.executionPayloadProof.length - == 32 * (BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT + BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT), - "BeaconChainProofs.verifyWithdrawal: executionPayloadProof has incorrect length" - ); - require( - withdrawalProof.slotProof.length == 32 * (BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT), - "BeaconChainProofs.verifyWithdrawal: slotProof has incorrect length" - ); - require( - withdrawalProof.timestampProof.length == 32 * (executionPayloadHeaderFieldTreeHeight), - "BeaconChainProofs.verifyWithdrawal: timestampProof has incorrect length" - ); - - require( - withdrawalProof.historicalSummaryBlockRootProof.length - == 32 - * (BEACON_STATE_FIELD_TREE_HEIGHT + (HISTORICAL_SUMMARIES_TREE_HEIGHT + 1) + 1 + (BLOCK_ROOTS_TREE_HEIGHT)), - "BeaconChainProofs.verifyWithdrawal: historicalSummaryBlockRootProof has incorrect length" - ); - /** - * Note: Here, the "1" in "1 + (BLOCK_ROOTS_TREE_HEIGHT)" signifies that extra step of choosing the "block_root_summary" within the individual - * "historical_summary". Everywhere else it signifies merkelize_with_mixin, where the length of an array is hashed with the root of the array, - * but not here. - */ - uint256 historicalBlockHeaderIndex = ( - HISTORICAL_SUMMARIES_INDEX << ((HISTORICAL_SUMMARIES_TREE_HEIGHT + 1) + 1 + (BLOCK_ROOTS_TREE_HEIGHT)) - ) | (uint256(withdrawalProof.historicalSummaryIndex) << (1 + (BLOCK_ROOTS_TREE_HEIGHT))) - | (BLOCK_SUMMARY_ROOT_INDEX << (BLOCK_ROOTS_TREE_HEIGHT)) | uint256(withdrawalProof.blockRootIndex); + /// This proof combines two proofs, so its index accounts for the relative position of leaves in two trees: + /// - beaconBlockRoot + /// | HEIGHT: BEACON_BLOCK_HEADER_TREE_HEIGHT + /// -- beaconStateRoot + /// | HEIGHT: BEACON_STATE_TREE_HEIGHT + /// ---- balancesContainerRoot + uint256 index = (STATE_ROOT_INDEX << (BEACON_STATE_TREE_HEIGHT)) | BALANCE_CONTAINER_INDEX; require( Merkle.verifyInclusionSha256({ - proof: withdrawalProof.historicalSummaryBlockRootProof, - root: beaconStateRoot, - leaf: withdrawalProof.blockRoot, - index: historicalBlockHeaderIndex + proof: proof.proof, + root: beaconBlockRoot, + leaf: proof.balanceContainerRoot, + index: index }), - "BeaconChainProofs.verifyWithdrawal: Invalid historicalsummary merkle proof" + "BeaconChainProofs.verifyBalanceContainer: invalid balance container proof" ); + } - //Next we verify the slot against the blockRoot + /// @notice Verify a merkle proof of a validator's balance against the beacon state's `balanceContainerRoot` + /// @param balanceContainerRoot the merkle root of all validators' current balances + /// @param validatorIndex the index of the validator whose balance we are proving + /// @param proof the validator's associated balance root and a merkle proof of inclusion under `balanceContainerRoot` + /// @return validatorBalanceGwei the validator's current balance (in gwei) + function verifyValidatorBalance( + bytes32 balanceContainerRoot, + uint40 validatorIndex, + BalanceProof calldata proof + ) internal view returns (uint64 validatorBalanceGwei) { + /// Note: the reason we use `BALANCE_TREE_HEIGHT + 1` here is because the merklization process for + /// this container includes hashing the root of the balances tree with the length of the balances list require( - Merkle.verifyInclusionSha256({ - proof: withdrawalProof.slotProof, - root: withdrawalProof.blockRoot, - leaf: withdrawalProof.slotRoot, - index: SLOT_INDEX - }), - "BeaconChainProofs.verifyWithdrawal: Invalid slot merkle proof" + proof.proof.length == 32 * (BALANCE_TREE_HEIGHT + 1), + "BeaconChainProofs.verifyValidatorBalance: Proof has incorrect length" ); - { - // Next we verify the executionPayloadRoot against the blockRoot - uint256 executionPayloadIndex = - (BODY_ROOT_INDEX << (BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT)) | EXECUTION_PAYLOAD_INDEX; - require( - Merkle.verifyInclusionSha256({ - proof: withdrawalProof.executionPayloadProof, - root: withdrawalProof.blockRoot, - leaf: withdrawalProof.executionPayloadRoot, - index: executionPayloadIndex - }), - "BeaconChainProofs.verifyWithdrawal: Invalid executionPayload merkle proof" - ); - } - - // Next we verify the timestampRoot against the executionPayload root + /// When merkleized, beacon chain balances are combined into groups of 4 called a `balanceRoot`. The merkle + /// proof here verifies that this validator's `balanceRoot` is included in the `balanceContainerRoot` + /// - balanceContainerRoot + /// | HEIGHT: BALANCE_TREE_HEIGHT + /// -- balanceRoot + uint256 balanceIndex = uint256(validatorIndex / 4); + require( Merkle.verifyInclusionSha256({ - proof: withdrawalProof.timestampProof, - root: withdrawalProof.executionPayloadRoot, - leaf: withdrawalProof.timestampRoot, - index: TIMESTAMP_INDEX + proof: proof.proof, + root: balanceContainerRoot, + leaf: proof.balanceRoot, + index: balanceIndex }), - "BeaconChainProofs.verifyWithdrawal: Invalid timestamp merkle proof" + "BeaconChainProofs.verifyValidatorBalance: Invalid merkle proof" ); - { - /** - * Next we verify the withdrawal fields against the executionPayloadRoot: - * First we compute the withdrawal_index, then we merkleize the - * withdrawalFields container to calculate the withdrawalRoot. - * - * Note: Merkleization of the withdrawals root tree uses MerkleizeWithMixin, i.e., the length of the array is hashed with the root of - * the array. Thus we shift the WITHDRAWALS_INDEX over by WITHDRAWALS_TREE_HEIGHT + 1 and not just WITHDRAWALS_TREE_HEIGHT. - */ - uint256 withdrawalIndex = - (WITHDRAWALS_INDEX << (WITHDRAWALS_TREE_HEIGHT + 1)) | uint256(withdrawalProof.withdrawalIndex); - bytes32 withdrawalRoot = Merkle.merkleizeSha256(withdrawalFields); - require( - Merkle.verifyInclusionSha256({ - proof: withdrawalProof.withdrawalProof, - root: withdrawalProof.executionPayloadRoot, - leaf: withdrawalRoot, - index: withdrawalIndex - }), - "BeaconChainProofs.verifyWithdrawal: Invalid withdrawal merkle proof" - ); - } + /// Extract the individual validator's balance from the `balanceRoot` + return getBalanceAtIndex(proof.balanceRoot, validatorIndex); } /** - * @notice This function replicates the ssz hashing of a validator's pubkey, outlined below: - * hh := ssz.NewHasher() - * hh.PutBytes(validatorPubkey[:]) - * validatorPubkeyHash := hh.Hash() - * hh.Reset() + * @notice Parses a balanceRoot to get the uint64 balance of a validator. + * @dev During merkleization of the beacon state balance tree, four uint64 values are treated as a single + * leaf in the merkle tree. We use validatorIndex % 4 to determine which of the four uint64 values to + * extract from the balanceRoot. + * @param balanceRoot is the combination of 4 validator balances being proven for + * @param validatorIndex is the index of the validator being proven for + * @return The validator's balance, in Gwei */ - function hashValidatorBLSPubkey(bytes memory validatorPubkey) internal pure returns (bytes32 pubkeyHash) { - require(validatorPubkey.length == 48, "Input should be 48 bytes in length"); - return sha256(abi.encodePacked(validatorPubkey, bytes16(0))); + function getBalanceAtIndex(bytes32 balanceRoot, uint40 validatorIndex) internal pure returns (uint64) { + uint256 bitShiftAmount = (validatorIndex % 4) * 64; + return Endian.fromLittleEndianUint64(bytes32((uint256(balanceRoot) << bitShiftAmount))); } - /** - * @dev Retrieve the withdrawal timestamp - */ - function getWithdrawalTimestamp(WithdrawalProof memory withdrawalProof) internal pure returns (uint64) { - return Endian.fromLittleEndianUint64(withdrawalProof.timestampRoot); - } - - /** - * @dev Converts the withdrawal's slot to an epoch - */ - function getWithdrawalEpoch(WithdrawalProof memory withdrawalProof) internal pure returns (uint64) { - return Endian.fromLittleEndianUint64(withdrawalProof.slotRoot) / SLOTS_PER_EPOCH; - } - - /** - * Indices for validator fields (refer to consensus specs): - * 0: pubkey - * 1: withdrawal credentials - * 2: effective balance - * 3: slashed? - * 4: activation elligibility epoch - * 5: activation epoch - * 6: exit epoch - * 7: withdrawable epoch - */ - - /** - * @dev Retrieves a validator's pubkey hash - */ + /// @notice Indices for fields in the `Validator` container: + /// 0: pubkey + /// 1: withdrawal credentials + /// 2: effective balance + /// 3: slashed? + /// 4: activation eligibility epoch + /// 5: activation epoch + /// 6: exit epoch + /// 7: withdrawable epoch + /// + /// (See https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator) + + /// @dev Retrieves a validator's pubkey hash function getPubkeyHash(bytes32[] memory validatorFields) internal pure returns (bytes32) { return validatorFields[VALIDATOR_PUBKEY_INDEX]; } + /// @dev Retrieves a validator's withdrawal credentials function getWithdrawalCredentials(bytes32[] memory validatorFields) internal pure returns (bytes32) { return validatorFields[VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX]; } - /** - * @dev Retrieves a validator's effective balance (in gwei) - */ + /// @dev Retrieves a validator's effective balance (in gwei) function getEffectiveBalanceGwei(bytes32[] memory validatorFields) internal pure returns (uint64) { return Endian.fromLittleEndianUint64(validatorFields[VALIDATOR_BALANCE_INDEX]); } - /** - * @dev Retrieves a validator's withdrawable epoch - */ - function getWithdrawableEpoch(bytes32[] memory validatorFields) internal pure returns (uint64) { - return Endian.fromLittleEndianUint64(validatorFields[VALIDATOR_WITHDRAWABLE_EPOCH_INDEX]); + /// @dev Retrieves a validator's activation epoch + function getActivationEpoch(bytes32[] memory validatorFields) internal pure returns (uint64) { + return Endian.fromLittleEndianUint64(validatorFields[VALIDATOR_ACTIVATION_EPOCH_INDEX]); } - /** - * Indices for withdrawal fields (refer to consensus specs): - * 0: withdrawal index - * 1: validator index - * 2: execution address - * 3: withdrawal amount - */ - - /** - * @dev Retrieves a withdrawal's validator index - */ - function getValidatorIndex(bytes32[] memory withdrawalFields) internal pure returns (uint40) { - return uint40(Endian.fromLittleEndianUint64(withdrawalFields[WITHDRAWAL_VALIDATOR_INDEX_INDEX])); + /// @dev Retrieves true IFF a validator is marked slashed + function isValidatorSlashed(bytes32[] memory validatorFields) internal pure returns (bool) { + return validatorFields[VALIDATOR_SLASHED_INDEX] != 0; } - /** - * @dev Retrieves a withdrawal's withdrawal amount (in gwei) - */ - function getWithdrawalAmountGwei(bytes32[] memory withdrawalFields) internal pure returns (uint64) { - return Endian.fromLittleEndianUint64(withdrawalFields[WITHDRAWAL_VALIDATOR_AMOUNT_INDEX]); + /// @dev Retrieves a validator's exit epoch + function getExitEpoch(bytes32[] memory validatorFields) internal pure returns (uint64) { + return Endian.fromLittleEndianUint64(validatorFields[VALIDATOR_EXIT_EPOCH_INDEX]); } } diff --git a/src/contracts/pods/DelayedWithdrawalRouter.sol b/src/contracts/pods/DelayedWithdrawalRouter.sol deleted file mode 100644 index 355bbd7ab..000000000 --- a/src/contracts/pods/DelayedWithdrawalRouter.sol +++ /dev/null @@ -1,233 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.12; - -import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; -import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol"; -import "../interfaces/IEigenPodManager.sol"; -import "../interfaces/IDelayedWithdrawalRouter.sol"; -import "../permissions/Pausable.sol"; - -contract DelayedWithdrawalRouter is - Initializable, - OwnableUpgradeable, - ReentrancyGuardUpgradeable, - Pausable, - IDelayedWithdrawalRouter -{ - // index for flag that pauses withdrawals (i.e. 'delayedWithdrawal claims') when set - uint8 internal constant PAUSED_DELAYED_WITHDRAWAL_CLAIMS = 0; - - /** - * @notice Delay enforced by this contract for completing any delayedWithdrawal. 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). - */ - uint256 public withdrawalDelayBlocks; - // the number of 12-second blocks in 30 days (60 * 60 * 24 * 30 / 12 = 216,000) - uint256 public constant MAX_WITHDRAWAL_DELAY_BLOCKS = 216_000; - - /// @notice The EigenPodManager contract of EigenLayer. - IEigenPodManager public immutable eigenPodManager; - - /// @notice Mapping: user => struct storing all delayedWithdrawal info. Marked as internal with an external getter function named `userWithdrawals` - mapping(address => UserDelayedWithdrawals) internal _userWithdrawals; - - /// @notice Modifier used to permission a function to only be called by the EigenPod of the specified `podOwner` - modifier onlyEigenPod(address podOwner) { - require( - address(eigenPodManager.getPod(podOwner)) == msg.sender, - "DelayedWithdrawalRouter.onlyEigenPod: not podOwner's EigenPod" - ); - _; - } - - constructor(IEigenPodManager _eigenPodManager) { - require( - address(_eigenPodManager) != address(0), - "DelayedWithdrawalRouter.constructor: _eigenPodManager cannot be zero address" - ); - eigenPodManager = _eigenPodManager; - _disableInitializers(); - } - - function initialize( - address initOwner, - IPauserRegistry _pauserRegistry, - uint256 initPausedStatus, - uint256 _withdrawalDelayBlocks - ) external initializer { - _transferOwnership(initOwner); - _initializePauser(_pauserRegistry, initPausedStatus); - _setWithdrawalDelayBlocks(_withdrawalDelayBlocks); - } - - /** - * @notice Creates a delayed withdrawal for `msg.value` to the `recipient`. - * @dev Only callable by the `podOwner`'s EigenPod contract. - */ - function createDelayedWithdrawal( - address podOwner, - address recipient - ) external payable onlyEigenPod(podOwner) onlyWhenNotPaused(PAUSED_DELAYED_WITHDRAWAL_CLAIMS) { - require( - recipient != address(0), "DelayedWithdrawalRouter.createDelayedWithdrawal: recipient cannot be zero address" - ); - uint224 withdrawalAmount = uint224(msg.value); - if (withdrawalAmount != 0) { - DelayedWithdrawal memory delayedWithdrawal = - DelayedWithdrawal({amount: withdrawalAmount, blockCreated: uint32(block.number)}); - _userWithdrawals[recipient].delayedWithdrawals.push(delayedWithdrawal); - emit DelayedWithdrawalCreated( - podOwner, recipient, withdrawalAmount, _userWithdrawals[recipient].delayedWithdrawals.length - 1 - ); - } - } - - /** - * @notice Called in order to withdraw delayed withdrawals made to the `recipient` that have passed the `withdrawalDelayBlocks` period. - * @param recipient The address to claim delayedWithdrawals for. - * @param maxNumberOfDelayedWithdrawalsToClaim Used to limit the maximum number of delayedWithdrawals to loop through claiming. - * @dev - * WARNING: Note that the caller of this function cannot control where the funds are sent, but they can control when the - * funds are sent once the withdrawal becomes claimable. - */ - function claimDelayedWithdrawals( - address recipient, - uint256 maxNumberOfDelayedWithdrawalsToClaim - ) external nonReentrant onlyWhenNotPaused(PAUSED_DELAYED_WITHDRAWAL_CLAIMS) { - _claimDelayedWithdrawals(recipient, maxNumberOfDelayedWithdrawalsToClaim); - } - - /** - * @notice Called in order to withdraw delayed withdrawals made to the caller that have passed the `withdrawalDelayBlocks` period. - * @param maxNumberOfDelayedWithdrawalsToClaim Used to limit the maximum number of delayedWithdrawals to loop through claiming. - */ - function claimDelayedWithdrawals(uint256 maxNumberOfDelayedWithdrawalsToClaim) - external - nonReentrant - onlyWhenNotPaused(PAUSED_DELAYED_WITHDRAWAL_CLAIMS) - { - _claimDelayedWithdrawals(msg.sender, maxNumberOfDelayedWithdrawalsToClaim); - } - - /// @notice Owner-only function for modifying the value of the `withdrawalDelayBlocks` variable. - function setWithdrawalDelayBlocks(uint256 newValue) external onlyOwner { - _setWithdrawalDelayBlocks(newValue); - } - - /// @notice Getter function for the mapping `_userWithdrawals` - function userWithdrawals(address user) external view returns (UserDelayedWithdrawals memory) { - return _userWithdrawals[user]; - } - - /// @notice Getter function to get all delayedWithdrawals of the `user` - function getUserDelayedWithdrawals(address user) external view returns (DelayedWithdrawal[] memory) { - uint256 delayedWithdrawalsCompleted = _userWithdrawals[user].delayedWithdrawalsCompleted; - uint256 totalDelayedWithdrawals = _userWithdrawals[user].delayedWithdrawals.length; - uint256 userDelayedWithdrawalsLength = totalDelayedWithdrawals - delayedWithdrawalsCompleted; - DelayedWithdrawal[] memory userDelayedWithdrawals = new DelayedWithdrawal[](userDelayedWithdrawalsLength); - for (uint256 i = 0; i < userDelayedWithdrawalsLength; i++) { - userDelayedWithdrawals[i] = _userWithdrawals[user].delayedWithdrawals[delayedWithdrawalsCompleted + i]; - } - return userDelayedWithdrawals; - } - - /// @notice Getter function to get all delayedWithdrawals that are currently claimable by the `user` - function getClaimableUserDelayedWithdrawals(address user) external view returns (DelayedWithdrawal[] memory) { - uint256 delayedWithdrawalsCompleted = _userWithdrawals[user].delayedWithdrawalsCompleted; - uint256 totalDelayedWithdrawals = _userWithdrawals[user].delayedWithdrawals.length; - uint256 userDelayedWithdrawalsLength = totalDelayedWithdrawals - delayedWithdrawalsCompleted; - - uint256 firstNonClaimableWithdrawalIndex = userDelayedWithdrawalsLength; - - for (uint256 i = 0; i < userDelayedWithdrawalsLength; i++) { - DelayedWithdrawal memory delayedWithdrawal = - _userWithdrawals[user].delayedWithdrawals[delayedWithdrawalsCompleted + i]; - // check if delayedWithdrawal can be claimed. break the loop as soon as a delayedWithdrawal cannot be claimed - if (block.number < delayedWithdrawal.blockCreated + withdrawalDelayBlocks) { - firstNonClaimableWithdrawalIndex = i; - break; - } - } - uint256 numberOfClaimableWithdrawals = firstNonClaimableWithdrawalIndex; - DelayedWithdrawal[] memory claimableDelayedWithdrawals = new DelayedWithdrawal[](numberOfClaimableWithdrawals); - - if (numberOfClaimableWithdrawals != 0) { - for (uint256 i = 0; i < numberOfClaimableWithdrawals; i++) { - claimableDelayedWithdrawals[i] = - _userWithdrawals[user].delayedWithdrawals[delayedWithdrawalsCompleted + i]; - } - } - return claimableDelayedWithdrawals; - } - - /// @notice Getter function for fetching the delayedWithdrawal at the `index`th entry from the `_userWithdrawals[user].delayedWithdrawals` array - function userDelayedWithdrawalByIndex( - address user, - uint256 index - ) external view returns (DelayedWithdrawal memory) { - return _userWithdrawals[user].delayedWithdrawals[index]; - } - - /// @notice Getter function for fetching the length of the delayedWithdrawals array of a specific user - function userWithdrawalsLength(address user) external view returns (uint256) { - return _userWithdrawals[user].delayedWithdrawals.length; - } - - /// @notice Convenience function for checking whether or not the delayedWithdrawal at the `index`th entry from the `_userWithdrawals[user].delayedWithdrawals` array is currently claimable - function canClaimDelayedWithdrawal(address user, uint256 index) external view returns (bool) { - return ( - (index >= _userWithdrawals[user].delayedWithdrawalsCompleted) - && (block.number >= _userWithdrawals[user].delayedWithdrawals[index].blockCreated + withdrawalDelayBlocks) - ); - } - - /// @notice internal function used in both of the overloaded `claimDelayedWithdrawals` functions - function _claimDelayedWithdrawals(address recipient, uint256 maxNumberOfDelayedWithdrawalsToClaim) internal { - uint256 amountToSend = 0; - uint256 delayedWithdrawalsCompletedBefore = _userWithdrawals[recipient].delayedWithdrawalsCompleted; - uint256 _userWithdrawalsLength = _userWithdrawals[recipient].delayedWithdrawals.length; - uint256 i = 0; - while ( - i < maxNumberOfDelayedWithdrawalsToClaim && (delayedWithdrawalsCompletedBefore + i) < _userWithdrawalsLength - ) { - // copy delayedWithdrawal from storage to memory - DelayedWithdrawal memory delayedWithdrawal = - _userWithdrawals[recipient].delayedWithdrawals[delayedWithdrawalsCompletedBefore + i]; - // check if delayedWithdrawal can be claimed. break the loop as soon as a delayedWithdrawal cannot be claimed - if (block.number < delayedWithdrawal.blockCreated + withdrawalDelayBlocks) { - break; - } - // otherwise, the delayedWithdrawal can be claimed, in which case we increase the amountToSend and increment i - amountToSend += delayedWithdrawal.amount; - // increment i to account for the delayedWithdrawal being claimed - unchecked { - ++i; - } - } - // mark the i delayedWithdrawals as claimed - _userWithdrawals[recipient].delayedWithdrawalsCompleted = delayedWithdrawalsCompletedBefore + i; - // actually send the ETH - if (amountToSend != 0) { - AddressUpgradeable.sendValue(payable(recipient), amountToSend); - } - emit DelayedWithdrawalsClaimed(recipient, amountToSend, delayedWithdrawalsCompletedBefore + i); - } - - /// @notice internal function for changing the value of `withdrawalDelayBlocks`. Also performs sanity check and emits an event. - function _setWithdrawalDelayBlocks(uint256 newValue) internal { - require( - newValue <= MAX_WITHDRAWAL_DELAY_BLOCKS, - "DelayedWithdrawalRouter._setWithdrawalDelayBlocks: newValue too large" - ); - emit WithdrawalDelayBlocksSet(withdrawalDelayBlocks, newValue); - withdrawalDelayBlocks = newValue; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/src/contracts/pods/EigenPod.sol b/src/contracts/pods/EigenPod.sol index 184daf7a1..d98ef59f3 100644 --- a/src/contracts/pods/EigenPod.sol +++ b/src/contracts/pods/EigenPod.sol @@ -10,115 +10,72 @@ import "../libraries/BytesLib.sol"; import "../interfaces/IETHPOSDeposit.sol"; import "../interfaces/IEigenPodManager.sol"; -import "../interfaces/IEigenPod.sol"; -import "../interfaces/IDelayedWithdrawalRouter.sol"; import "../interfaces/IPausable.sol"; import "./EigenPodPausingConstants.sol"; +import "./EigenPodStorage.sol"; /** * @title The implementation contract used for restaking beacon chain ETH on EigenLayer * @author Layr Labs, Inc. * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice The main functionalities are: - * - creating new ETH validators with their withdrawal credentials pointed to this contract - * - proving from beacon chain state roots that withdrawal credentials are pointed to this contract - * - proving from beacon chain state roots the balances of ETH validators with their withdrawal credentials - * pointed to this contract - * - updating aggregate balances in the EigenPodManager - * - withdrawing eth when withdrawals are initiated - * @notice This EigenPod Beacon Proxy implementation adheres to the current Capella consensus specs + * @notice This EigenPod Beacon Proxy implementation adheres to the current Deneb consensus specs * @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 */ -contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, EigenPodPausingConstants { +contract EigenPod is Initializable, ReentrancyGuardUpgradeable, EigenPodPausingConstants, EigenPodStorage { using BytesLib for bytes; using SafeERC20 for IERC20; using BeaconChainProofs for *; - // CONSTANTS + IMMUTABLES - // @notice Internal constant used in calculations, since the beacon chain stores balances in Gwei rather than wei - uint256 internal constant GWEI_TO_WEI = 1e9; - /** - * @notice Maximum "staleness" of a Beacon Chain state root against which `verifyBalanceUpdate` or `verifyWithdrawalCredentials` may be proven. - * We can't allow "stale" roots to be used for restaking as the validator may have been slashed in a more updated beacon state root. + * + * CONSTANTS / IMMUTABLES + * */ - uint256 internal constant VERIFY_BALANCE_UPDATE_WINDOW_SECONDS = 4.5 hours; - /// @notice This is the beacon chain deposit contract - IETHPOSDeposit public immutable ethPOS; + /// @notice The beacon chain stores balances in Gwei, rather than wei. This value is used to convert between the two + uint256 internal constant GWEI_TO_WEI = 1e9; + + /// @notice The address of the EIP-4788 beacon block root oracle + /// (See https://eips.ethereum.org/EIPS/eip-4788) + address internal constant BEACON_ROOTS_ADDRESS = 0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02; - /// @notice Contract used for withdrawal routing, to provide an extra "safety net" mechanism - IDelayedWithdrawalRouter public immutable delayedWithdrawalRouter; + /// @notice The length of the EIP-4788 beacon block root ring buffer + uint256 internal constant BEACON_ROOTS_HISTORY_BUFFER_LENGTH = 8191; + + /// @notice The beacon chain deposit contract + IETHPOSDeposit public immutable ethPOS; /// @notice The single EigenPodManager for EigenLayer IEigenPodManager public immutable eigenPodManager; - ///@notice The maximum amount of ETH, in gwei, a validator can have restaked in the eigenlayer - uint64 public immutable MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; - /// @notice This is the genesis time of the beacon state, to help us calculate conversions between slot and timestamp uint64 public immutable GENESIS_TIME; - // STORAGE VARIABLES - /// @notice The owner of this EigenPod - address public podOwner; - /** - * @notice The latest timestamp at which the pod owner withdrew the balance of the pod, via calling `withdrawBeforeRestaking`. - * @dev This variable is only updated when the `withdrawBeforeRestaking` function is called, which can only occur before `hasRestaked` is set to true for this pod. - * Proofs for this pod are only valid against Beacon Chain state roots corresponding to timestamps after the stored `mostRecentWithdrawalTimestamp`. + * + * MODIFIERS + * */ - uint64 public mostRecentWithdrawalTimestamp; - - /// @notice the amount of execution layer ETH in this contract that is staked in EigenLayer (i.e. withdrawn from the Beacon Chain but not from EigenLayer), - uint64 public withdrawableRestakedExecutionLayerGwei; - - /// @notice an indicator of whether or not the podOwner has ever "fully restaked" by successfully calling `verifyCorrectWithdrawalCredentials`. - bool public hasRestaked; - - /// @notice This is a mapping of validatorPubkeyHash to timestamp to whether or not they have proven a withdrawal for that timestamp - mapping(bytes32 => mapping(uint64 => bool)) public provenWithdrawal; - - /// @notice This is a mapping that tracks a validator's information by their pubkey hash - mapping(bytes32 => ValidatorInfo) internal _validatorPubkeyHashToInfo; - - /// @notice This variable tracks any ETH deposited into this contract via the `receive` fallback function - uint256 public nonBeaconChainETHBalanceWei; - - /// @notice This variable tracks the total amount of partial withdrawals claimed via merkle proofs prior to a switch to ZK proofs for claiming partial withdrawals - uint64 public sumOfPartialWithdrawalsClaimedGwei; - - /// @notice Number of validators with proven withdrawal credentials, who do not have proven full withdrawals - uint256 activeValidatorCount; + /// @notice Callable only by the EigenPodManager modifier onlyEigenPodManager() { require(msg.sender == address(eigenPodManager), "EigenPod.onlyEigenPodManager: not eigenPodManager"); _; } + /// @notice Callable only by the pod's owner modifier onlyEigenPodOwner() { require(msg.sender == podOwner, "EigenPod.onlyEigenPodOwner: not podOwner"); _; } - modifier hasNeverRestaked() { - require(!hasRestaked, "EigenPod.hasNeverRestaked: restaking is enabled"); - _; - } - - /// @notice checks that hasRestaked is set to true by calling activateRestaking() - modifier hasEnabledRestaking() { - require(hasRestaked, "EigenPod.hasEnabledRestaking: restaking is not enabled"); - _; - } - - /// @notice Checks that `timestamp` is greater than or equal to the value stored in `mostRecentWithdrawalTimestamp` - modifier proofIsForValidTimestamp(uint64 timestamp) { + /// @notice Callable only by the pod's owner or proof submitter + modifier onlyOwnerOrProofSubmitter() { require( - timestamp >= mostRecentWithdrawalTimestamp, - "EigenPod.proofIsForValidTimestamp: beacon chain proof must be at or after mostRecentWithdrawalTimestamp" + msg.sender == podOwner || msg.sender == proofSubmitter, + "EigenPod.onlyOwnerOrProofSubmitter: caller is not pod owner or proof submitter" ); _; } @@ -136,17 +93,14 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen _; } - constructor( - IETHPOSDeposit _ethPOS, - IDelayedWithdrawalRouter _delayedWithdrawalRouter, - IEigenPodManager _eigenPodManager, - uint64 _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - uint64 _GENESIS_TIME - ) { + /** + * + * CONSTRUCTOR / INIT + * + */ + constructor(IETHPOSDeposit _ethPOS, IEigenPodManager _eigenPodManager, uint64 _GENESIS_TIME) { ethPOS = _ethPOS; - delayedWithdrawalRouter = _delayedWithdrawalRouter; eigenPodManager = _eigenPodManager; - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; GENESIS_TIME = _GENESIS_TIME; _disableInitializers(); } @@ -155,195 +109,160 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen function initialize(address _podOwner) external initializer { require(_podOwner != address(0), "EigenPod.initialize: podOwner cannot be zero address"); podOwner = _podOwner; - /** - * From the M2 deployment onwards, we are requiring that pods deployed are by default enabled with restaking - * In prior deployments without proofs, EigenPods could be deployed with restaking disabled so as to allow - * simple (proof-free) withdrawals. However, this is no longer the case. Thus going forward, all pods are - * initialized with hasRestaked set to true. - */ - hasRestaked = true; - emit RestakingActivated(podOwner); } + /** + * + * EXTERNAL METHODS + * + */ + /// @notice payable fallback function that receives ether deposited to the eigenpods contract receive() external payable { - nonBeaconChainETHBalanceWei += msg.value; emit NonBeaconChainETHReceived(msg.value); } /** - * @notice This function records an update (either increase or decrease) in a validator's balance. - * @param oracleTimestamp The oracleTimestamp whose state root the proof will be proven against. - * Must be within `VERIFY_BALANCE_UPDATE_WINDOW_SECONDS` of the current block. - * @param validatorIndices is the list of indices of the validators being proven, refer to consensus specs - * @param stateRootProof proves a `beaconStateRoot` against a block root fetched from the oracle - * @param validatorFieldsProofs proofs against the `beaconStateRoot` for each validator in `validatorFields` - * @param validatorFields are the fields of the "Validator Container", refer to consensus specs - * @dev For more details on the Beacon Chain spec, see: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator + * @dev Create a checkpoint used to prove this pod's active validator set. Checkpoints are completed + * by submitting one checkpoint proof per ACTIVE validator. During the checkpoint process, the total + * change in ACTIVE validator balance is tracked, and any validators with 0 balance are marked `WITHDRAWN`. + * @dev Once finalized, the pod owner is awarded shares corresponding to: + * - the total change in their ACTIVE validator balances + * - any ETH in the pod not already awarded shares + * @dev A checkpoint cannot be created if the pod already has an outstanding checkpoint. If + * this is the case, the pod owner MUST complete the existing checkpoint before starting a new one. + * @param revertIfNoBalance Forces a revert if the pod ETH balance is 0. This allows the pod owner + * to prevent accidentally starting a checkpoint that will not increase their shares */ - function verifyBalanceUpdates( - uint64 oracleTimestamp, - uint40[] calldata validatorIndices, - BeaconChainProofs.StateRootProof calldata stateRootProof, - bytes[] calldata validatorFieldsProofs, - bytes32[][] calldata validatorFields - ) external onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE) { - require( - (validatorIndices.length == validatorFieldsProofs.length) - && (validatorFieldsProofs.length == validatorFields.length), - "EigenPod.verifyBalanceUpdates: validatorIndices and proofs must be same length" - ); - - // Balance updates should not be "stale" (older than VERIFY_BALANCE_UPDATE_WINDOW_SECONDS) - require( - oracleTimestamp + VERIFY_BALANCE_UPDATE_WINDOW_SECONDS >= block.timestamp, - "EigenPod.verifyBalanceUpdates: specified timestamp is too far in past" - ); - - // Verify passed-in beaconStateRoot against oracle-provided block root: - BeaconChainProofs.verifyStateRootAgainstLatestBlockRoot({ - latestBlockRoot: eigenPodManager.getBlockRootAtTimestamp(oracleTimestamp), - beaconStateRoot: stateRootProof.beaconStateRoot, - stateRootProof: stateRootProof.proof - }); - - int256 sharesDeltaGwei; - for (uint256 i = 0; i < validatorIndices.length; i++) { - sharesDeltaGwei += _verifyBalanceUpdate( - oracleTimestamp, - validatorIndices[i], - stateRootProof.beaconStateRoot, - validatorFieldsProofs[i], // Use validator fields proof because contains the effective balance - validatorFields[i] - ); - } - eigenPodManager.recordBeaconChainETHBalanceUpdate(podOwner, sharesDeltaGwei * int256(GWEI_TO_WEI)); + function startCheckpoint(bool revertIfNoBalance) + external + onlyOwnerOrProofSubmitter + onlyWhenNotPaused(PAUSED_START_CHECKPOINT) + { + _startCheckpoint(revertIfNoBalance); } /** - * @notice This function records full and partial withdrawals on behalf of one or more of this EigenPod's validators - * @param oracleTimestamp is the timestamp of the oracle slot that the withdrawal is being proven against - * @param stateRootProof proves a `beaconStateRoot` against a block root fetched from the oracle - * @param withdrawalProofs proves several withdrawal-related values against the `beaconStateRoot` - * @param validatorFieldsProofs proves `validatorFields` against the `beaconStateRoot` - * @param withdrawalFields are the fields of the withdrawals being proven - * @param validatorFields are the fields of the validators being proven + * @dev Progress the current checkpoint towards completion by submitting one or more validator + * checkpoint proofs. Anyone can call this method to submit proofs towards the current checkpoint. + * For each validator proven, the current checkpoint's `proofsRemaining` decreases. + * @dev If the checkpoint's `proofsRemaining` reaches 0, the checkpoint is finalized. + * (see `_updateCheckpoint` for more details) + * @dev This method can only be called when there is a currently-active checkpoint. + * @param balanceContainerProof proves the beacon's current balance container root against a checkpoint's `beaconBlockRoot` + * @param proofs Proofs for one or more validator current balances against the `balanceContainerRoot` */ - function verifyAndProcessWithdrawals( - uint64 oracleTimestamp, - BeaconChainProofs.StateRootProof calldata stateRootProof, - BeaconChainProofs.WithdrawalProof[] calldata withdrawalProofs, - bytes[] calldata validatorFieldsProofs, - bytes32[][] calldata validatorFields, - bytes32[][] calldata withdrawalFields - ) external onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_WITHDRAWAL) { + function verifyCheckpointProofs( + BeaconChainProofs.BalanceContainerProof calldata balanceContainerProof, + BeaconChainProofs.BalanceProof[] calldata proofs + ) external onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_CHECKPOINT_PROOFS) { + uint64 checkpointTimestamp = currentCheckpointTimestamp; require( - (validatorFields.length == validatorFieldsProofs.length) - && (validatorFieldsProofs.length == withdrawalProofs.length) - && (withdrawalProofs.length == withdrawalFields.length), - "EigenPod.verifyAndProcessWithdrawals: inputs must be same length" + checkpointTimestamp != 0, + "EigenPod.verifyCheckpointProofs: must have active checkpoint to perform checkpoint proof" ); - // Verify passed-in beaconStateRoot against oracle-provided block root: - BeaconChainProofs.verifyStateRootAgainstLatestBlockRoot({ - latestBlockRoot: eigenPodManager.getBlockRootAtTimestamp(oracleTimestamp), - beaconStateRoot: stateRootProof.beaconStateRoot, - stateRootProof: stateRootProof.proof + Checkpoint memory checkpoint = _currentCheckpoint; + + // Verify `balanceContainerProof` against `beaconBlockRoot` + BeaconChainProofs.verifyBalanceContainer({ + beaconBlockRoot: checkpoint.beaconBlockRoot, + proof: balanceContainerProof }); - VerifiedWithdrawal memory withdrawalSummary; - for (uint256 i = 0; i < withdrawalFields.length; i++) { - VerifiedWithdrawal memory verifiedWithdrawal = _verifyAndProcessWithdrawal( - stateRootProof.beaconStateRoot, - withdrawalProofs[i], - validatorFieldsProofs[i], - validatorFields[i], - withdrawalFields[i] - ); + // Process each checkpoint proof submitted + uint64 exitedBalancesGwei; + for (uint256 i = 0; i < proofs.length; i++) { + BeaconChainProofs.BalanceProof calldata proof = proofs[i]; + ValidatorInfo memory validatorInfo = _validatorPubkeyHashToInfo[proof.pubkeyHash]; + + // Validator must be in the ACTIVE state to be provable during a checkpoint. + // Validators become ACTIVE when initially proven via verifyWithdrawalCredentials + // Validators become WITHDRAWN when a checkpoint proof shows they have 0 balance + if (validatorInfo.status != VALIDATOR_STATUS.ACTIVE) { + continue; + } + + // Ensure we aren't proving a validator twice for the same checkpoint. This will fail if: + // - validator submitted twice during this checkpoint + // - validator withdrawal credentials verified after checkpoint starts, then submitted + // as a checkpoint proof + if (validatorInfo.lastCheckpointedAt >= checkpointTimestamp) { + continue; + } + + // Process a checkpoint proof for a validator and update its balance. + // + // If the proof shows the validator has a balance of 0, they are marked `WITHDRAWN`. + // The assumption is that if this is the case, any withdrawn ETH was already in + // the pod when `startCheckpoint` was originally called. + (int128 balanceDeltaGwei, uint64 exitedBalanceGwei) = _verifyCheckpointProof({ + validatorInfo: validatorInfo, + checkpointTimestamp: checkpointTimestamp, + balanceContainerRoot: balanceContainerProof.balanceContainerRoot, + proof: proof + }); - withdrawalSummary.amountToSendGwei += verifiedWithdrawal.amountToSendGwei; - withdrawalSummary.sharesDeltaGwei += verifiedWithdrawal.sharesDeltaGwei; - } + checkpoint.proofsRemaining--; + checkpoint.balanceDeltasGwei += balanceDeltaGwei; + exitedBalancesGwei += exitedBalanceGwei; - // If any withdrawals are eligible for immediate redemption, send to the pod owner via - // DelayedWithdrawalRouter - if (withdrawalSummary.amountToSendGwei != 0) { - _sendETH_AsDelayedWithdrawal(podOwner, withdrawalSummary.amountToSendGwei * GWEI_TO_WEI); - } - // If any withdrawals resulted in a change in the pod's shares, update the EigenPodManager - if (withdrawalSummary.sharesDeltaGwei != 0) { - eigenPodManager.recordBeaconChainETHBalanceUpdate( - podOwner, withdrawalSummary.sharesDeltaGwei * int256(GWEI_TO_WEI) - ); + // Record the updated validator in state + _validatorPubkeyHashToInfo[proof.pubkeyHash] = validatorInfo; + emit ValidatorCheckpointed(checkpointTimestamp, uint40(validatorInfo.validatorIndex)); } + + // Update the checkpoint and the total amount attributed to exited validators + checkpointBalanceExitedGwei[checkpointTimestamp] += exitedBalancesGwei; + _updateCheckpoint(checkpoint); } /** - * - * EXTERNAL FUNCTIONS CALLABLE BY EIGENPOD OWNER - * - */ - - /** - * @notice This function verifies that the withdrawal credentials of validator(s) owned by the podOwner are pointed to - * this contract. It also verifies the effective balance of the validator. It verifies the provided proof of the ETH validator against the beacon chain state - * root, marks the validator as 'active' in EigenLayer, and credits the restaked ETH in Eigenlayer. - * @param oracleTimestamp is the Beacon Chain timestamp whose state root the `proof` will be proven against. - * @param stateRootProof proves a `beaconStateRoot` against a block root fetched from the oracle - * @param validatorIndices is the list of indices of the validators being proven, refer to consensus specs - * @param validatorFieldsProofs proofs against the `beaconStateRoot` for each validator in `validatorFields` - * @param validatorFields are the fields of the "Validator Container", refer to consensus specs - * for details: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator + * @dev Verify one or more validators have their withdrawal credentials pointed at this EigenPod, and award + * shares based on their effective balance. Proven validators are marked `ACTIVE` within the EigenPod, and + * future checkpoint proofs will need to include them. + * @dev Withdrawal credential proofs MUST NOT be older than `currentCheckpointTimestamp`. + * @dev Validators proven via this method MUST NOT have an exit epoch set already. + * @param beaconTimestamp the beacon chain timestamp sent to the 4788 oracle contract. Corresponds + * to the parent beacon block root against which the proof is verified. + * @param stateRootProof proves a beacon state root against a beacon block root + * @param validatorIndices a list of validator indices being proven + * @param validatorFieldsProofs proofs of each validator's `validatorFields` against the beacon state root + * @param validatorFields the fields of the beacon chain "Validator" container. See consensus specs for + * details: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator */ function verifyWithdrawalCredentials( - uint64 oracleTimestamp, + uint64 beaconTimestamp, BeaconChainProofs.StateRootProof calldata stateRootProof, uint40[] calldata validatorIndices, bytes[] calldata validatorFieldsProofs, bytes32[][] calldata validatorFields - ) - external - onlyEigenPodOwner - onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_CREDENTIALS) - // ensure that caller has previously enabled restaking by calling `activateRestaking()` - hasEnabledRestaking - { + ) external onlyOwnerOrProofSubmitter onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_CREDENTIALS) { require( (validatorIndices.length == validatorFieldsProofs.length) && (validatorFieldsProofs.length == validatorFields.length), "EigenPod.verifyWithdrawalCredentials: validatorIndices and proofs must be same length" ); - // `mostRecentWithdrawalTimestamp` will be 0 for any pods deployed after M2 - // If this is non-zero, ensure `oracleTimestamp` is from the epoch AFTER `activateRestaking` - // was called. - require( - mostRecentWithdrawalTimestamp == 0 - || oracleTimestamp >= _nextEpochStartTimestamp(_timestampToEpoch(mostRecentWithdrawalTimestamp)), - "EigenPod.verifyWithdrawalCredentials: proof must be in the epoch after activation" - ); - - /** - * Withdrawal credential proof should not be "stale" (older than VERIFY_BALANCE_UPDATE_WINDOW_SECONDS) as we are doing a balance check here - * The validator container persists as the state evolves and even after the validator exits. So we can use a more "fresh" credential proof within - * the VERIFY_BALANCE_UPDATE_WINDOW_SECONDS window, not just the first proof where the validator container is registered in the state. - */ + // Calling this method using a `beaconTimestamp` <= `currentCheckpointTimestamp` would allow + // a newly-verified validator to be submitted to `verifyCheckpointProofs`, making progress + // on an existing checkpoint. require( - oracleTimestamp + VERIFY_BALANCE_UPDATE_WINDOW_SECONDS >= block.timestamp, + beaconTimestamp > currentCheckpointTimestamp, "EigenPod.verifyWithdrawalCredentials: specified timestamp is too far in past" ); - // Verify passed-in beaconStateRoot against oracle-provided block root: - BeaconChainProofs.verifyStateRootAgainstLatestBlockRoot({ - latestBlockRoot: eigenPodManager.getBlockRootAtTimestamp(oracleTimestamp), - beaconStateRoot: stateRootProof.beaconStateRoot, - stateRootProof: stateRootProof.proof + // Verify passed-in `beaconStateRoot` against the beacon block root + // forgefmt: disable-next-item + BeaconChainProofs.verifyStateRoot({ + beaconBlockRoot: getParentBlockRoot(beaconTimestamp), + proof: stateRootProof }); uint256 totalAmountToBeRestakedWei; for (uint256 i = 0; i < validatorIndices.length; i++) { + // forgefmt: disable-next-item totalAmountToBeRestakedWei += _verifyWithdrawalCredentials( - oracleTimestamp, stateRootProof.beaconStateRoot, validatorIndices[i], validatorFieldsProofs[i], @@ -355,18 +274,92 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen eigenPodManager.recordBeaconChainETHBalanceUpdate(podOwner, int256(totalAmountToBeRestakedWei)); } - /// @notice Called by the pod owner to withdraw the nonBeaconChainETHBalanceWei - function withdrawNonBeaconChainETHBalanceWei( - address recipient, - uint256 amountToWithdraw - ) external onlyEigenPodOwner onlyWhenNotPaused(PAUSED_NON_PROOF_WITHDRAWALS) { + /** + * @dev Prove that one of this pod's active validators was slashed on the beacon chain. A successful + * staleness proof allows the caller to start a checkpoint. + * + * @dev Note that in order to start a checkpoint, any existing checkpoint must already be completed! + * (See `_startCheckpoint` for details) + * + * @dev Note that this method allows anyone to start a checkpoint as soon as a slashing occurs on the beacon + * chain. This is intended to make it easier to external watchers to keep a pod's balance up to date. + * + * @dev Note too that beacon chain slashings are not instant. There is a delay between the initial slashing event + * and the validator's final exit back to the execution layer. During this time, the validator's balance may or + * may not drop further due to a correlation penalty. This method allows proof of a slashed validator + * to initiate a checkpoint for as long as the validator remains on the beacon chain. Once the validator + * has exited and been checkpointed at 0 balance, they are no longer "checkpoint-able" and cannot be proven + * "stale" via this method. + * See https://eth2book.info/capella/part3/transition/epoch/#slashings for more info. + * + * @param beaconTimestamp the beacon chain timestamp sent to the 4788 oracle contract. Corresponds + * to the parent beacon block root against which the proof is verified. + * @param stateRootProof proves a beacon state root against a beacon block root + * @param proof the fields of the beacon chain "Validator" container, along with a merkle proof against + * the beacon state root. See the consensus specs for more details: + * https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator + * + * @dev Staleness conditions: + * - Validator's last checkpoint is older than `beaconTimestamp` + * - Validator MUST be in `ACTIVE` status in the pod + * - Validator MUST be slashed on the beacon chain + */ + function verifyStaleBalance( + uint64 beaconTimestamp, + BeaconChainProofs.StateRootProof calldata stateRootProof, + BeaconChainProofs.ValidatorProof calldata proof + ) external onlyWhenNotPaused(PAUSED_START_CHECKPOINT) onlyWhenNotPaused(PAUSED_VERIFY_STALE_BALANCE) { + bytes32 validatorPubkey = proof.validatorFields.getPubkeyHash(); + ValidatorInfo memory validatorInfo = _validatorPubkeyHashToInfo[validatorPubkey]; + + // Validator must be eligible for a staleness proof. Generally, this condition + // ensures that the staleness proof is newer than the last time we got an update + // on this validator. + // + // Note: It is possible for `validatorInfo.lastCheckpointedAt` to be 0 if + // a validator's withdrawal credentials are verified when no checkpoint has + // ever been completed in this pod. Technically, this would mean that `beaconTimestamp` + // can be any valid EIP-4788 timestamp - because any nonzero value satisfies the + // require below. + // + // However, in practice, if the only update we've seen from a validator is their + // `verifyWithdrawalCredentials` proof, any valid `verifyStaleBalance` proof is + // necessarily newer. This is because when a validator is initially slashed, their + // exit epoch is set. And because `verifyWithdrawalCredentials` rejects validators + // that have initiated exits, we know that if we're seeing a proof where the validator + // is slashed that it MUST be newer than the `verifyWithdrawalCredentials` proof + // (regardless of the relationship between `beaconTimestamp` and `lastCheckpointedAt`). + require( + beaconTimestamp > validatorInfo.lastCheckpointedAt, + "EigenPod.verifyStaleBalance: proof is older than last checkpoint" + ); + + // Validator must be checkpoint-able + require(validatorInfo.status == VALIDATOR_STATUS.ACTIVE, "EigenPod.verifyStaleBalance: validator is not active"); + + // Validator must be slashed on the beacon chain require( - amountToWithdraw <= nonBeaconChainETHBalanceWei, - "EigenPod.withdrawnonBeaconChainETHBalanceWei: amountToWithdraw is greater than nonBeaconChainETHBalanceWei" + proof.validatorFields.isValidatorSlashed(), + "EigenPod.verifyStaleBalance: validator must be slashed to be marked stale" ); - nonBeaconChainETHBalanceWei -= amountToWithdraw; - emit NonBeaconChainETHWithdrawn(recipient, amountToWithdraw); - _sendETH_AsDelayedWithdrawal(recipient, amountToWithdraw); + + // Verify passed-in `beaconStateRoot` against the beacon block root + // forgefmt: disable-next-item + BeaconChainProofs.verifyStateRoot({ + beaconBlockRoot: getParentBlockRoot(beaconTimestamp), + proof: stateRootProof + }); + + // Verify Validator container proof against `beaconStateRoot` + BeaconChainProofs.verifyValidatorFields({ + beaconStateRoot: stateRootProof.beaconStateRoot, + validatorFields: proof.validatorFields, + validatorFieldsProof: proof.proof, + validatorIndex: uint40(validatorInfo.validatorIndex) + }); + + // Validator verified to be stale - start a checkpoint + _startCheckpoint(false); } /// @notice called by owner of a pod to remove any ERC20s deposited in the pod @@ -384,34 +377,18 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen } } - /** - * @notice Called by the pod owner to activate restaking by withdrawing - * all existing ETH from the pod and preventing further withdrawals via - * "withdrawBeforeRestaking()" - */ - function activateRestaking() - external - onlyWhenNotPaused(PAUSED_EIGENPODS_VERIFY_CREDENTIALS) - onlyEigenPodOwner - hasNeverRestaked - { - hasRestaked = true; - _processWithdrawalBeforeRestaking(podOwner); - - emit RestakingActivated(podOwner); + /// @notice Allows the owner of a pod to update the proof submitter, a permissioned + /// address that can call `startCheckpoint` and `verifyWithdrawalCredentials`. + /// @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` + function setProofSubmitter(address newProofSubmitter) external onlyEigenPodOwner { + emit ProofSubmitterUpdated(proofSubmitter, newProofSubmitter); + proofSubmitter = newProofSubmitter; } - /// @notice Called by the pod owner to withdraw the balance of the pod when `hasRestaked` is set to false - function withdrawBeforeRestaking() external onlyEigenPodOwner hasNeverRestaked { - _processWithdrawalBeforeRestaking(podOwner); - } - - /** - * - * EXTERNAL FUNCTIONS CALLABLE BY EIGENPODMANAGER - * - */ - /// @notice Called by EigenPodManager when the owner wants to create another ETH validator. function stake( bytes calldata pubkey, @@ -444,7 +421,7 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen withdrawableRestakedExecutionLayerGwei -= amountGwei; emit RestakedBeaconChainETHWithdrawn(recipient, amountWei); // transfer ETH from pod to `recipient` directly - _sendETH(recipient, amountWei); + Address.sendValue(payable(recipient), amountWei); } /** @@ -452,44 +429,83 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen * INTERNAL FUNCTIONS * */ + /** * @notice internal function that proves an individual validator's withdrawal credentials - * @param oracleTimestamp is the timestamp whose state root the `proof` will be proven against. * @param validatorIndex is the index of the validator being proven * @param validatorFieldsProof is the bytes that prove the ETH validator's withdrawal credentials against a beacon chain state root * @param validatorFields are the fields of the "Validator Container", refer to consensus specs */ function _verifyWithdrawalCredentials( - uint64 oracleTimestamp, bytes32 beaconStateRoot, uint40 validatorIndex, bytes calldata validatorFieldsProof, bytes32[] calldata validatorFields ) internal returns (uint256) { - bytes32 validatorPubkeyHash = validatorFields.getPubkeyHash(); - ValidatorInfo memory validatorInfo = _validatorPubkeyHashToInfo[validatorPubkeyHash]; + bytes32 pubkeyHash = validatorFields.getPubkeyHash(); + ValidatorInfo memory validatorInfo = _validatorPubkeyHashToInfo[pubkeyHash]; // Withdrawal credential proofs should only be processed for "INACTIVE" validators require( validatorInfo.status == VALIDATOR_STATUS.INACTIVE, - "EigenPod.verifyCorrectWithdrawalCredentials: Validator must be inactive to prove withdrawal credentials" + "EigenPod._verifyWithdrawalCredentials: validator must be inactive to prove withdrawal credentials" + ); + + // Validator should be active on the beacon chain, or in the process of activating. + // This implies the validator has reached the minimum effective balance required + // to become active on the beacon chain. + // + // This check is important because the Pectra upgrade will move any validators that + // do NOT have an activation epoch to a "pending deposit queue," temporarily resetting + // their current and effective balances to 0. This balance can be restored if a deposit + // is made to bring the validator's balance above the minimum activation balance. + // (See https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/fork.md#upgrading-the-state) + // + // In the context of EigenLayer slashing, this temporary reset would allow pod shares + // to temporarily decrease, then be restored later. This would effectively prevent these + // shares from being slashable on EigenLayer for a short period of time. + require( + validatorFields.getActivationEpoch() != BeaconChainProofs.FAR_FUTURE_EPOCH, + "EigenPod._verifyWithdrawalCredentials: validator must be in the process of activating" + ); + + // Validator should not already be in the process of exiting. This is an important property + // this method needs to enforce to ensure a validator cannot be already-exited by the time + // its withdrawal credentials are verified. + // + // Note that when a validator initiates an exit, two values are set: + // - exit_epoch + // - withdrawable_epoch + // + // The latter of these two values describes an epoch after which the validator's ETH MIGHT + // have been exited to the EigenPod, depending on the state of the beacon chain withdrawal + // queue. + // + // Requiring that a validator has not initiated exit by the time the EigenPod sees their + // withdrawal credentials guarantees that the validator has not fully exited at this point. + // + // This is because: + // - the earliest beacon chain slot allowed for withdrawal credential proofs is the earliest + // slot available in the EIP-4788 oracle, which keeps the last 8192 slots. + // - when initiating an exit, a validator's earliest possible withdrawable_epoch is equal to + // 1 + MAX_SEED_LOOKAHEAD + MIN_VALIDATOR_WITHDRAWABILITY_DELAY == 261 epochs (8352 slots). + // + // (See https://eth2book.info/capella/part3/helper/mutators/#initiate_validator_exit) + require( + validatorFields.getExitEpoch() == BeaconChainProofs.FAR_FUTURE_EPOCH, + "EigenPod._verifyWithdrawalCredentials: validator must not be exiting" ); - // Ensure the `validatorFields` we're proving have the correct withdrawal credentials + // Ensure the validator's withdrawal credentials are pointed at this pod require( validatorFields.getWithdrawalCredentials() == bytes32(_podWithdrawalCredentials()), - "EigenPod.verifyCorrectWithdrawalCredentials: Proof is not for this EigenPod" + "EigenPod._verifyWithdrawalCredentials: proof is not for this EigenPod" ); - /** - * Deserialize the balance field from the Validator struct. Note that this is the "effective" balance of the validator - * rather than the current balance. Effective balance is generated via a hystersis function such that an effective - * balance, always a multiple of 1 ETH, will only lower to the next multiple of 1 ETH if the current balance is less - * than 0.25 ETH below their current effective balance. For example, if the effective balance is 31ETH, it only falls to - * 30ETH when the true balance falls below 30.75ETH. Thus in the worst case, the effective balance is overestimating the - * actual validator balance by 0.25 ETH. - */ - uint64 validatorEffectiveBalanceGwei = validatorFields.getEffectiveBalanceGwei(); + // Get the validator's effective balance. Note that this method uses effective balance, while + // `verifyCheckpointProofs` uses current balance. Effective balance is updated per-epoch - so it's + // less accurate, but is good enough for verifying withdrawal credentials. + uint64 restakedBalanceGwei = validatorFields.getEffectiveBalanceGwei(); // Verify passed-in validatorFields against verified beaconStateRoot: BeaconChainProofs.verifyValidatorFields({ @@ -499,250 +515,162 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen validatorIndex: validatorIndex }); - // Proofs complete - update this validator's status, record its proven balance, and save in state: + // Account for validator in future checkpoints. Note that if this pod has never started a + // checkpoint before, `lastCheckpointedAt` will be zero here. This is fine because the main + // purpose of `lastCheckpointedAt` is to enforce that newly-verified validators are not + // eligible to progress already-existing checkpoints - however in this case, no checkpoints exist. activeValidatorCount++; - validatorInfo.status = VALIDATOR_STATUS.ACTIVE; - validatorInfo.validatorIndex = validatorIndex; - validatorInfo.mostRecentBalanceUpdateTimestamp = oracleTimestamp; - - if (validatorEffectiveBalanceGwei > MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) { - validatorInfo.restakedBalanceGwei = MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; - } else { - validatorInfo.restakedBalanceGwei = validatorEffectiveBalanceGwei; - } - _validatorPubkeyHashToInfo[validatorPubkeyHash] = validatorInfo; + uint64 lastCheckpointedAt = + currentCheckpointTimestamp == 0 ? lastCheckpointTimestamp : currentCheckpointTimestamp; + + // Proofs complete - create the validator in state + _validatorPubkeyHashToInfo[pubkeyHash] = ValidatorInfo({ + validatorIndex: validatorIndex, + restakedBalanceGwei: restakedBalanceGwei, + lastCheckpointedAt: lastCheckpointedAt, + status: VALIDATOR_STATUS.ACTIVE + }); emit ValidatorRestaked(validatorIndex); - emit ValidatorBalanceUpdated(validatorIndex, oracleTimestamp, validatorInfo.restakedBalanceGwei); - - return validatorInfo.restakedBalanceGwei * GWEI_TO_WEI; - } - - function _verifyBalanceUpdate( - uint64 oracleTimestamp, - uint40 validatorIndex, - bytes32 beaconStateRoot, - bytes calldata validatorFieldsProof, - bytes32[] calldata validatorFields - ) internal returns (int256 sharesDeltaGwei) { - uint64 validatorEffectiveBalanceGwei = validatorFields.getEffectiveBalanceGwei(); - bytes32 validatorPubkeyHash = validatorFields.getPubkeyHash(); - ValidatorInfo memory validatorInfo = _validatorPubkeyHashToInfo[validatorPubkeyHash]; - - // 1. Balance updates should be more recent than the most recent update - require( - validatorInfo.mostRecentBalanceUpdateTimestamp < oracleTimestamp, - "EigenPod.verifyBalanceUpdate: Validators balance has already been updated for this timestamp" - ); - - // 2. Balance updates should only be performed on "ACTIVE" validators - require(validatorInfo.status == VALIDATOR_STATUS.ACTIVE, "EigenPod.verifyBalanceUpdate: Validator not active"); - - // 3. Balance updates should only be made before a validator is fully withdrawn. - // -- A withdrawable validator may not have withdrawn yet, so we require their balance is nonzero - // -- A fully withdrawn validator should withdraw via verifyAndProcessWithdrawals - if (validatorFields.getWithdrawableEpoch() <= _timestampToEpoch(oracleTimestamp)) { - require( - validatorEffectiveBalanceGwei > 0, - "EigenPod.verifyBalanceUpdate: validator is withdrawable but has not withdrawn" - ); - } - - // Verify passed-in validatorFields against verified beaconStateRoot: - BeaconChainProofs.verifyValidatorFields({ - beaconStateRoot: beaconStateRoot, - validatorFields: validatorFields, - validatorFieldsProof: validatorFieldsProof, - validatorIndex: validatorIndex + emit ValidatorBalanceUpdated(validatorIndex, lastCheckpointedAt, restakedBalanceGwei); + return restakedBalanceGwei * GWEI_TO_WEI; + } + + function _verifyCheckpointProof( + ValidatorInfo memory validatorInfo, + uint64 checkpointTimestamp, + bytes32 balanceContainerRoot, + BeaconChainProofs.BalanceProof calldata proof + ) internal returns (int128 balanceDeltaGwei, uint64 exitedBalanceGwei) { + uint40 validatorIndex = uint40(validatorInfo.validatorIndex); + + // Verify validator balance against `balanceContainerRoot` + uint64 prevBalanceGwei = validatorInfo.restakedBalanceGwei; + uint64 newBalanceGwei = BeaconChainProofs.verifyValidatorBalance({ + balanceContainerRoot: balanceContainerRoot, + validatorIndex: validatorIndex, + proof: proof }); - // Done with proofs! Now update the validator's balance and send to the EigenPodManager if needed + // Calculate change in the validator's balance since the last proof + if (newBalanceGwei != prevBalanceGwei) { + // forgefmt: disable-next-item + balanceDeltaGwei = _calcBalanceDelta({ + newAmountGwei: newBalanceGwei, + previousAmountGwei: prevBalanceGwei + }); - uint64 currentRestakedBalanceGwei = validatorInfo.restakedBalanceGwei; - uint64 newRestakedBalanceGwei; - if (validatorEffectiveBalanceGwei > MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) { - newRestakedBalanceGwei = MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; - } else { - newRestakedBalanceGwei = validatorEffectiveBalanceGwei; + emit ValidatorBalanceUpdated(validatorIndex, checkpointTimestamp, newBalanceGwei); } - // Update validator balance and timestamp, and save to state: - validatorInfo.restakedBalanceGwei = newRestakedBalanceGwei; - validatorInfo.mostRecentBalanceUpdateTimestamp = oracleTimestamp; - _validatorPubkeyHashToInfo[validatorPubkeyHash] = validatorInfo; + validatorInfo.restakedBalanceGwei = newBalanceGwei; + validatorInfo.lastCheckpointedAt = checkpointTimestamp; - // If our new and old balances differ, calculate the delta and send to the EigenPodManager - if (newRestakedBalanceGwei != currentRestakedBalanceGwei) { - emit ValidatorBalanceUpdated(validatorIndex, oracleTimestamp, newRestakedBalanceGwei); + // If the validator's new balance is 0, mark them withdrawn + if (newBalanceGwei == 0) { + activeValidatorCount--; + validatorInfo.status = VALIDATOR_STATUS.WITHDRAWN; + // If we reach this point, `balanceDeltaGwei` should always be negative, + // so this should be a safe conversion + exitedBalanceGwei = uint64(uint128(-balanceDeltaGwei)); - sharesDeltaGwei = _calculateSharesDelta({ - newAmountGwei: newRestakedBalanceGwei, - previousAmountGwei: currentRestakedBalanceGwei - }); + emit ValidatorWithdrawn(checkpointTimestamp, validatorIndex); } - } - function _verifyAndProcessWithdrawal( - bytes32 beaconStateRoot, - BeaconChainProofs.WithdrawalProof calldata withdrawalProof, - bytes calldata validatorFieldsProof, - bytes32[] calldata validatorFields, - bytes32[] calldata withdrawalFields - ) - internal - /** - * Check that the provided timestamp being proven against is after the `mostRecentWithdrawalTimestamp`. - * Without this check, there is an edge case where a user proves a past withdrawal for a validator whose funds they already withdrew, - * as a way to "withdraw the same funds twice" without providing adequate proof. - * Note that this check is not made using the oracleTimestamp as in the `verifyWithdrawalCredentials` proof; instead this proof - * proof is made for the timestamp of the withdrawal, which may be within SLOTS_PER_HISTORICAL_ROOT slots of the oracleTimestamp. - * This difference in modifier usage is OK, since it is still not possible to `verifyAndProcessWithdrawal` against a slot that occurred - * *prior* to the proof provided in the `verifyWithdrawalCredentials` function. - */ - proofIsForValidTimestamp(withdrawalProof.getWithdrawalTimestamp()) - returns (VerifiedWithdrawal memory) - { - uint64 withdrawalTimestamp = withdrawalProof.getWithdrawalTimestamp(); - bytes32 validatorPubkeyHash = validatorFields.getPubkeyHash(); + return (balanceDeltaGwei, exitedBalanceGwei); + } - /** - * Withdrawal processing should only be performed for "ACTIVE" or "WITHDRAWN" validators. - * (WITHDRAWN is allowed because technically you can deposit to a validator even after it exits) - */ + /** + * @dev Initiate a checkpoint proof by snapshotting both the pod's ETH balance and the + * current block's parent block root. After providing a checkpoint proof for each of the + * pod's ACTIVE validators, the pod's ETH balance is awarded shares and can be withdrawn. + * @dev ACTIVE validators are validators with verified withdrawal credentials (See + * `verifyWithdrawalCredentials` for details) + * @dev If the pod does not have any ACTIVE validators, the checkpoint is automatically + * finalized. + * @dev Once started, a checkpoint MUST be completed! It is not possible to start a + * checkpoint if the existing one is incomplete. + * @param revertIfNoBalance If the available ETH balance for checkpointing is 0 and this is + * true, this method will revert + */ + function _startCheckpoint(bool revertIfNoBalance) internal { require( - _validatorPubkeyHashToInfo[validatorPubkeyHash].status != VALIDATOR_STATUS.INACTIVE, - "EigenPod._verifyAndProcessWithdrawal: Validator never proven to have withdrawal credentials pointed to this contract" + currentCheckpointTimestamp == 0, + "EigenPod._startCheckpoint: must finish previous checkpoint before starting another" ); - // Ensure we don't process the same withdrawal twice + // Prevent a checkpoint being completable twice in the same block. This prevents an edge case + // where the second checkpoint would not be completable. + // + // This is because the validators checkpointed in the first checkpoint would have a `lastCheckpointedAt` + // value equal to the second checkpoint, causing their proofs to get skipped in `verifyCheckpointProofs` require( - !provenWithdrawal[validatorPubkeyHash][withdrawalTimestamp], - "EigenPod._verifyAndProcessWithdrawal: withdrawal has already been proven for this timestamp" + lastCheckpointTimestamp != uint64(block.timestamp), + "EigenPod._startCheckpoint: cannot checkpoint twice in one block" ); - provenWithdrawal[validatorPubkeyHash][withdrawalTimestamp] = true; + // Snapshot pod balance at the start of the checkpoint, subtracting pod balance that has + // previously been credited with shares. Once the checkpoint is finalized, `podBalanceGwei` + // will be added to the total validator balance delta and credited as shares. + // + // Note: On finalization, `podBalanceGwei` is added to `withdrawableRestakedExecutionLayerGwei` + // to denote that it has been credited with shares. Because this value is denominated in gwei, + // `podBalanceGwei` is also converted to a gwei amount here. This means that any sub-gwei amounts + // sent to the pod are not credited with shares and are therefore not withdrawable. + // This can be addressed by topping up a pod's balance to a value divisible by 1 gwei. + uint64 podBalanceGwei = uint64(address(this).balance / GWEI_TO_WEI) - withdrawableRestakedExecutionLayerGwei; + + // If the caller doesn't want a "0 balance" checkpoint, revert + if (revertIfNoBalance && podBalanceGwei == 0) { + revert("EigenPod._startCheckpoint: no balance available to checkpoint"); + } - // Verifying the withdrawal against verified beaconStateRoot: - BeaconChainProofs.verifyWithdrawal({ - beaconStateRoot: beaconStateRoot, - withdrawalFields: withdrawalFields, - withdrawalProof: withdrawalProof, - denebForkTimestamp: eigenPodManager.denebForkTimestamp() + // Create checkpoint using the previous block's root for proofs, and the current + // `activeValidatorCount` as the number of checkpoint proofs needed to finalize + // the checkpoint. + Checkpoint memory checkpoint = Checkpoint({ + beaconBlockRoot: getParentBlockRoot(uint64(block.timestamp)), + proofsRemaining: uint24(activeValidatorCount), + podBalanceGwei: podBalanceGwei, + balanceDeltasGwei: 0 }); - uint40 validatorIndex = withdrawalFields.getValidatorIndex(); - - // Verify passed-in validatorFields against verified beaconStateRoot: - BeaconChainProofs.verifyValidatorFields({ - beaconStateRoot: beaconStateRoot, - validatorFields: validatorFields, - validatorFieldsProof: validatorFieldsProof, - validatorIndex: validatorIndex - }); + // Place checkpoint in storage. If `proofsRemaining` is 0, the checkpoint + // is automatically finalized. + currentCheckpointTimestamp = uint64(block.timestamp); + _updateCheckpoint(checkpoint); - uint64 withdrawalAmountGwei = withdrawalFields.getWithdrawalAmountGwei(); - - /** - * If the withdrawal's epoch comes after the validator's "withdrawable epoch," we know the validator - * has fully withdrawn, and we process this as a full withdrawal. - */ - if (withdrawalProof.getWithdrawalEpoch() >= validatorFields.getWithdrawableEpoch()) { - return _processFullWithdrawal( - validatorIndex, - validatorPubkeyHash, - withdrawalTimestamp, - podOwner, - withdrawalAmountGwei, - _validatorPubkeyHashToInfo[validatorPubkeyHash] - ); - } else { - return _processPartialWithdrawal(validatorIndex, withdrawalTimestamp, podOwner, withdrawalAmountGwei); - } + emit CheckpointCreated(uint64(block.timestamp), checkpoint.beaconBlockRoot, checkpoint.proofsRemaining); } - function _processFullWithdrawal( - uint40 validatorIndex, - bytes32 validatorPubkeyHash, - uint64 withdrawalTimestamp, - address recipient, - uint64 withdrawalAmountGwei, - ValidatorInfo memory validatorInfo - ) internal returns (VerifiedWithdrawal memory) { - /** - * First, determine withdrawal amounts. We need to know: - * 1. How much can be withdrawn immediately - * 2. How much needs to be withdrawn via the EigenLayer withdrawal queue - */ - uint64 amountToQueueGwei; - - if (withdrawalAmountGwei > MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) { - amountToQueueGwei = MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; + /** + * @dev Finish progress on a checkpoint and store it in state. + * @dev If the checkpoint has no proofs remaining, it is finalized: + * - a share delta is calculated and sent to the `EigenPodManager` + * - the checkpointed `podBalanceGwei` is added to `withdrawableRestakedExecutionLayerGwei` + * - `lastCheckpointTimestamp` is updated + * - `_currentCheckpoint` and `currentCheckpointTimestamp` are deleted + */ + function _updateCheckpoint(Checkpoint memory checkpoint) internal { + if (checkpoint.proofsRemaining == 0) { + int256 totalShareDeltaWei = + (int128(uint128(checkpoint.podBalanceGwei)) + checkpoint.balanceDeltasGwei) * int256(GWEI_TO_WEI); + + // Add any native ETH in the pod to `withdrawableRestakedExecutionLayerGwei` + // ... this amount can be withdrawn via the `DelegationManager` withdrawal queue + withdrawableRestakedExecutionLayerGwei += checkpoint.podBalanceGwei; + + // Finalize the checkpoint + lastCheckpointTimestamp = currentCheckpointTimestamp; + delete currentCheckpointTimestamp; + delete _currentCheckpoint; + + // Update pod owner's shares + eigenPodManager.recordBeaconChainETHBalanceUpdate(podOwner, totalShareDeltaWei); + emit CheckpointFinalized(lastCheckpointTimestamp, totalShareDeltaWei); } else { - amountToQueueGwei = withdrawalAmountGwei; + _currentCheckpoint = checkpoint; } - - /** - * If the withdrawal is for more than the max per-validator balance, we mark - * the max as "withdrawable" via the queue, and withdraw the excess immediately - */ - VerifiedWithdrawal memory verifiedWithdrawal; - verifiedWithdrawal.amountToSendGwei = uint256(withdrawalAmountGwei - amountToQueueGwei); - withdrawableRestakedExecutionLayerGwei += amountToQueueGwei; - - /** - * Next, calculate the change in number of shares this validator is "backing": - * - Anything that needs to go through the withdrawal queue IS backed - * - Anything immediately withdrawn IS NOT backed - * - * This means that this validator is currently backing `amountToQueueGwei` shares. - */ - verifiedWithdrawal.sharesDeltaGwei = _calculateSharesDelta({ - newAmountGwei: amountToQueueGwei, - previousAmountGwei: validatorInfo.restakedBalanceGwei - }); - - /** - * Finally, the validator is fully withdrawn. Update their status and place in state: - */ - if (validatorInfo.status != VALIDATOR_STATUS.WITHDRAWN) { - activeValidatorCount--; - validatorInfo.status = VALIDATOR_STATUS.WITHDRAWN; - } - - validatorInfo.restakedBalanceGwei = 0; - _validatorPubkeyHashToInfo[validatorPubkeyHash] = validatorInfo; - - emit FullWithdrawalRedeemed(validatorIndex, withdrawalTimestamp, recipient, withdrawalAmountGwei); - - return verifiedWithdrawal; - } - - function _processPartialWithdrawal( - uint40 validatorIndex, - uint64 withdrawalTimestamp, - address recipient, - uint64 partialWithdrawalAmountGwei - ) internal returns (VerifiedWithdrawal memory) { - emit PartialWithdrawalRedeemed(validatorIndex, withdrawalTimestamp, recipient, partialWithdrawalAmountGwei); - - sumOfPartialWithdrawalsClaimedGwei += partialWithdrawalAmountGwei; - - // For partial withdrawals, the withdrawal amount is immediately sent to the pod owner - return VerifiedWithdrawal({amountToSendGwei: uint256(partialWithdrawalAmountGwei), sharesDeltaGwei: 0}); - } - - function _processWithdrawalBeforeRestaking(address _podOwner) internal { - mostRecentWithdrawalTimestamp = uint32(block.timestamp); - nonBeaconChainETHBalanceWei = 0; - _sendETH_AsDelayedWithdrawal(_podOwner, address(this).balance); - } - - function _sendETH(address recipient, uint256 amountWei) internal { - Address.sendValue(payable(recipient), amountWei); - } - - function _sendETH_AsDelayedWithdrawal(address recipient, uint256 amountWei) internal { - delayedWithdrawalRouter.createDelayedWithdrawal{value: amountWei}(podOwner, recipient); } function _podWithdrawalCredentials() internal view returns (bytes memory) { @@ -755,28 +683,9 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen return sha256(abi.encodePacked(validatorPubkey, bytes16(0))); } - /** - * Calculates delta between two share amounts and returns as an int256 - */ - function _calculateSharesDelta(uint64 newAmountGwei, uint64 previousAmountGwei) internal pure returns (int256) { - return int256(uint256(newAmountGwei)) - int256(uint256(previousAmountGwei)); - } - - /** - * @dev Converts a timestamp to a beacon chain epoch by calculating the number of - * seconds since genesis, and dividing by seconds per epoch. - * reference: https://github.com/ethereum/consensus-specs/blob/ce240ca795e257fc83059c4adfd591328c7a7f21/specs/bellatrix/beacon-chain.md#compute_timestamp_at_slot - */ - function _timestampToEpoch(uint64 timestamp) internal view returns (uint64) { - require(timestamp >= GENESIS_TIME, "EigenPod._timestampToEpoch: timestamp is before genesis"); - return (timestamp - GENESIS_TIME) / BeaconChainProofs.SECONDS_PER_EPOCH; - } - - /** - * @dev Given an epoch number, calculates the timestamp of the first slot in the following epoch - */ - function _nextEpochStartTimestamp(uint64 epoch) internal view returns (uint64) { - return GENESIS_TIME + ((1 + epoch) * BeaconChainProofs.SECONDS_PER_EPOCH); + /// @dev Calculates the delta between two Gwei amounts and returns as an int256 + function _calcBalanceDelta(uint64 newAmountGwei, uint64 previousAmountGwei) internal pure returns (int128) { + return int128(uint128(newAmountGwei)) - int128(uint128(previousAmountGwei)); } /** @@ -784,6 +693,8 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen * VIEW FUNCTIONS * */ + + /// @notice Returns the validatorInfo for a given validatorPubkeyHash function validatorPubkeyHashToInfo(bytes32 validatorPubkeyHash) external view returns (ValidatorInfo memory) { return _validatorPubkeyHashToInfo[validatorPubkeyHash]; } @@ -803,10 +714,24 @@ contract EigenPod is IEigenPod, Initializable, ReentrancyGuardUpgradeable, Eigen return _validatorPubkeyHashToInfo[validatorPubkeyHash].status; } - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[44] private __gap; + /// @notice Returns the currently-active checkpoint + function currentCheckpoint() public view returns (Checkpoint memory) { + return _currentCheckpoint; + } + + /// @notice Query the 4788 oracle to get the parent block root of the slot with the given `timestamp` + /// @param timestamp of the block for which the parent block root will be returned. MUST correspond + /// to an existing slot within the last 24 hours. If the slot at `timestamp` was skipped, this method + /// will revert. + function getParentBlockRoot(uint64 timestamp) public view returns (bytes32) { + require( + block.timestamp - timestamp < BEACON_ROOTS_HISTORY_BUFFER_LENGTH * 12, + "EigenPod.getParentBlockRoot: timestamp out of range" + ); + + (bool success, bytes memory result) = BEACON_ROOTS_ADDRESS.staticcall(abi.encode(timestamp)); + + require(success && result.length > 0, "EigenPod.getParentBlockRoot: invalid block root returned"); + return abi.decode(result, (bytes32)); + } } diff --git a/src/contracts/pods/EigenPodManager.sol b/src/contracts/pods/EigenPodManager.sol index 8ea4a2a2a..300f36de0 100644 --- a/src/contracts/pods/EigenPodManager.sol +++ b/src/contracts/pods/EigenPodManager.sol @@ -6,8 +6,6 @@ import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol"; -import "../interfaces/IBeaconChainOracle.sol"; - import "../permissions/Pausable.sol"; import "./EigenPodPausingConstants.sol"; import "./EigenPodManagerStorage.sol"; @@ -53,12 +51,10 @@ contract EigenPodManager is } function initialize( - IBeaconChainOracle _beaconChainOracle, address initialOwner, IPauserRegistry _pauserRegistry, uint256 _initPausedStatus ) external initializer { - _updateBeaconChainOracle(_beaconChainOracle); _transferOwnership(initialOwner); _initializePauser(_pauserRegistry, _initPausedStatus); } @@ -141,6 +137,7 @@ contract EigenPodManager is } } emit PodSharesUpdated(podOwner, sharesDelta); + emit NewTotalShares(podOwner, updatedPodOwnerShares); } /** @@ -161,6 +158,8 @@ contract EigenPodManager is "EigenPodManager.removeShares: cannot result in pod owner having negative shares" ); podOwnerShares[podOwner] = updatedPodOwnerShares; + + emit NewTotalShares(podOwner, updatedPodOwnerShares); } /** @@ -179,6 +178,7 @@ contract EigenPodManager is podOwnerShares[podOwner] = updatedPodOwnerShares; emit PodSharesUpdated(podOwner, int256(shares)); + emit NewTotalShares(podOwner, updatedPodOwnerShares); return uint256( _calculateChangeInDelegatableShares({ @@ -209,15 +209,19 @@ contract EigenPodManager is // if there is an existing shares deficit, prioritize decreasing the deficit first if (currentPodOwnerShares < 0) { uint256 currentShareDeficit = uint256(-currentPodOwnerShares); - // get rid of the whole deficit if possible, and pass any remaining shares onto destination + if (shares > currentShareDeficit) { + // get rid of the whole deficit if possible, and pass any remaining shares onto destination podOwnerShares[podOwner] = 0; shares -= currentShareDeficit; emit PodSharesUpdated(podOwner, int256(currentShareDeficit)); - // otherwise get rid of as much deficit as possible, and return early, since there is nothing left over to forward on + emit NewTotalShares(podOwner, 0); } else { - podOwnerShares[podOwner] += int256(shares); + // otherwise get rid of as much deficit as possible, and return early, since there is nothing left over to forward on + int256 updatedPodOwnerShares = podOwnerShares[podOwner] + int256(shares); + podOwnerShares[podOwner] = updatedPodOwnerShares; emit PodSharesUpdated(podOwner, int256(shares)); + emit NewTotalShares(podOwner, updatedPodOwnerShares); return; } } @@ -225,32 +229,6 @@ contract EigenPodManager is ownerToPod[podOwner].withdrawRestakedBeaconChainETH(destination, shares); } - /** - * @notice Updates the oracle contract that provides the beacon chain state root - * @param newBeaconChainOracle is the new oracle contract being pointed to - * @dev Callable only by the owner of this contract (i.e. governance) - */ - function updateBeaconChainOracle(IBeaconChainOracle newBeaconChainOracle) external onlyOwner { - _updateBeaconChainOracle(newBeaconChainOracle); - } - - /** - * @notice Sets the timestamp of the Deneb fork. - * @param newDenebForkTimestamp is the new timestamp of the Deneb fork - */ - function setDenebForkTimestamp(uint64 newDenebForkTimestamp) external onlyOwner { - require( - newDenebForkTimestamp != 0, "EigenPodManager.setDenebForkTimestamp: cannot set newDenebForkTimestamp to 0" - ); - require( - _denebForkTimestamp == 0, - "EigenPodManager.setDenebForkTimestamp: cannot set denebForkTimestamp more than once" - ); - - _denebForkTimestamp = newDenebForkTimestamp; - emit DenebForkTimestampUpdated(newDenebForkTimestamp); - } - // INTERNAL FUNCTIONS function _deployPod() internal returns (IEigenPod) { @@ -271,12 +249,6 @@ contract EigenPodManager is return pod; } - /// @notice Internal setter for `beaconChainOracle` that also emits an event - function _updateBeaconChainOracle(IBeaconChainOracle newBeaconChainOracle) internal { - beaconChainOracle = newBeaconChainOracle; - emit BeaconOracleUpdated(address(newBeaconChainOracle)); - } - /** * @notice Calculates the change in a pod owner's delegateable shares as a result of their beacon chain ETH shares changing * from `sharesBefore` to `sharesAfter`. The key concept here is that negative/"deficit" shares are not delegateable. @@ -325,27 +297,4 @@ contract EigenPodManager is function hasPod(address podOwner) public view returns (bool) { return address(ownerToPod[podOwner]) != address(0); } - - /// @notice Returns the Beacon block root at `timestamp`. Reverts if the Beacon block root at `timestamp` has not yet been finalized. - function getBlockRootAtTimestamp(uint64 timestamp) external view returns (bytes32) { - bytes32 stateRoot = beaconChainOracle.timestampToBlockRoot(timestamp); - require( - stateRoot != bytes32(0), - "EigenPodManager.getBlockRootAtTimestamp: state root at timestamp not yet finalized" - ); - return stateRoot; - } - - /** - * @notice Wrapper around the `_denebForkTimestamp` storage variable that returns type(uint64).max if the storage variable is unset. - * @dev This allows restricting the storage variable to be set once and only once. - */ - function denebForkTimestamp() public view returns (uint64) { - uint64 timestamp = _denebForkTimestamp; - if (timestamp == 0) { - return type(uint64).max; - } else { - return timestamp; - } - } } diff --git a/src/contracts/pods/EigenPodManagerStorage.sol b/src/contracts/pods/EigenPodManagerStorage.sol index 39c98f2c2..d85c0a178 100644 --- a/src/contracts/pods/EigenPodManagerStorage.sol +++ b/src/contracts/pods/EigenPodManagerStorage.sol @@ -11,6 +11,12 @@ import "../interfaces/IETHPOSDeposit.sol"; import "../interfaces/IEigenPod.sol"; abstract contract EigenPodManagerStorage is IEigenPodManager { + /** + * + * CONSTANTS / IMMUTABLES + * + */ + /// @notice The ETH2 Deposit Contract IETHPOSDeposit public immutable ethPOS; @@ -40,8 +46,14 @@ abstract contract EigenPodManagerStorage is IEigenPodManager { /// @notice Canonical, virtual beacon chain ETH strategy IStrategy public constant beaconChainETHStrategy = IStrategy(0xbeaC0eeEeeeeEEeEeEEEEeeEEeEeeeEeeEEBEaC0); - /// @notice Oracle contract that provides updates to the beacon chain's state - IBeaconChainOracle public beaconChainOracle; + /** + * + * STATE VARIABLES + * + */ + + /// @notice [DEPRECATED] Previously used to query beacon block roots. We now use eip-4788 directly + address internal __deprecated_beaconChainOracle; /// @notice Pod owner to deployed EigenPod address mapping(address => IEigenPod) public ownerToPod; @@ -50,7 +62,7 @@ abstract contract EigenPodManagerStorage is IEigenPodManager { /// @notice The number of EigenPods that have been deployed uint256 public numPods; - /// @notice Deprecated from old mainnet release. Was initially used to limit growth early on but there is no longer + /// @notice [DEPRECATED] Was initially used to limit growth early on but there is no longer /// a maximum number of EigenPods that can be deployed. uint256 private __deprecated_maxPods; @@ -65,7 +77,7 @@ abstract contract EigenPodManagerStorage is IEigenPodManager { */ mapping(address => int256) public podOwnerShares; - uint64 internal _denebForkTimestamp; + uint64 internal __deprecated_denebForkTimestamp; constructor( IETHPOSDeposit _ethPOS, diff --git a/src/contracts/pods/EigenPodPausingConstants.sol b/src/contracts/pods/EigenPodPausingConstants.sol index f7eca3ece..e731747a6 100644 --- a/src/contracts/pods/EigenPodPausingConstants.sol +++ b/src/contracts/pods/EigenPodPausingConstants.sol @@ -17,10 +17,20 @@ abstract contract EigenPodPausingConstants { /// @notice Index for flag that pauses the deposit related functions *of the EigenPods* when set. see EigenPod code for details. uint8 internal constant PAUSED_EIGENPODS_VERIFY_CREDENTIALS = 2; - /// @notice Index for flag that pauses the `verifyBalanceUpdate` function *of the EigenPods* when set. see EigenPod code for details. - uint8 internal constant PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE = 3; - /// @notice Index for flag that pauses the `verifyBeaconChainFullWithdrawal` function *of the EigenPods* when set. see EigenPod code for details. - uint8 internal constant PAUSED_EIGENPODS_VERIFY_WITHDRAWAL = 4; + + // Deprecated + // uint8 internal constant PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE = 3; + + // Deprecated + // uint8 internal constant PAUSED_EIGENPODS_VERIFY_WITHDRAWAL = 4; + /// @notice Pausability for EigenPod's "accidental transfer" withdrawal methods uint8 internal constant PAUSED_NON_PROOF_WITHDRAWALS = 5; + + uint8 internal constant PAUSED_START_CHECKPOINT = 6; + + /// @notice Index for flag that pauses the `verifyCheckpointProofs` function *of the EigenPods* when set. see EigenPod code for details. + uint8 internal constant PAUSED_EIGENPODS_VERIFY_CHECKPOINT_PROOFS = 7; + + uint8 internal constant PAUSED_VERIFY_STALE_BALANCE = 8; } diff --git a/src/contracts/pods/EigenPodStorage.sol b/src/contracts/pods/EigenPodStorage.sol new file mode 100644 index 000000000..43bd494b8 --- /dev/null +++ b/src/contracts/pods/EigenPodStorage.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "../interfaces/IEigenPod.sol"; + +abstract contract EigenPodStorage is IEigenPod { + /// @notice The owner of this EigenPod + address public podOwner; + + /// @notice DEPRECATED: previously used to track the time when restaking was activated + uint64 internal __deprecated_mostRecentWithdrawalTimestamp; + + /// @notice the amount of execution layer ETH in this contract that is staked in EigenLayer (i.e. withdrawn from the Beacon Chain but not from EigenLayer), + uint64 public withdrawableRestakedExecutionLayerGwei; + + /// @notice DEPRECATED: previously used to track whether a pod had activated restaking + bool internal __deprecated_hasRestaked; + + /// @notice DEPRECATED: previously tracked withdrawals proven per validator + mapping(bytes32 => mapping(uint64 => bool)) internal __deprecated_provenWithdrawal; + + /// @notice This is a mapping that tracks a validator's information by their pubkey hash + mapping(bytes32 => ValidatorInfo) internal _validatorPubkeyHashToInfo; + + /// @notice DEPRECATED: previously used to track ETH sent to the fallback function + uint256 internal __deprecated_nonBeaconChainETHBalanceWei; + + /// @notice DEPRECATED: previously used to track claimed partial withdrawals + uint64 __deprecated_sumOfPartialWithdrawalsClaimedGwei; + + /// @notice Number of validators with proven withdrawal credentials, who do not have proven full withdrawals + uint256 public activeValidatorCount; + + /// @notice The timestamp of the last checkpoint finalized + uint64 public lastCheckpointTimestamp; + + /// @notice The timestamp of the currently-active checkpoint. Will be 0 if there is not active checkpoint + uint64 public currentCheckpointTimestamp; + + /// @notice For each checkpoint, the total balance attributed to exited validators, in gwei + /// + /// NOTE that the values added to this mapping are NOT guaranteed to capture the entirety of a validator's + /// exit - rather, they capture the total change in a validator's balance when a checkpoint shows their + /// balance change from nonzero to zero. While a change from nonzero to zero DOES guarantee that a validator + /// has been fully exited, it is possible that the magnitude of this change does not capture what is + /// typically thought of as a "full exit." + /// + /// For example: + /// 1. Consider a validator was last checkpointed at 32 ETH before exiting. Once the exit has been processed, + /// it is expected that the validator's exited balance is calculated to be `32 ETH`. + /// 2. However, before `startCheckpoint` is called, a deposit is made to the validator for 1 ETH. The beacon + /// chain will automatically withdraw this ETH, but not until the withdrawal sweep passes over the validator + /// again. Until this occurs, the validator's current balance (used for checkpointing) is 1 ETH. + /// 3. If `startCheckpoint` is called at this point, the balance delta calculated for this validator will be + /// `-31 ETH`, and because the validator has a nonzero balance, it is not marked WITHDRAWN. + /// 4. After the exit is processed by the beacon chain, a subsequent `startCheckpoint` and checkpoint proof + /// will calculate a balance delta of `-1 ETH` and attribute a 1 ETH exit to the validator. + /// + /// If this edge case impacts your usecase, it should be possible to mitigate this by monitoring for deposits + /// to your exited validators, and waiting to call `startCheckpoint` until those deposits have been automatically + /// exited. + /// + /// Additional edge cases this mapping does not cover: + /// - If a validator is slashed, their balance exited will reflect their original balance rather than the slashed amount + /// - The final partial withdrawal for an exited validator will be likely be included in this mapping. + /// i.e. if a validator was last checkpointed at 32.1 ETH before exiting, the next checkpoint will calculate their + /// "exited" amount to be 32.1 ETH rather than 32 ETH. + mapping(uint64 => uint64) public checkpointBalanceExitedGwei; + + /// @notice The current checkpoint, if there is one active + Checkpoint internal _currentCheckpoint; + + /// @notice An address with permissions to call `startCheckpoint` and `verifyWithdrawalCredentials`, set + /// by the podOwner. This role exists to allow a podOwner to designate a hot wallet that can call + /// these methods, allowing the podOwner to remain a cold wallet that is only used to manage funds. + /// @dev If this address is NOT set, only the podOwner can call `startCheckpoint` and `verifyWithdrawalCredentials` + address public proofSubmitter; + + /** + * @dev This empty reserved space is put in place to allow future versions to add new + * variables without shifting down storage in the inheritance chain. + * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + */ + uint256[36] private __gap; +} diff --git a/src/test/DepositWithdraw.t.sol b/src/test/DepositWithdraw.t.sol index 984f39f6b..8e87e245b 100644 --- a/src/test/DepositWithdraw.t.sol +++ b/src/test/DepositWithdraw.t.sol @@ -363,12 +363,9 @@ contract DepositWithdrawTests is EigenLayerTestHelper { eigenPodManager = EigenPodManager( address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) ); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); ethPOSDeposit = new ETHPOSDepositMock(); - pod = new EigenPod(ethPOSDeposit, delayedWithdrawalRouter, eigenPodManager, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, GOERLI_GENESIS_TIME); + pod = new EigenPod(ethPOSDeposit, eigenPodManager, GOERLI_GENESIS_TIME); eigenPodBeacon = new UpgradeableBeacon(address(pod)); @@ -417,7 +414,6 @@ contract DepositWithdrawTests is EigenLayerTestHelper { address(eigenPodManagerImplementation), abi.encodeWithSelector( EigenPodManager.initialize.selector, - beaconChainOracleAddress, eigenLayerReputedMultisig, eigenLayerPauserReg, 0/*initialPausedStatus*/ diff --git a/src/test/EigenLayerDeployer.t.sol b/src/test/EigenLayerDeployer.t.sol index 5912edb24..0f4888fc5 100644 --- a/src/test/EigenLayerDeployer.t.sol +++ b/src/test/EigenLayerDeployer.t.sol @@ -11,7 +11,6 @@ import "../contracts/interfaces/IDelegationManager.sol"; import "../contracts/core/DelegationManager.sol"; import "../contracts/interfaces/IETHPOSDeposit.sol"; -import "../contracts/interfaces/IBeaconChainOracle.sol"; import "../contracts/core/StrategyManager.sol"; import "../contracts/strategies/StrategyBase.sol"; @@ -19,7 +18,6 @@ import "../contracts/core/Slasher.sol"; import "../contracts/pods/EigenPod.sol"; import "../contracts/pods/EigenPodManager.sol"; -import "../contracts/pods/DelayedWithdrawalRouter.sol"; import "../contracts/permissions/PauserRegistry.sol"; @@ -28,7 +26,6 @@ import "./utils/Operators.sol"; import "./mocks/LiquidStakingToken.sol"; import "./mocks/EmptyContract.sol"; import "./mocks/ETHDepositMock.sol"; -import "./mocks/BeaconChainOracleMock.sol"; import "forge-std/Test.sol"; @@ -44,7 +41,6 @@ contract EigenLayerDeployer is Operators { StrategyManager public strategyManager; EigenPodManager public eigenPodManager; IEigenPod public pod; - IDelayedWithdrawalRouter public delayedWithdrawalRouter; IETHPOSDeposit public ethPOSDeposit; IBeacon public eigenPodBeacon; @@ -79,7 +75,6 @@ contract EigenLayerDeployer is Operators { uint32 PARTIAL_WITHDRAWAL_FRAUD_PROOF_PERIOD_BLOCKS = 7 days / 12 seconds; uint256 REQUIRED_BALANCE_WEI = 32 ether; uint64 MAX_PARTIAL_WTIHDRAWAL_AMOUNT_GWEI = 1 ether / 1e9; - uint64 MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = 32e9; uint64 GOERLI_GENESIS_TIME = 1616508000; address pauser; @@ -98,16 +93,11 @@ contract EigenLayerDeployer is Operators { address strategyManagerAddress; address eigenPodManagerAddress; address podAddress; - address delayedWithdrawalRouterAddress; address eigenPodBeaconAddress; - address beaconChainOracleAddress; address emptyContractAddress; address operationsMultisig; address executorMultisig; - uint256 public initialBeaconChainOracleThreshold = 3; - - string internal goerliDeploymentConfig = vm.readFile("script/output/goerli/M1_deployment_goerli_2023_3_23.json"); // addresses excluded from fuzzing due to abnormal behavior. TODO: @Sidu28 define this better and give it a clearer name mapping(address => bool) fuzzedAddressMapping; @@ -124,13 +114,10 @@ contract EigenLayerDeployer is Operators { } //performs basic deployment before each test - // for fork tests run: forge test -vv --fork-url https://eth-goerli.g.alchemy.com/v2/demo -vv function setUp() public virtual { try vm.envUint("CHAIN_ID") returns (uint256 chainId) { if (chainId == 31337) { _deployEigenLayerContractsLocal(); - } else if (chainId == 5) { - _deployEigenLayerContractsGoerli(); } // If CHAIN_ID ENV is not set, assume local deployment on 31337 } catch { @@ -145,68 +132,6 @@ contract EigenLayerDeployer is Operators { fuzzedAddressMapping[address(slasher)] = true; } - function _deployEigenLayerContractsGoerli() internal { - _setAddresses(goerliDeploymentConfig); - pauser = operationsMultisig; - unpauser = executorMultisig; - // deploy proxy admin for ability to upgrade proxy contracts - eigenLayerProxyAdmin = ProxyAdmin(eigenLayerProxyAdminAddress); - - emptyContract = new EmptyContract(); - - //deploy pauser registry - eigenLayerPauserReg = PauserRegistry(eigenLayerPauserRegAddress); - - delegation = DelegationManager(delegationAddress); - strategyManager = StrategyManager(strategyManagerAddress); - slasher = Slasher(slasherAddress); - eigenPodManager = EigenPodManager(eigenPodManagerAddress); - delayedWithdrawalRouter = DelayedWithdrawalRouter(delayedWithdrawalRouterAddress); - - beaconChainOracleAddress = address(new BeaconChainOracleMock()); - - ethPOSDeposit = new ETHPOSDepositMock(); - pod = new EigenPod( - ethPOSDeposit, - delayedWithdrawalRouter, - eigenPodManager, - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - GOERLI_GENESIS_TIME - ); - - eigenPodBeacon = new UpgradeableBeacon(address(pod)); - - //simple ERC20 (**NOT** WETH-like!), used in a test strategy - weth = new ERC20PresetFixedSupply("weth", "WETH", wethInitialSupply, address(this)); - - // deploy StrategyBase contract implementation, then create upgradeable proxy that points to implementation and initialize it - baseStrategyImplementation = new StrategyBase(strategyManager); - wethStrat = StrategyBase( - address( - new TransparentUpgradeableProxy( - address(baseStrategyImplementation), - address(eigenLayerProxyAdmin), - abi.encodeWithSelector(StrategyBase.initialize.selector, weth, eigenLayerPauserReg) - ) - ) - ); - - eigenToken = new ERC20PresetFixedSupply("eigen", "EIGEN", wethInitialSupply, address(this)); - - // deploy upgradeable proxy that points to StrategyBase implementation and initialize it - eigenStrat = StrategyBase( - address( - new TransparentUpgradeableProxy( - address(baseStrategyImplementation), - address(eigenLayerProxyAdmin), - abi.encodeWithSelector(StrategyBase.initialize.selector, eigenToken, eigenLayerPauserReg) - ) - ) - ); - - stakers = [acct_0, acct_1]; - } - function _deployEigenLayerContractsLocal() internal { pauser = address(69); unpauser = address(489); @@ -235,16 +160,10 @@ contract EigenLayerDeployer is Operators { eigenPodManager = EigenPodManager( address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) ); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - ethPOSDeposit = new ETHPOSDepositMock(); pod = new EigenPod( ethPOSDeposit, - delayedWithdrawalRouter, eigenPodManager, - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, GOERLI_GENESIS_TIME ); @@ -261,7 +180,6 @@ contract EigenLayerDeployer is Operators { slasher, delegation ); - DelayedWithdrawalRouter delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. eigenLayerProxyAdmin.upgradeAndCall( @@ -303,25 +221,11 @@ contract EigenLayerDeployer is Operators { address(eigenPodManagerImplementation), abi.encodeWithSelector( EigenPodManager.initialize.selector, - beaconChainOracleAddress, eigenLayerReputedMultisig, eigenLayerPauserReg, 0 /*initialPausedStatus*/ ) ); - uint256 initPausedStatus = 0; - uint256 withdrawalDelayBlocks = PARTIAL_WITHDRAWAL_FRAUD_PROOF_PERIOD_BLOCKS; - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation), - abi.encodeWithSelector( - DelayedWithdrawalRouter.initialize.selector, - eigenLayerReputedMultisig, - eigenLayerPauserReg, - initPausedStatus, - withdrawalDelayBlocks - ) - ); //simple ERC20 (**NOT** WETH-like!), used in a test strategy weth = new ERC20PresetFixedSupply("weth", "WETH", wethInitialSupply, address(this)); @@ -361,7 +265,6 @@ contract EigenLayerDeployer is Operators { strategyManagerAddress = stdJson.readAddress(config, ".addresses.strategyManager"); slasherAddress = stdJson.readAddress(config, ".addresses.slasher"); eigenPodManagerAddress = stdJson.readAddress(config, ".addresses.eigenPodManager"); - delayedWithdrawalRouterAddress = stdJson.readAddress(config, ".addresses.delayedWithdrawalRouter"); emptyContractAddress = stdJson.readAddress(config, ".addresses.emptyContract"); operationsMultisig = stdJson.readAddress(config, ".parameters.operationsMultisig"); executorMultisig = stdJson.readAddress(config, ".parameters.executorMultisig"); diff --git a/src/test/EigenPod.t.sol b/src/test/EigenPod.t.sol deleted file mode 100644 index 0759981a1..000000000 --- a/src/test/EigenPod.t.sol +++ /dev/null @@ -1,2030 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.12; - -import "../contracts/interfaces/IEigenPod.sol"; -import "../contracts/pods/DelayedWithdrawalRouter.sol"; -import "./utils/ProofParsing.sol"; -import "./EigenLayerDeployer.t.sol"; -import "../contracts/libraries/BeaconChainProofs.sol"; -import "./mocks/BeaconChainOracleMock.sol"; -import "./harnesses/EigenPodHarness.sol"; - -contract EigenPodTests is ProofParsing, EigenPodPausingConstants { - using BytesLib for bytes; - using BeaconChainProofs for *; - - - uint256 internal constant GWEI_TO_WEI = 1e9; - uint64 public constant DENEB_FORK_TIMESTAMP_GOERLI = 1705473120; - - - bytes pubkey = - hex"88347ed1c492eedc97fc8c506a35d44d81f27a0c7a1c661b35913cfd15256c0cccbd34a83341f505c7de2983292f2cab"; - uint40 validatorIndex0 = 0; - uint40 validatorIndex1 = 1; - - - address podOwner = address(42000094993494); - - bool public IS_DENEB; - - Vm cheats = Vm(HEVM_ADDRESS); - DelegationManager public delegation; - IStrategyManager public strategyManager; - Slasher public slasher; - PauserRegistry public pauserReg; - - ProxyAdmin public eigenLayerProxyAdmin; - IEigenPodManager public eigenPodManager; - IEigenPod public podImplementation; - IDelayedWithdrawalRouter public delayedWithdrawalRouter; - IETHPOSDeposit public ethPOSDeposit; - UpgradeableBeacon public eigenPodBeacon; - EPInternalFunctions public podInternalFunctionTester; - - BeaconChainOracleMock public beaconChainOracle; - address[] public slashingContracts; - address pauser = address(69); - address unpauser = address(489); - address podManagerAddress = 0x212224D2F2d262cd093eE13240ca4873fcCBbA3C; - address podAddress = address(123); - uint256 stakeAmount = 32e18; - mapping(address => bool) fuzzedAddressMapping; - bytes signature; - bytes32 depositDataRoot; - - bytes32[] withdrawalFields; - bytes32[] validatorFields; - - uint32 WITHDRAWAL_DELAY_BLOCKS = 7 days / 12 seconds; - IStrategy[] public initializeStrategiesToSetDelayBlocks; - uint256[] public initializeWithdrawalDelayBlocks; - uint64 MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = 32e9; - uint64 RESTAKED_BALANCE_OFFSET_GWEI = 75e7; - uint64 internal constant GOERLI_GENESIS_TIME = 1616508000; - uint64 internal constant SECONDS_PER_SLOT = 12; - - // bytes validatorPubkey = hex"93a0dd04ccddf3f1b419fdebf99481a2182c17d67cf14d32d6e50fc4bf8effc8db4a04b7c2f3a5975c1b9b74e2841888"; - - // EIGENPODMANAGER EVENTS - /// @notice Emitted to notify the update of the beaconChainOracle address - event BeaconOracleUpdated(address indexed newOracleAddress); - - /// @notice Emitted to notify the deployment of an EigenPod - event PodDeployed(address indexed eigenPod, address indexed podOwner); - - /// @notice Emitted to notify a deposit of beacon chain ETH recorded in the strategy manager - event BeaconChainETHDeposited(address indexed podOwner, uint256 amount); - - // EIGENPOD EVENTS - /// @notice Emitted when an ETH validator stakes via this eigenPod - event EigenPodStaked(bytes pubkey); - - /// @notice Emitted when an ETH validator's withdrawal credentials are successfully verified to be pointed to this eigenPod - event ValidatorRestaked(uint40 validatorIndex); - - /// @notice Emitted when an ETH validator's balance is updated in EigenLayer - event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newBalanceGwei); - - /// @notice Emitted when an ETH validator is prove to have withdrawn from the beacon chain - event FullWithdrawalRedeemed( - uint40 validatorIndex, - uint64 withdrawalTimestamp, - address indexed recipient, - uint64 withdrawalAmountGwei - ); - - /// @notice Emitted when a partial withdrawal claim is successfully redeemed - event PartialWithdrawalRedeemed( - uint40 validatorIndex, - uint64 withdrawalTimestamp, - address indexed recipient, - uint64 partialWithdrawalAmountGwei - ); - - /// @notice Emitted when restaked beacon chain ETH is withdrawn from the eigenPod. - event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount); - - // DELAYED WITHDRAWAL ROUTER EVENTS - /// @notice Emitted when the `withdrawalDelayBlocks` variable is modified from `previousValue` to `newValue`. - event WithdrawalDelayBlocksSet(uint256 previousValue, uint256 newValue); - - /// @notice event for delayedWithdrawal creation - event DelayedWithdrawalCreated(address podOwner, address recipient, uint256 amount, uint256 index); - - /// @notice event for the claiming of delayedWithdrawals - event DelayedWithdrawalsClaimed(address recipient, uint256 amountClaimed, uint256 delayedWithdrawalsCompleted); - - /// @notice Emitted when ETH that was previously received via the `receive` fallback is withdrawn - event NonBeaconChainETHWithdrawn(address indexed recipient, uint256 amountWithdrawn); - - modifier fuzzedAddress(address addr) virtual { - cheats.assume(fuzzedAddressMapping[addr] == false); - _; - } - - //performs basic deployment before each test - function setUp() public { - // deploy proxy admin for ability to upgrade proxy contracts - eigenLayerProxyAdmin = new ProxyAdmin(); - - // deploy pauser registry - address[] memory pausers = new address[](1); - pausers[0] = pauser; - pauserReg = new PauserRegistry(pausers, unpauser); - - /// weird workaround: check commit before this -- the call to `upgradeAndCall` the DelegationManager breaks without performing this step! - /// seems to be foundry bug. the revert is ultimately for 'TransparentUpgradeableProxy: admin cannot fallback to proxy target', i.e. - /// the simulated caller is somehow the ProxyAdmin itself. - EmptyContract emptyContract = new EmptyContract(); - - /** - * First, deploy upgradeable proxy contracts that **will point** to the implementations. Since the implementation contracts are - * not yet deployed, we give these proxies an empty contract as the initial implementation, to act as if they have no code. - */ - emptyContract = new EmptyContract(); - delegation = DelegationManager( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - strategyManager = StrategyManager( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - slasher = Slasher( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - - cheats.warp(GOERLI_GENESIS_TIME); // start at a sane timestamp - ethPOSDeposit = new ETHPOSDepositMock(); - podImplementation = new EigenPod( - ethPOSDeposit, - delayedWithdrawalRouter, - IEigenPodManager(podManagerAddress), - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - GOERLI_GENESIS_TIME - ); - - eigenPodBeacon = new UpgradeableBeacon(address(podImplementation)); - - // this contract is deployed later to keep its address the same (for these tests) - eigenPodManager = EigenPodManager( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - - // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs - DelegationManager delegationImplementation = new DelegationManager(strategyManager, slasher, eigenPodManager); - StrategyManager strategyManagerImplementation = new StrategyManager( - delegation, - IEigenPodManager(podManagerAddress), - slasher - ); - Slasher slasherImplementation = new Slasher(strategyManager, delegation); - EigenPodManager eigenPodManagerImplementation = new EigenPodManager( - ethPOSDeposit, - eigenPodBeacon, - strategyManager, - slasher, - delegation - ); - - //ensuring that the address of eigenpodmanager doesn't change - bytes memory code = address(eigenPodManager).code; - cheats.etch(podManagerAddress, code); - eigenPodManager = IEigenPodManager(podManagerAddress); - - beaconChainOracle = new BeaconChainOracleMock(); - DelayedWithdrawalRouter delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter( - IEigenPodManager(podManagerAddress) - ); - - address initialOwner = address(this); - // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(delegation))), - address(delegationImplementation), - abi.encodeWithSelector( - DelegationManager.initialize.selector, - initialOwner, - pauserReg, - 0 /*initialPausedStatus*/, - WITHDRAWAL_DELAY_BLOCKS, - initializeStrategiesToSetDelayBlocks, - initializeWithdrawalDelayBlocks - ) - ); - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(strategyManager))), - address(strategyManagerImplementation), - abi.encodeWithSelector( - StrategyManager.initialize.selector, - initialOwner, - initialOwner, - pauserReg, - 0 /*initialPausedStatus*/ - ) - ); - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(slasher))), - address(slasherImplementation), - abi.encodeWithSelector(Slasher.initialize.selector, initialOwner, pauserReg, 0 /*initialPausedStatus*/) - ); - // TODO: add `cheats.expectEmit` calls for initialization events - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(eigenPodManager))), - address(eigenPodManagerImplementation), - abi.encodeWithSelector( - EigenPodManager.initialize.selector, - beaconChainOracle, - initialOwner, - pauserReg, - 0 /*initialPausedStatus*/ - ) - ); - uint256 initPausedStatus = 0; - uint256 withdrawalDelayBlocks = WITHDRAWAL_DELAY_BLOCKS; - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation), - abi.encodeWithSelector( - DelayedWithdrawalRouter.initialize.selector, - initialOwner, - pauserReg, - initPausedStatus, - withdrawalDelayBlocks - ) - ); - - cheats.deal(address(podOwner), 5 * stakeAmount); - - fuzzedAddressMapping[address(0)] = true; - fuzzedAddressMapping[address(eigenLayerProxyAdmin)] = true; - fuzzedAddressMapping[address(strategyManager)] = true; - fuzzedAddressMapping[address(eigenPodManager)] = true; - fuzzedAddressMapping[address(delegation)] = true; - fuzzedAddressMapping[address(slasher)] = true; - } - - function testStaking() public { - cheats.startPrank(podOwner); - IEigenPod newPod = eigenPodManager.getPod(podOwner); - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(pubkey); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - } - - function testWithdrawBeforeRestaking() public { - testStaking(); - IEigenPod pod = eigenPodManager.getPod(podOwner); - - //simulate that hasRestaked is set to false, so that we can test withdrawBeforeRestaking for pods deployed before M2 activation - cheats.store(address(pod), bytes32(uint256(52)), bytes32(uint256(1))); - require(pod.hasRestaked() == false, "Pod should not be restaked"); - - // simulate a withdrawal - cheats.deal(address(pod), stakeAmount); - cheats.startPrank(podOwner); - cheats.expectEmit(true, true, true, true, address(delayedWithdrawalRouter)); - emit DelayedWithdrawalCreated( - podOwner, - podOwner, - stakeAmount, - delayedWithdrawalRouter.userWithdrawalsLength(podOwner) - ); - - uint timestampBeforeTx = pod.mostRecentWithdrawalTimestamp(); - - pod.withdrawBeforeRestaking(); - - require(_getLatestDelayedWithdrawalAmount(podOwner) == stakeAmount, "Payment amount should be stake amount"); - require( - pod.mostRecentWithdrawalTimestamp() == uint64(block.timestamp), - "Most recent withdrawal block number not updated" - ); - require( - pod.mostRecentWithdrawalTimestamp() > timestampBeforeTx, - "Most recent withdrawal block number not updated" - ); - } - - function testDeployEigenPodWithoutActivateRestaking() public { - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - cheats.startPrank(podOwner); - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(pubkey); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - bytes[] memory proofsArray = new bytes[](1); - proofsArray[0] = abi.encodePacked(getWithdrawalCredentialProof()); - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(getValidatorIndex()); - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(getLatestBlockRoot()); - - //this simulates that hasRestaking is set to false, as would be the case for deployed pods that have not yet restaked prior to M2 - cheats.store(address(newPod), bytes32(uint256(52)), bytes32(uint256(0))); - - cheats.startPrank(podOwner); - cheats.warp(GOERLI_GENESIS_TIME); - cheats.expectRevert(bytes("EigenPod.hasEnabledRestaking: restaking is not enabled")); - newPod.verifyWithdrawalCredentials( - GOERLI_GENESIS_TIME, - stateRootProofStruct, - validatorIndices, - proofsArray, - validatorFieldsArray - ); - cheats.stopPrank(); - } - - // regression test for bug when activateRestaking -> verifyWC occur in the same epoch, in that order - function testEigenPodWithdrawalCredentialTimingBug(uint16 epochNum) public { - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - cheats.startPrank(podOwner); - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(pubkey); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - bytes[] memory proofsArray = new bytes[](1); - proofsArray[0] = abi.encodePacked(getWithdrawalCredentialProof()); - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(getValidatorIndex()); - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(getLatestBlockRoot()); - - //this simulates that hasRestaking is set to false, as would be the case for deployed pods that have not yet restaked prior to M2 - cheats.store(address(newPod), bytes32(uint256(52)), bytes32(uint256(0))); - assertTrue(newPod.hasRestaked() == false, "EigenPod should not be restaked"); - - uint64 startTime = GOERLI_GENESIS_TIME + (BeaconChainProofs.SECONDS_PER_EPOCH * epochNum); - uint64 startEpoch = _timestampToEpoch(startTime); - // move to start time - this is the first slot in the epoch, and is where we will call activateRestaking - cheats.warp(startTime); - - // activate restaking - cheats.startPrank(podOwner); - newPod.activateRestaking(); - - // Ensure verifyWC fails for each slot remaining in the epoch - for (uint i = 0; i < 32; i++) { - // Move forward 0-31 slots - uint64 slotTimestamp = uint64(startTime + (BeaconChainProofs.SECONDS_PER_SLOT * i)); - uint64 epoch = _timestampToEpoch(slotTimestamp); - assertTrue(epoch == startEpoch, "calculated epoch should not change"); - - cheats.warp(slotTimestamp); - cheats.expectRevert(bytes("EigenPod.verifyWithdrawalCredentials: proof must be in the epoch after activation")); - newPod.verifyWithdrawalCredentials( - slotTimestamp, - stateRootProofStruct, - validatorIndices, - proofsArray, - validatorFieldsArray - ); - } - - // finally, move to the next epoch - cheats.warp(block.timestamp + BeaconChainProofs.SECONDS_PER_SLOT); - uint64 endEpoch = _timestampToEpoch(uint64(block.timestamp)); - assertEq(startEpoch + 1, endEpoch, "should have advanced one epoch"); - - // now verifyWC should succeed - newPod.verifyWithdrawalCredentials( - uint64(block.timestamp), - stateRootProofStruct, - validatorIndices, - proofsArray, - validatorFieldsArray - ); - - cheats.stopPrank(); - } - - function _timestampToEpoch(uint64 timestamp) internal view returns (uint64) { - require(timestamp >= GOERLI_GENESIS_TIME, "Test._timestampToEpoch: timestamp is before genesis"); - return (timestamp - GOERLI_GENESIS_TIME) / BeaconChainProofs.SECONDS_PER_EPOCH; - } - - // verifies that it is possible to subsequently prove WCs and withdraw funds when activateRestaking -> validator exit occur in the same epoch, in that order - // this is similar to `testProveWithdrawalCredentialsAfterValidatorExit` but somewhat more specific / targeted - function testEigenPodWithdrawalCredentialTimingSuccess() public { - // upgrade EigenPods to an implementation that has the genesis time to **one slot earlier** - // we do this so the validator exit at `GOERLI_GENESIS_TIME` is explicitly after genesis time, where we will active restaking - uint64 modifiedGenesisTime = GOERLI_GENESIS_TIME - 12; - podImplementation = new EigenPod( - ethPOSDeposit, - delayedWithdrawalRouter, - IEigenPodManager(podManagerAddress), - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - modifiedGenesisTime - ); - eigenPodBeacon.upgradeTo(address(podImplementation)); - - cheats.startPrank(podOwner); - IEigenPod newPod = IEigenPod(eigenPodManager.createPod()); - cheats.stopPrank(); - - //this simulates that hasRestaking is set to false, as would be the case for deployed pods that have not yet restaked prior to M2 - cheats.store(address(newPod), bytes32(uint256(52)), bytes32(uint256(0))); - require(newPod.hasRestaked() == false, "Pod should not be restaked"); - - // move to slot at modifiedGenesisTime. this is within epoch 0, like the withdrawal - cheats.warp(modifiedGenesisTime); - cheats.prank(podOwner); - newPod.activateRestaking(); - - // warp forward to start of next epoch (epoch 1), so we can do WC proof with zero effective balance - cheats.warp(modifiedGenesisTime + BeaconChainProofs.SECONDS_PER_EPOCH); - - // get proof of validator 302913 having WCs pointed with 0 balance - // ./solidityProofGen -newBalance=0 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913_exited.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913_exited.json"); - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - - bytes[] memory proofsArray = new bytes[](1); - proofsArray[0] = abi.encodePacked(getWithdrawalCredentialProof()); - - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(getValidatorIndex()); - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - //set the oracle block root - _setOracleBlockRoot(); - - int256 beaconChainETHSharesBefore = eigenPodManager.podOwnerShares(podOwner); - - cheats.prank(podOwner); - newPod.verifyWithdrawalCredentials( - uint64(block.timestamp), - stateRootProofStruct, - validatorIndices, - proofsArray, - validatorFieldsArray - ); - - int256 beaconChainETHSharesAfter = eigenPodManager.podOwnerShares(podOwner); - require(beaconChainETHSharesBefore == beaconChainETHSharesAfter, - "effectiveBalance should be zero, no shares should be credited"); - - //./solidityProofGen "WithdrawalFieldsProof" 302913 146 8092 true false "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6397852.json" "data/withdrawal_proof_goerli/goerli_block_header_6397852.json" "data/withdrawal_proof_goerli/goerli_block_6397852.json" "fullWithdrawalProof_Latest.json" false - // To get block header: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v1/beacon/headers/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_header_6399000.json - // To get block: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v2/beacon/blocks/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_6399000.json - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - - _proveWithdrawalForPod(newPod); - } - - function testWithdrawNonBeaconChainETHBalanceWei() public { - IEigenPod pod = testDeployAndVerifyNewEigenPod(); - - cheats.deal(address(podOwner), 10 ether); - emit log_named_address("Pod:", address(pod)); - - uint256 balanceBeforeDeposit = pod.nonBeaconChainETHBalanceWei(); - - (bool sent, ) = payable(address(pod)).call{value: 1 ether}(""); - - require(sent == true, "not sent"); - - uint256 balanceAfterDeposit = pod.nonBeaconChainETHBalanceWei(); - - require( - balanceBeforeDeposit < balanceAfterDeposit - && (balanceAfterDeposit - balanceBeforeDeposit) == 1 ether, - "increment checks" - ); - - cheats.startPrank(podOwner, podOwner); - cheats.expectEmit(true, true, true, true, address(pod)); - emit NonBeaconChainETHWithdrawn(podOwner, 1 ether); - pod.withdrawNonBeaconChainETHBalanceWei( - podOwner, - 1 ether - ); - - uint256 balanceAfterWithdrawal = pod.nonBeaconChainETHBalanceWei(); - - require( - balanceAfterWithdrawal < balanceAfterDeposit - && balanceAfterWithdrawal == balanceBeforeDeposit, - "decrement checks" - ); - - cheats.stopPrank(); - } - - function testWithdrawFromPod() public { - IEigenPod pod = eigenPodManager.getPod(podOwner); - cheats.startPrank(podOwner); - - cheats.expectEmit(true, true, true, true, address(pod)); - emit EigenPodStaked(pubkey); - - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - - cheats.deal(address(pod), stakeAmount); - - // this is testing if pods deployed before M2 that do not have hasRestaked initialized to true, will revert - cheats.store(address(pod), bytes32(uint256(52)), bytes32(uint256(1))); - - cheats.startPrank(podOwner); - uint256 userWithdrawalsLength = delayedWithdrawalRouter.userWithdrawalsLength(podOwner); - // cheats.expectEmit(true, true, true, true, address(delayedWithdrawalRouter)); - //cheats.expectEmit(true, true, true, true); - emit DelayedWithdrawalCreated(podOwner, podOwner, stakeAmount, userWithdrawalsLength); - pod.withdrawBeforeRestaking(); - cheats.stopPrank(); - require(address(pod).balance == 0, "Pod balance should be 0"); - } - - function testFullWithdrawalProof() public { - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - BeaconChainProofs.WithdrawalProof memory proofs = _getWithdrawalProof(); - bytes32 beaconStateRoot = getBeaconStateRoot(); - withdrawalFields = getWithdrawalFields(); - validatorFields = getValidatorFields(); - - Relayer relay = new Relayer(); - - relay.verifyWithdrawal(beaconStateRoot, withdrawalFields, proofs); - } - - function testFullWithdrawalProofWithWrongIndices( - uint64 wrongBlockRootIndex, - uint64 wrongWithdrawalIndex, - uint64 wrongHistoricalSummariesIndex - ) public { - uint256 BLOCK_ROOTS_TREE_HEIGHT = 13; - uint256 WITHDRAWALS_TREE_HEIGHT = 4; - uint256 HISTORICAL_SUMMARIES_TREE_HEIGHT = 24; - cheats.assume(wrongBlockRootIndex > 2 ** BLOCK_ROOTS_TREE_HEIGHT); - cheats.assume(wrongWithdrawalIndex > 2 ** WITHDRAWALS_TREE_HEIGHT); - cheats.assume(wrongHistoricalSummariesIndex > 2 ** HISTORICAL_SUMMARIES_TREE_HEIGHT); - - Relayer relay = new Relayer(); - - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - bytes32 beaconStateRoot = getBeaconStateRoot(); - validatorFields = getValidatorFields(); - withdrawalFields = getWithdrawalFields(); - - { - BeaconChainProofs.WithdrawalProof memory wrongProofs = _getWithdrawalProof(); - wrongProofs.blockRootIndex = wrongBlockRootIndex; - cheats.expectRevert(bytes("BeaconChainProofs.verifyWithdrawal: blockRootIndex is too large")); - relay.verifyWithdrawal(beaconStateRoot, withdrawalFields, wrongProofs); - } - - { - BeaconChainProofs.WithdrawalProof memory wrongProofs = _getWithdrawalProof(); - wrongProofs.withdrawalIndex = wrongWithdrawalIndex; - cheats.expectRevert(bytes("BeaconChainProofs.verifyWithdrawal: withdrawalIndex is too large")); - relay.verifyWithdrawal(beaconStateRoot, withdrawalFields, wrongProofs); - } - - { - BeaconChainProofs.WithdrawalProof memory wrongProofs = _getWithdrawalProof(); - wrongProofs.historicalSummaryIndex = wrongHistoricalSummariesIndex; - cheats.expectRevert(bytes("BeaconChainProofs.verifyWithdrawal: historicalSummaryIndex is too large")); - relay.verifyWithdrawal(beaconStateRoot, withdrawalFields, wrongProofs); - } - } - - /// @notice This test is to ensure the full withdrawal flow works - function testFullWithdrawalFlowDeneb() public returns (IEigenPod) { - eigenPodManager.setDenebForkTimestamp(DENEB_FORK_TIMESTAMP_GOERLI); - IS_DENEB = true; - //this call is to ensure that validator 302913 has proven their withdrawalcreds - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - //Deneb: ./solidityProofGen/solidityProofGen "WithdrawalFieldsProof" 302913 271 8191 true false "data/deneb_goerli_block_header_7431952.json" "data/deneb_goerli_slot_7431952.json" "data/deneb_goerli_slot_7421952.json" "data/deneb_goerli_block_header_7421951.json" "data/deneb_goerli_block_7421951.json" "fullWithdrawalProof_Latest.json" false false - // To get block header: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v1/beacon/headers/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_header_6399000.json - // To get block: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v2/beacon/blocks/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_6399000.json - setJSON("./src/test/test-data/fullWithdrawalDeneb.json"); - return _proveWithdrawalForPod(newPod); - } - - function testFullWithdrawalFlowCapellaWithdrawalAgainstDenebRoot() public returns (IEigenPod) { - IS_DENEB = false; - //this call is to ensure that validator 302913 has proven their withdrawalcreds - // ./solidityProofGen/solidityProofGen "WithdrawalFieldsProof" 302913 146 8092 true false "data/deneb_goerli_block_header_7431952.json" "data/deneb_goerli_slot_7431952.json" "data/goerli_slot_6397952.json" "data/goerli_block_header_6397852.json" "data/goerli_block_6397852.json" "fullWithdrawalProof_CapellaAgainstDeneb.json" false true - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - //Deneb: ./solidityProofGen/solidityProofGen "WithdrawalFieldsProof" 302913 271 8191 true false "data/deneb_goerli_block_header_7431952.json" "data/deneb_goerli_slot_7431952.json" "data/deneb_goerli_slot_7421952.json" "data/deneb_goerli_block_header_7421951.json" "data/deneb_goerli_block_7421951.json" "fullWithdrawalProof_Latest.json" false - // To get block header: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v1/beacon/headers/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_header_6399000.json - // To get block: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v2/beacon/blocks/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_6399000.json - setJSON("./src/test/test-data/fullWithdrawalCapellaAgainstDenebRoot.json"); - return _proveWithdrawalForPod(newPod); - } - - function testFullWithdrawalFlow() public returns (IEigenPod) { - //this call is to ensure that validator 302913 has proven their withdrawalcreds - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - //./solidityProofGen "WithdrawalFieldsProof" 302913 146 8092 true false "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6397852.json" "data/withdrawal_proof_goerli/goerli_block_header_6397852.json" "data/withdrawal_proof_goerli/goerli_block_6397852.json" "fullWithdrawalProof_Latest.json" false - // To get block header: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v1/beacon/headers/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_header_6399000.json - // To get block: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v2/beacon/blocks/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_6399000.json - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - return _proveWithdrawalForPod(newPod); - } - - /** - * @notice this test is to ensure that a full withdrawal can be made once a validator has processed their first full withrawal - * This is specifically for the case where a validator has redeposited into their exited validator and needs to prove another withdrawal - * to get their funds out - */ - function testWithdrawAfterFullWithdrawal() external { - _deployInternalFunctionTester(); - IEigenPod pod = testFullWithdrawalFlow(); - - // ./solidityProofGen "WithdrawalFieldsProof" 302913 146 8092 true false "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6397852.json" "data/withdrawal_proof_goerli/goerli_block_header_6397852.json" "data/withdrawal_proof_goerli/goerli_block_6397852.json" "fullWithdrawalProof_Latest_1SlotAdvanced.json" true - setJSON("./src/test/test-data/fullWithdrawalProof_Latest_1SlotAdvanced.json"); - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(getLatestBlockRoot()); - - withdrawalFields = getWithdrawalFields(); - uint64 withdrawalAmountGwei = Endian.fromLittleEndianUint64( - withdrawalFields[BeaconChainProofs.WITHDRAWAL_VALIDATOR_AMOUNT_INDEX] - ); - uint64 leftOverBalanceWEI = uint64( - withdrawalAmountGwei - pod.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() - ) * uint64(GWEI_TO_WEI); - cheats.deal(address(pod), leftOverBalanceWEI); - { - BeaconChainProofs.WithdrawalProof[] memory withdrawalProofsArray = new BeaconChainProofs.WithdrawalProof[]( - 1 - ); - withdrawalProofsArray[0] = _getWithdrawalProof(); - bytes[] memory validatorFieldsProofArray = new bytes[](1); - validatorFieldsProofArray[0] = abi.encodePacked(getValidatorProof()); - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - bytes32[][] memory withdrawalFieldsArray = new bytes32[][](1); - withdrawalFieldsArray[0] = withdrawalFields; - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - pod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofsArray, - validatorFieldsProofArray, - validatorFieldsArray, - withdrawalFieldsArray - ); - } - } - - function testProvingFullWithdrawalForTheSameSlotFails() external { - IEigenPod pod = testFullWithdrawalFlow(); - - { - BeaconChainProofs.WithdrawalProof[] memory withdrawalProofsArray = new BeaconChainProofs.WithdrawalProof[]( - 1 - ); - withdrawalProofsArray[0] = _getWithdrawalProof(); - bytes[] memory validatorFieldsProofArray = new bytes[](1); - validatorFieldsProofArray[0] = abi.encodePacked(getValidatorProof()); - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - bytes32[][] memory withdrawalFieldsArray = new bytes32[][](1); - withdrawalFieldsArray[0] = withdrawalFields; - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - cheats.expectRevert( - bytes("EigenPod._verifyAndProcessWithdrawal: withdrawal has already been proven for this timestamp") - ); - pod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofsArray, - validatorFieldsProofArray, - validatorFieldsArray, - withdrawalFieldsArray - ); - } - } - - /// @notice This test is to ensure that the partial withdrawal flow works correctly - function testPartialWithdrawalFlow() public returns (IEigenPod) { - //this call is to ensure that validator 61068 has proven their withdrawalcreds - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - //generate partialWithdrawalProofs.json with: - // ./solidityProofGen "WithdrawalFieldsProof" 302913 146 8092 true true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6397852.json" "data/withdrawal_proof_goerli/goerli_block_header_6397852.json" "data/withdrawal_proof_goerli/goerli_block_6397852.json" "partialWithdrawalProof_Latest.json" false - setJSON("./src/test/test-data/partialWithdrawalProof_Latest.json"); - withdrawalFields = getWithdrawalFields(); - validatorFields = getValidatorFields(); - BeaconChainProofs.WithdrawalProof memory withdrawalProofs = _getWithdrawalProof(); - bytes memory validatorFieldsProof = abi.encodePacked(getValidatorProof()); - - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(getLatestBlockRoot()); - uint64 withdrawalAmountGwei = Endian.fromLittleEndianUint64( - withdrawalFields[BeaconChainProofs.WITHDRAWAL_VALIDATOR_AMOUNT_INDEX] - ); - uint40 validatorIndex = uint40( - Endian.fromLittleEndianUint64(withdrawalFields[BeaconChainProofs.WITHDRAWAL_VALIDATOR_INDEX_INDEX]) - ); - - cheats.deal(address(newPod), stakeAmount); - { - BeaconChainProofs.WithdrawalProof[] memory withdrawalProofsArray = new BeaconChainProofs.WithdrawalProof[]( - 1 - ); - withdrawalProofsArray[0] = withdrawalProofs; - bytes[] memory validatorFieldsProofArray = new bytes[](1); - validatorFieldsProofArray[0] = validatorFieldsProof; - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = validatorFields; - bytes32[][] memory withdrawalFieldsArray = new bytes32[][](1); - withdrawalFieldsArray[0] = withdrawalFields; - - uint256 delayedWithdrawalRouterContractBalanceBefore = address(delayedWithdrawalRouter).balance; - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - //cheats.expectEmit(true, true, true, true, address(newPod)); - // cheats.expectEmit(validatorIndex, _computeTimestampAtSlot(Endian.fromLittleEndianUint64(withdrawalProofs.slotRoot)), podOwner, withdrawalAmountGwei, address(newPod)); - emit PartialWithdrawalRedeemed( - validatorIndex, - _computeTimestampAtSlot(Endian.fromLittleEndianUint64(withdrawalProofs.slotRoot)), - podOwner, - withdrawalAmountGwei - ); - newPod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofsArray, - validatorFieldsProofArray, - validatorFieldsArray, - withdrawalFieldsArray - ); - require( - newPod.provenWithdrawal( - validatorFields[0], - _computeTimestampAtSlot(Endian.fromLittleEndianUint64(withdrawalProofs.slotRoot)) - ), - "provenPartialWithdrawal should be true" - ); - withdrawalAmountGwei = uint64(withdrawalAmountGwei * GWEI_TO_WEI); - require( - address(delayedWithdrawalRouter).balance - delayedWithdrawalRouterContractBalanceBefore == - withdrawalAmountGwei, - "pod delayed withdrawal balance hasn't been updated correctly" - ); - } - - cheats.roll(block.number + WITHDRAWAL_DELAY_BLOCKS + 1); - uint256 podOwnerBalanceBefore = address(podOwner).balance; - delayedWithdrawalRouter.claimDelayedWithdrawals(podOwner, 1); - require( - address(podOwner).balance - podOwnerBalanceBefore == withdrawalAmountGwei, - "Pod owner balance hasn't been updated correctly" - ); - return newPod; - } - - /// @notice verifies that multiple partial withdrawals can be made before a full withdrawal - function testProvingMultiplePartialWithdrawalsForSameSlot() public /*uint256 numPartialWithdrawals*/ { - IEigenPod newPod = testPartialWithdrawalFlow(); - - BeaconChainProofs.WithdrawalProof memory withdrawalProofs = _getWithdrawalProof(); - bytes memory validatorFieldsProof = abi.encodePacked(getValidatorProof()); - withdrawalFields = getWithdrawalFields(); - validatorFields = getValidatorFields(); - - BeaconChainProofs.WithdrawalProof[] memory withdrawalProofsArray = new BeaconChainProofs.WithdrawalProof[](1); - withdrawalProofsArray[0] = withdrawalProofs; - bytes[] memory validatorFieldsProofArray = new bytes[](1); - validatorFieldsProofArray[0] = validatorFieldsProof; - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = validatorFields; - bytes32[][] memory withdrawalFieldsArray = new bytes32[][](1); - withdrawalFieldsArray[0] = withdrawalFields; - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - cheats.expectRevert( - bytes("EigenPod._verifyAndProcessWithdrawal: withdrawal has already been proven for this timestamp") - ); - newPod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofsArray, - validatorFieldsProofArray, - validatorFieldsArray, - withdrawalFieldsArray - ); - } - - /// @notice verifies that multiple full withdrawals for a single validator fail - function testDoubleFullWithdrawal() public returns (IEigenPod newPod) { - newPod = testFullWithdrawalFlow(); - uint64 withdrawalAmountGwei = Endian.fromLittleEndianUint64( - withdrawalFields[BeaconChainProofs.WITHDRAWAL_VALIDATOR_AMOUNT_INDEX] - ); - uint64 leftOverBalanceWEI = uint64(withdrawalAmountGwei - newPod.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR()) * - uint64(GWEI_TO_WEI); - cheats.deal(address(newPod), leftOverBalanceWEI); - - BeaconChainProofs.WithdrawalProof memory withdrawalProofs = _getWithdrawalProof(); - bytes memory validatorFieldsProof = abi.encodePacked(getValidatorProof()); - withdrawalFields = getWithdrawalFields(); - validatorFields = getValidatorFields(); - - BeaconChainProofs.WithdrawalProof[] memory withdrawalProofsArray = new BeaconChainProofs.WithdrawalProof[](1); - withdrawalProofsArray[0] = withdrawalProofs; - bytes[] memory validatorFieldsProofArray = new bytes[](1); - validatorFieldsProofArray[0] = validatorFieldsProof; - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = validatorFields; - bytes32[][] memory withdrawalFieldsArray = new bytes32[][](1); - withdrawalFieldsArray[0] = withdrawalFields; - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - cheats.expectRevert( - bytes("EigenPod._verifyAndProcessWithdrawal: withdrawal has already been proven for this timestamp") - ); - newPod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofsArray, - validatorFieldsProofArray, - validatorFieldsArray, - withdrawalFieldsArray - ); - - return newPod; - } - - function testDeployAndVerifyNewEigenPod() public returns (IEigenPod) { - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - return _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - } - - // test freezing operator after a beacon chain slashing event - function testUpdateSlashedBeaconBalance() public { - _deployInternalFunctionTester(); - //make initial deposit - // ./solidityProofGen "BalanceUpdateProof" 302913 false 0 "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_notOverCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); - _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - cheats.warp(block.timestamp + 1); - // ./solidityProofGen "BalanceUpdateProof" 302913 true 0 "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_overCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_updated_to_0ETH_302913.json"); - _proveOverCommittedStake(newPod); - - uint64 newValidatorBalance = _getValidatorUpdatedBalance(); - int256 beaconChainETHShares = eigenPodManager.podOwnerShares(podOwner); - - require( - beaconChainETHShares == int256((newValidatorBalance) * GWEI_TO_WEI), - "eigenPodManager shares not updated correctly" - ); - } - - /// @notice Similar test done in EP unit test - //test deploying an eigen pod with mismatched withdrawal credentials between the proof and the actual pod's address - function testDeployNewEigenPodWithWrongWithdrawalCreds(address wrongWithdrawalAddress) public { - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - cheats.startPrank(podOwner); - IEigenPod newPod; - newPod = eigenPodManager.getPod(podOwner); - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(pubkey); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - - - // make sure that wrongWithdrawalAddress is not set to actual pod address - cheats.assume(wrongWithdrawalAddress != address(newPod)); - - validatorFields = getValidatorFields(); - validatorFields[1] = abi.encodePacked(bytes1(uint8(1)), bytes11(0), wrongWithdrawalAddress).toBytes32(0); - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = validatorFields; - bytes[] memory proofsArray = new bytes[](1); - proofsArray[0] = abi.encodePacked(getWithdrawalCredentialProof()); - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(validatorIndex0); - - cheats.startPrank(podOwner); - if (!newPod.hasRestaked()) { - newPod.activateRestaking(); - } - // set oracle block root - _setOracleBlockRoot(); - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - uint64 timestamp = _verifyWCStartTimestamp(newPod); - cheats.warp(timestamp); - - cheats.expectRevert(bytes("EigenPod.verifyCorrectWithdrawalCredentials: Proof is not for this EigenPod")); - newPod.verifyWithdrawalCredentials( - timestamp, - stateRootProofStruct, - validatorIndices, - proofsArray, - validatorFieldsArray - ); - cheats.stopPrank(); - } - //ensures that a validator proving WC after they have exited the beacon chain is allowed to - //prove their WC and process a withdrawal - function testProveWithdrawalCredentialsAfterValidatorExit() public { - // ./solidityProofGen -newBalance=0 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913_exited.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913_exited.json"); - emit log("hello"); - - IEigenPod newPod = _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - //./solidityProofGen "WithdrawalFieldsProof" 302913 146 8092 true false "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6397852.json" "data/withdrawal_proof_goerli/goerli_block_header_6397852.json" "data/withdrawal_proof_goerli/goerli_block_6397852.json" "fullWithdrawalProof_Latest.json" false - // To get block header: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v1/beacon/headers/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_header_6399000.json - // To get block: curl -H "Accept: application/json" 'https://eigenlayer.spiceai.io/goerli/beacon/eth/v2/beacon/blocks/6399000?api_key\="343035|f6ebfef661524745abb4f1fd908a76e8"' > block_6399000.json - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - _proveWithdrawalForPod(newPod); - } - - function testVerifyWithdrawalCredsFromNonPodOwnerAddress(address nonPodOwnerAddress) public { - // nonPodOwnerAddress must be different from podOwner - cheats.assume(nonPodOwnerAddress != podOwner); - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - cheats.startPrank(podOwner); - - IEigenPod newPod = eigenPodManager.getPod(podOwner); - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(pubkey); - - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - bytes[] memory proofsArray = new bytes[](1); - proofsArray[0] = abi.encodePacked(getWithdrawalCredentialProof()); - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(validatorIndex0); - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - uint64 timestamp = _verifyWCStartTimestamp(newPod); - cheats.warp(timestamp); - - cheats.startPrank(nonPodOwnerAddress); - cheats.expectRevert(bytes("EigenPod.onlyEigenPodOwner: not podOwner")); - newPod.verifyWithdrawalCredentials( - timestamp, - stateRootProofStruct, - validatorIndices, - proofsArray, - validatorFieldsArray - ); - cheats.stopPrank(); - } - - function testBalanceProofWithWrongTimestamp(uint64 timestamp) public { - cheats.assume(timestamp > GOERLI_GENESIS_TIME); - // ./solidityProofGen "BalanceUpdateProof" 302913 false 0 "data/withdrawal_proof_goerli/goerli_slot_6399999.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_notOverCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); - IEigenPod newPod = testDeployAndVerifyNewEigenPod(); - - // ./solidityProofGen "BalanceUpdateProof" 302913 true 0 "data/withdrawal_proof_goerli/goerli_slot_6399999.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_overCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_updated_to_0ETH_302913.json"); - // prove overcommitted balance - cheats.warp(timestamp); - _proveOverCommittedStake(newPod); - - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(getValidatorIndex()); - - bytes memory proof = abi.encodePacked(getBalanceUpdateProof()); - bytes[] memory proofs = new bytes[](1); - proofs[0] = proof; - - bytes32 newLatestBlockRoot = getLatestBlockRoot(); - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(newLatestBlockRoot); - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - cheats.expectRevert(bytes("EigenPod.verifyBalanceUpdate: Validators balance has already been updated for this timestamp")); - newPod.verifyBalanceUpdates(uint64(block.timestamp - 1), validatorIndices, stateRootProofStruct, proofs, validatorFieldsArray); - } - - // // 3. Single withdrawal credential - // // Test: Owner proves an withdrawal credential. - // // validator status should be marked as ACTIVE - - function testProveSingleWithdrawalCredential() public { - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - IEigenPod pod = _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - bytes32 validatorPubkeyHash = getValidatorPubkeyHash(); - - assertTrue( - pod.validatorStatus(validatorPubkeyHash) == IEigenPod.VALIDATOR_STATUS.ACTIVE, - "wrong validator status" - ); - } - - // 5. Prove overcommitted balance - // Setup: Run (3). - // Test: Watcher proves an overcommitted balance for validator from (3). - // validator status should be marked as OVERCOMMITTED - - function testProveOverCommittedBalance() public { - _deployInternalFunctionTester(); - // ./solidityProofGen "BalanceUpdateProof" 302913 false 0 "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_notOverCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); - IEigenPod newPod = _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - // get beaconChainETH shares - int256 beaconChainETHBefore = eigenPodManager.podOwnerShares(podOwner); - - bytes32 validatorPubkeyHash = getValidatorPubkeyHash(); - uint256 validatorRestakedBalanceBefore = newPod - .validatorPubkeyHashToInfo(validatorPubkeyHash) - .restakedBalanceGwei; - - // ./solidityProofGen "BalanceUpdateProof" 302913 true 0 "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_overCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_updated_to_0ETH_302913.json"); - // prove overcommitted balance - cheats.warp(block.timestamp + 1); - _proveOverCommittedStake(newPod); - - uint256 validatorRestakedBalanceAfter = newPod - .validatorPubkeyHashToInfo(validatorPubkeyHash) - .restakedBalanceGwei; - - uint64 newValidatorBalance = _getValidatorUpdatedBalance(); - int256 shareDiff = beaconChainETHBefore - eigenPodManager.podOwnerShares(podOwner); - assertTrue( - eigenPodManager.podOwnerShares(podOwner) == - int256(newValidatorBalance * GWEI_TO_WEI), - "hysterisis not working" - ); - assertTrue( - beaconChainETHBefore - eigenPodManager.podOwnerShares(podOwner) == shareDiff, - "BeaconChainETHShares not updated" - ); - assertTrue( - int256(validatorRestakedBalanceBefore) - int256(validatorRestakedBalanceAfter) == - shareDiff / int256(GWEI_TO_WEI), - "validator restaked balance not updated" - ); - } - - function testVerifyUndercommittedBalance() public { - _deployInternalFunctionTester(); - // ./solidityProofGen "BalanceUpdateProof" 302913 false 0 "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_notOverCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); - IEigenPod newPod = _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - // get beaconChainETH shares - int256 beaconChainETHBefore = eigenPodManager.podOwnerShares(podOwner); - bytes32 validatorPubkeyHash = getValidatorPubkeyHash(); - uint256 validatorRestakedBalanceBefore = newPod - .validatorPubkeyHashToInfo(validatorPubkeyHash) - .restakedBalanceGwei; - - // ./solidityProofGen "BalanceUpdateProof" 302913 true 0 "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_overCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_updated_to_0ETH_302913.json"); - // prove overcommitted balance - cheats.warp(block.timestamp + 1); - _proveOverCommittedStake(newPod); - - cheats.warp(block.timestamp + 1); - // ./solidityProofGen "BalanceUpdateProof" 302913 false 100 "data/withdrawal_proof_goerli/goerli_slot_6399999.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_notOverCommitted_302913_incrementedBlockBy100.json" - setJSON("./src/test/test-data/balanceUpdateProof_notOverCommitted_302913_incrementedBlockBy100.json"); - _proveUnderCommittedStake(newPod); - - uint256 validatorRestakedBalanceAfter = newPod - .validatorPubkeyHashToInfo(validatorPubkeyHash) - .restakedBalanceGwei; - - int256 shareDiff = beaconChainETHBefore - eigenPodManager.podOwnerShares(podOwner); - - assertTrue( - eigenPodManager.podOwnerShares(podOwner) == - int256((MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) * GWEI_TO_WEI), - "hysterisis not working" - ); - assertTrue( - beaconChainETHBefore - eigenPodManager.podOwnerShares(podOwner) == shareDiff, - "BeaconChainETHShares not updated" - ); - assertTrue( - int256(uint256(validatorRestakedBalanceBefore)) - int256(uint256(validatorRestakedBalanceAfter)) == - shareDiff / int256(GWEI_TO_WEI), - "validator restaked balance not updated" - ); - } - - function testDeployingEigenPodRevertsWhenPaused() external { - // pause the contract - cheats.startPrank(pauser); - eigenPodManager.pause(2 ** PAUSED_NEW_EIGENPODS); - cheats.stopPrank(); - - cheats.startPrank(podOwner); - cheats.expectRevert(bytes("Pausable: index is paused")); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - } - - function testCreatePodWhenPaused() external { - // pause the contract - cheats.startPrank(pauser); - eigenPodManager.pause(2 ** PAUSED_NEW_EIGENPODS); - cheats.stopPrank(); - - cheats.startPrank(podOwner); - cheats.expectRevert(bytes("Pausable: index is paused")); - eigenPodManager.createPod(); - cheats.stopPrank(); - } - - function testCreatePodIfItReturnsPodAddress() external { - cheats.startPrank(podOwner); - address _podAddress = eigenPodManager.createPod(); - cheats.stopPrank(); - IEigenPod pod = eigenPodManager.getPod(podOwner); - require(_podAddress == address(pod), "invalid pod address"); - } - - function testStakeOnEigenPodFromNonPodManagerAddress(address nonPodManager) external fuzzedAddress(nonPodManager) { - cheats.assume(nonPodManager != address(eigenPodManager)); - - cheats.startPrank(podOwner); - IEigenPod newPod = eigenPodManager.getPod(podOwner); - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(pubkey); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - - cheats.deal(nonPodManager, stakeAmount); - - cheats.startPrank(nonPodManager); - cheats.expectRevert(bytes("EigenPod.onlyEigenPodManager: not eigenPodManager")); - newPod.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - } - - function testCallWithdrawBeforeRestakingFromNonOwner(address nonPodOwner) external fuzzedAddress(nonPodOwner) { - cheats.assume(nonPodOwner != podOwner); - testStaking(); - IEigenPod pod = eigenPodManager.getPod(podOwner); - - // this is testing if pods deployed before M2 that do not have hasRestaked initialized to true, will revert - cheats.store(address(pod), bytes32(uint256(52)), bytes32(0)); - require(pod.hasRestaked() == false, "Pod should not be restaked"); - - //simulate a withdrawal - cheats.startPrank(nonPodOwner); - cheats.expectRevert(bytes("EigenPod.onlyEigenPodOwner: not podOwner")); - pod.withdrawBeforeRestaking(); - } - - /* test deprecated since this is checked on the EigenPodManager level, rather than the EigenPod level - TODO: @Sidu28 - check whether we have adequate coverage of the correct function - function testWithdrawRestakedBeaconChainETHRevertsWhenPaused() external { - // pause the contract - cheats.startPrank(pauser); - eigenPodManager.pause(2 ** PAUSED_WITHDRAW_RESTAKED_ETH); - cheats.stopPrank(); - - address recipient = address(this); - uint256 amount = 1e18; - IEigenPod eigenPod = eigenPodManager.getPod(podOwner); - cheats.startPrank(address(eigenPodManager)); - cheats.expectRevert(bytes("Pausable: index is paused")); - eigenPod.withdrawRestakedBeaconChainETH(recipient, amount); - cheats.stopPrank(); - } - */ - - function testVerifyCorrectWithdrawalCredentialsRevertsWhenPaused() external { - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - bytes32 newBeaconStateRoot = getBeaconStateRoot(); - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(newBeaconStateRoot); - - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - cheats.startPrank(podOwner); - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(pubkey); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - - // pause the contract - cheats.startPrank(pauser); - eigenPodManager.pause(2 ** PAUSED_EIGENPODS_VERIFY_CREDENTIALS); - cheats.stopPrank(); - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - - bytes[] memory proofsArray = new bytes[](1); - proofsArray[0] = abi.encodePacked(getWithdrawalCredentialProof()); - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(getValidatorIndex()); - - uint64 timestamp = _verifyWCStartTimestamp(newPod); - cheats.warp(timestamp); - - cheats.startPrank(podOwner); - cheats.expectRevert(bytes("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager")); - newPod.verifyWithdrawalCredentials( - timestamp, - stateRootProofStruct, - validatorIndices, - proofsArray, - validatorFieldsArray - ); - cheats.stopPrank(); - } - - function testVerifyOvercommittedStakeRevertsWhenPaused() external { - // ./solidityProofGen "BalanceUpdateProof" 302913 false 0 "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_notOverCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); - IEigenPod newPod = _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - - // ./solidityProofGen "BalanceUpdateProof" 302913 true 0 "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "balanceUpdateProof_overCommitted_302913.json" - setJSON("./src/test/test-data/balanceUpdateProof_updated_to_0ETH_302913.json"); - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(getValidatorIndex()); - - bytes[] memory proofs = new bytes[](1); - proofs[0] = abi.encodePacked(getBalanceUpdateProof()); - - bytes32 newBeaconStateRoot = getBeaconStateRoot(); - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(newBeaconStateRoot); - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - // pause the contract - cheats.startPrank(pauser); - eigenPodManager.pause(2 ** PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE); - cheats.stopPrank(); - - cheats.expectRevert(bytes("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager")); - newPod.verifyBalanceUpdates(0, validatorIndices, stateRootProofStruct, proofs, validatorFieldsArray); - } - - function _proveOverCommittedStake(IEigenPod newPod) internal { - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(getValidatorIndex()); - - bytes[] memory proofs = new bytes[](1); - proofs[0] = abi.encodePacked(getBalanceUpdateProof()); - - bytes32 newLatestBlockRoot = getLatestBlockRoot(); - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(newLatestBlockRoot); - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - newPod.verifyBalanceUpdates( - uint64(block.timestamp), - validatorIndices, - stateRootProofStruct, - proofs, - validatorFieldsArray - ); - } - - function _proveUnderCommittedStake(IEigenPod newPod) internal { - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(getValidatorIndex()); - - bytes[] memory proofs = new bytes[](1); - proofs[0] = abi.encodePacked(getBalanceUpdateProof()); - - bytes32 newLatestBlockRoot = getLatestBlockRoot(); - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(newLatestBlockRoot); - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - newPod.verifyBalanceUpdates( - uint64(block.timestamp), - validatorIndices, - stateRootProofStruct, - proofs, - validatorFieldsArray - ); - require(newPod.validatorPubkeyHashToInfo(getValidatorPubkeyHash()).status == IEigenPod.VALIDATOR_STATUS.ACTIVE); - } - - function _getValidatorUpdatedBalance() internal returns (uint64) { - bytes32[] memory validatorFieldsToGet = getValidatorFields(); - return validatorFieldsToGet.getEffectiveBalanceGwei(); - } - - function testStake(bytes calldata _pubkey, bytes calldata _signature, bytes32 _depositDataRoot) public { - // should fail if no/wrong value is provided - cheats.startPrank(podOwner); - cheats.expectRevert("EigenPod.stake: must initially stake for any validator with 32 ether"); - eigenPodManager.stake(_pubkey, _signature, _depositDataRoot); - cheats.expectRevert("EigenPod.stake: must initially stake for any validator with 32 ether"); - eigenPodManager.stake{value: 12 ether}(_pubkey, _signature, _depositDataRoot); - - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - // successful call - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(_pubkey); - eigenPodManager.stake{value: 32 ether}(_pubkey, _signature, _depositDataRoot); - cheats.stopPrank(); - } - - /// @notice Test that the Merkle proof verification fails when the proof length is 0 - function testVerifyInclusionSha256FailsForEmptyProof(bytes32 root, bytes32 leaf, uint256 index) public { - bytes memory emptyProof = new bytes(0); - cheats.expectRevert( - bytes("Merkle.processInclusionProofSha256: proof length should be a non-zero multiple of 32") - ); - Merkle.verifyInclusionSha256(emptyProof, root, leaf, index); - } - - /// @notice Test that the Merkle proof verification fails when the proof length is not a multple of 32 - function testVerifyInclusionSha256FailsForNonMultipleOf32ProofLength( - bytes32 root, - bytes32 leaf, - uint256 index, - bytes memory proof - ) public { - cheats.assume(proof.length % 32 != 0); - cheats.expectRevert( - bytes("Merkle.processInclusionProofSha256: proof length should be a non-zero multiple of 32") - ); - Merkle.verifyInclusionSha256(proof, root, leaf, index); - } - - // verifies that the `numPod` variable increments correctly on a succesful call to the `EigenPod.stake` function - function test_incrementNumPodsOnStake( - bytes calldata _pubkey, - bytes calldata _signature, - bytes32 _depositDataRoot - ) public { - uint256 numPodsBefore = EigenPodManager(address(eigenPodManager)).numPods(); - testStake(_pubkey, _signature, _depositDataRoot); - uint256 numPodsAfter = EigenPodManager(address(eigenPodManager)).numPods(); - require(numPodsAfter == numPodsBefore + 1, "numPods did not increment correctly"); - } - - // verifies that the `numPod` variable increments correctly on a succesful call to the `EigenPod.createPod` function - function test_incrementNumPodsOnCreatePod() public { - uint256 numPodsBefore = EigenPodManager(address(eigenPodManager)).numPods(); - eigenPodManager.createPod(); - uint256 numPodsAfter = EigenPodManager(address(eigenPodManager)).numPods(); - require(numPodsAfter == numPodsBefore + 1, "numPods did not increment correctly"); - } - - function test_createPodTwiceFails() public { - eigenPodManager.createPod(); - cheats.expectRevert(bytes("EigenPodManager.createPod: Sender already has a pod")); - eigenPodManager.createPod(); - } - - function test_validatorPubkeyToInfo() external { - bytes memory _pubkey = hex"93a0dd04ccddf3f1b419fdebf99481a2182c17d67cf14d32d6e50fc4bf8effc8db4a04b7c2f3a5975c1b9b74e2841888"; - - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - IEigenPod pod = eigenPodManager.getPod(podOwner); - - IEigenPod.ValidatorInfo memory info1 = pod.validatorPubkeyToInfo(_pubkey); - IEigenPod.ValidatorInfo memory info2 = pod.validatorPubkeyHashToInfo(getValidatorPubkeyHash()); - - require(info1.validatorIndex == info2.validatorIndex, "validatorIndex does not match"); - require(info1.restakedBalanceGwei > 0, "restakedBalanceGwei is 0"); - require(info1.restakedBalanceGwei == info2.restakedBalanceGwei, "restakedBalanceGwei does not match"); - require(info1.mostRecentBalanceUpdateTimestamp == info2.mostRecentBalanceUpdateTimestamp, "mostRecentBalanceUpdateTimestamp does not match"); - require(info1.status == info2.status, "status does not match"); - } - - function test_validatorStatus() external { - bytes memory _pubkey = hex"93a0dd04ccddf3f1b419fdebf99481a2182c17d67cf14d32d6e50fc4bf8effc8db4a04b7c2f3a5975c1b9b74e2841888"; - - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - IEigenPod pod = eigenPodManager.getPod(podOwner); - - IEigenPod.VALIDATOR_STATUS status1 = pod.validatorStatus(_pubkey); - IEigenPod.VALIDATOR_STATUS status2 = pod.validatorStatus(getValidatorPubkeyHash()); - - require(status1 == status2, "status does not match"); - } - - /* TODO: reimplement similar tests - function testQueueBeaconChainETHWithdrawalWithoutProvingFullWithdrawal() external { - // ./solidityProofGen -newBalance=32000115173 "ValidatorFieldsProof" 302913 true "data/withdrawal_proof_goerli/goerli_block_header_6399998.json" "data/withdrawal_proof_goerli/goerli_slot_6399998.json" "withdrawal_credential_proof_302913.json" - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _testDeployAndVerifyNewEigenPod(podOwner, signature, depositDataRoot); - uint256 shareAmount = 32e18; - // expect revert from underflow - cheats.expectRevert(); - _testQueueWithdrawal(podOwner, shareAmount); - } - - function testQueueBeaconChainETHWithdrawal() external { - IEigenPod pod = testFullWithdrawalFlow(); - - bytes32 validatorPubkeyHash = getValidatorPubkeyHash(); - - uint256 withdrawableRestakedExecutionLayerGweiBefore = pod.withdrawableRestakedExecutionLayerGwei(); - - uint256 shareAmount = (pod.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR()) * GWEI_TO_WEI; - _verifyEigenPodBalanceSharesInvariant(podOwner, pod, validatorPubkeyHash); - _testQueueWithdrawal(podOwner, shareAmount); - _verifyEigenPodBalanceSharesInvariant(podOwner, pod, validatorPubkeyHash); - - require(withdrawableRestakedExecutionLayerGweiBefore - pod.withdrawableRestakedExecutionLayerGwei() == shareAmount/int256(GWEI_TO_WEI), - "withdrawableRestakedExecutionLayerGwei not decremented correctly"); - } -*/ - function _verifyEigenPodBalanceSharesInvariant( - address podowner, - IEigenPod pod, - bytes32 validatorPubkeyHash - ) internal view { - int256 shares = eigenPodManager.podOwnerShares(podowner); - uint64 withdrawableRestakedExecutionLayerGwei = pod.withdrawableRestakedExecutionLayerGwei(); - - EigenPod.ValidatorInfo memory info = pod.validatorPubkeyHashToInfo(validatorPubkeyHash); - - uint64 validatorBalanceGwei = info.restakedBalanceGwei; - require( - shares / int256(GWEI_TO_WEI) == - int256(uint256(validatorBalanceGwei)) + int256(uint256(withdrawableRestakedExecutionLayerGwei)), - "EigenPod invariant violated: sharesInSM != withdrawableRestakedExecutionLayerGwei" - ); - } - - function _proveWithdrawalForPod(IEigenPod newPod) internal returns (IEigenPod) { - BeaconChainOracleMock(address(beaconChainOracle)).setOracleBlockRootAtTimestamp(getLatestBlockRoot()); - uint64 restakedExecutionLayerGweiBefore = newPod.withdrawableRestakedExecutionLayerGwei(); - - withdrawalFields = getWithdrawalFields(); - uint64 withdrawalAmountGwei = Endian.fromLittleEndianUint64( - withdrawalFields[BeaconChainProofs.WITHDRAWAL_VALIDATOR_AMOUNT_INDEX] - ); - emit log_named_uint("withdrawalAmountGwei", withdrawalAmountGwei); - uint64 leftOverBalanceWEI = uint64(withdrawalAmountGwei - newPod.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR()) * - uint64(GWEI_TO_WEI); - cheats.deal(address(newPod), leftOverBalanceWEI); - emit log_named_uint("leftOverBalanceWEI", leftOverBalanceWEI); - emit log_named_uint("address(newPod)", address(newPod).balance); - emit log_named_uint("withdrawalAmountGwei", withdrawalAmountGwei); - - uint256 delayedWithdrawalRouterContractBalanceBefore = address(delayedWithdrawalRouter).balance; - { - BeaconChainProofs.WithdrawalProof[] memory withdrawalProofsArray = new BeaconChainProofs.WithdrawalProof[]( - 1 - ); - withdrawalProofsArray[0] = _getWithdrawalProof(); - bytes[] memory validatorFieldsProofArray = new bytes[](1); - validatorFieldsProofArray[0] = abi.encodePacked(getValidatorProof()); - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - bytes32[][] memory withdrawalFieldsArray = new bytes32[][](1); - withdrawalFieldsArray[0] = withdrawalFields; - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - newPod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofsArray, - validatorFieldsProofArray, - validatorFieldsArray, - withdrawalFieldsArray - ); - } - require( - newPod.withdrawableRestakedExecutionLayerGwei() - restakedExecutionLayerGweiBefore == - newPod.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR(), - "restakedExecutionLayerGwei has not been incremented correctly" - ); - require( - address(delayedWithdrawalRouter).balance - delayedWithdrawalRouterContractBalanceBefore == - leftOverBalanceWEI, - "pod delayed withdrawal balance hasn't been updated correctly" - ); - require( - newPod.validatorPubkeyHashToInfo(getValidatorPubkeyHash()).restakedBalanceGwei == 0, - "balance not reset correctly" - ); - - cheats.roll(block.number + WITHDRAWAL_DELAY_BLOCKS + 1); - uint256 podOwnerBalanceBefore = address(podOwner).balance; - delayedWithdrawalRouter.claimDelayedWithdrawals(podOwner, 1); - require( - address(podOwner).balance - podOwnerBalanceBefore == leftOverBalanceWEI, - "Pod owner balance hasn't been updated correctly" - ); - return newPod; - } - - // simply tries to register 'sender' as a delegate, setting their 'DelegationTerms' contract in DelegationManager to 'dt' - // verifies that the storage of DelegationManager contract is updated appropriately - function _testRegisterAsOperator( - address sender, - IDelegationManager.OperatorDetails memory operatorDetails - ) internal { - cheats.startPrank(sender); - string memory emptyStringForMetadataURI; - delegation.registerAsOperator(operatorDetails, emptyStringForMetadataURI); - assertTrue(delegation.isOperator(sender), "testRegisterAsOperator: sender is not a delegate"); - - // TODO: FIX THIS - // assertTrue( - // delegation.delegationTerms(sender) == dt, "_testRegisterAsOperator: delegationTerms not set appropriately" - // ); - - assertTrue(delegation.isDelegated(sender), "_testRegisterAsOperator: sender not marked as actively delegated"); - cheats.stopPrank(); - } - - function _testDelegateToOperator(address sender, address operator) internal { - //delegator-specific information - (IStrategy[] memory delegateStrategies, uint256[] memory delegateShares) = strategyManager.getDeposits(sender); - - uint256 numStrats = delegateShares.length; - assertTrue(numStrats > 0, "_testDelegateToOperator: delegating from address with no deposits"); - uint256[] memory inititalSharesInStrats = new uint256[](numStrats); - for (uint256 i = 0; i < numStrats; ++i) { - inititalSharesInStrats[i] = delegation.operatorShares(operator, delegateStrategies[i]); - } - - cheats.startPrank(sender); - IDelegationManager.SignatureWithExpiry memory signatureWithExpiry; - delegation.delegateTo(operator, signatureWithExpiry, bytes32(0)); - cheats.stopPrank(); - - assertTrue( - delegation.delegatedTo(sender) == operator, - "_testDelegateToOperator: delegated address not set appropriately" - ); - assertTrue(delegation.isDelegated(sender), "_testDelegateToOperator: delegated status not set appropriately"); - - for (uint256 i = 0; i < numStrats; ++i) { - uint256 operatorSharesBefore = inititalSharesInStrats[i]; - uint256 operatorSharesAfter = delegation.operatorShares(operator, delegateStrategies[i]); - assertTrue( - operatorSharesAfter == (operatorSharesBefore + delegateShares[i]), - "_testDelegateToOperator: delegatedShares not increased correctly" - ); - } - } - - function _testDelegation(address operator, address staker) internal { - if (!delegation.isOperator(operator)) { - IDelegationManager.OperatorDetails memory operatorDetails = IDelegationManager.OperatorDetails({ - __deprecated_earningsReceiver: operator, - delegationApprover: address(0), - stakerOptOutWindowBlocks: 0 - }); - _testRegisterAsOperator(operator, operatorDetails); - } - - //making additional deposits to the strategies - assertTrue(!delegation.isDelegated(staker) == true, "testDelegation: staker is not delegate"); - _testDelegateToOperator(staker, operator); - assertTrue(delegation.isDelegated(staker) == true, "testDelegation: staker is not delegate"); - - IStrategy[] memory updatedStrategies; - uint256[] memory updatedShares; - (updatedStrategies, updatedShares) = strategyManager.getDeposits(staker); - } - - function _testDeployAndVerifyNewEigenPod( - address _podOwner, - bytes memory _signature, - bytes32 _depositDataRoot - ) internal returns (IEigenPod) { - IEigenPod newPod = eigenPodManager.getPod(_podOwner); - - cheats.startPrank(_podOwner); - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(pubkey); - eigenPodManager.stake{value: stakeAmount}(pubkey, _signature, _depositDataRoot); - cheats.stopPrank(); - - return _verifyWithdrawalCredentials(newPod, _podOwner); - } - - function _verifyWithdrawalCredentials(IEigenPod newPod, address _podOwner) internal returns (IEigenPod) { - _deployInternalFunctionTester(); - uint64 timestamp = EigenPod(payable(address(newPod))).GENESIS_TIME(); - // cheats.expectEmit(true, true, true, true, address(newPod)); - // emit ValidatorRestaked(validatorIndex); - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - validatorFieldsArray[0] = getValidatorFields(); - - bytes[] memory proofsArray = new bytes[](1); - proofsArray[0] = abi.encodePacked(getWithdrawalCredentialProof()); - - uint40[] memory validatorIndices = new uint40[](1); - validatorIndices[0] = uint40(getValidatorIndex()); - - BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - - int256 beaconChainETHSharesBefore = eigenPodManager.podOwnerShares(_podOwner); - - cheats.startPrank(_podOwner); - cheats.warp(timestamp); - if (newPod.hasRestaked() == false) { - newPod.activateRestaking(); - } - //set the oracle block root - _setOracleBlockRoot(); - - emit log_named_bytes32( - "restaking activated", - BeaconChainOracleMock(address(beaconChainOracle)).mockBeaconChainStateRoot() - ); - - timestamp = _verifyWCStartTimestamp(newPod); - cheats.warp(timestamp); - newPod.verifyWithdrawalCredentials( - timestamp, - stateRootProofStruct, - validatorIndices, - proofsArray, - validatorFieldsArray - ); - cheats.stopPrank(); - - int256 beaconChainETHSharesAfter = eigenPodManager.podOwnerShares(_podOwner); - uint256 effectiveBalance = uint256(Endian.fromLittleEndianUint64(validatorFieldsArray[0][2]) * GWEI_TO_WEI); - - emit log_named_uint("effectiveBalance", effectiveBalance); - emit log_named_uint("MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR", MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR * GWEI_TO_WEI); - emit log_named_uint("beaconChainETHSharesAfter", uint256(beaconChainETHSharesAfter)); - emit log_named_uint("beaconChainETHSharesBefore", uint256(beaconChainETHSharesBefore)); - - if(effectiveBalance < MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR * GWEI_TO_WEI){ - require( - (beaconChainETHSharesAfter - beaconChainETHSharesBefore) == int256(effectiveBalance), - "eigenPodManager shares not updated correctly" - ); - } else { - emit log("here)"); - require( - (beaconChainETHSharesAfter - beaconChainETHSharesBefore) == int256(uint256(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR * GWEI_TO_WEI)), - "eigenPodManager shares not updated correctly" - ); - emit log("here)"); - - } - return newPod; - } - - function _verifyWCStartTimestamp(IEigenPod pod) internal returns (uint64) { - uint64 genesis = EigenPod(payable(address(pod))).GENESIS_TIME(); - uint64 activateRestakingTimestamp = pod.mostRecentWithdrawalTimestamp(); - - // For pods deployed after M2, `mostRecentWithdrawalTimestamp` will always be 0 - // In order to give our `_nextEpochStartTimestamp` a sane calculation, we set it - // to the genesis time - if (activateRestakingTimestamp == 0) { - activateRestakingTimestamp = uint64(block.timestamp); - } - - emit log_named_uint("genesis", genesis); - emit log_named_uint("activation", activateRestakingTimestamp); - - return _nextEpochStartTimestamp(genesis, activateRestakingTimestamp); - } - - /// @dev Given a genesis time and a timestamp, converts the timestamp to an epoch - /// then calculates the next epoch's start timestamp. Used for the verifyWC proof window. - function _nextEpochStartTimestamp(uint64 genesisTime, uint64 timestamp) internal pure returns (uint64) { - require(timestamp >= genesisTime, "_verifyWCStartTimestamp: timestamp is before genesis"); - uint64 epoch = (timestamp - genesisTime) / BeaconChainProofs.SECONDS_PER_EPOCH; - - return genesisTime + ((1 + epoch) * BeaconChainProofs.SECONDS_PER_EPOCH); - } - - /* TODO: reimplement similar tests - function _testQueueWithdrawal( - address _podOwner, - uint256 amountWei - ) - internal - returns (bytes32) - { - //make a call from _podOwner to queue the withdrawal - cheats.startPrank(_podOwner); - bytes32 withdrawalRoot = eigenPodManager.queueWithdrawal( - amountWei, - _podOwner - ); - cheats.stopPrank(); - return withdrawalRoot; - } -*/ - function _getLatestDelayedWithdrawalAmount(address recipient) internal view returns (uint256) { - return - delayedWithdrawalRouter - .userDelayedWithdrawalByIndex(recipient, delayedWithdrawalRouter.userWithdrawalsLength(recipient) - 1) - .amount; - } - - function _getStateRootProof() internal returns (BeaconChainProofs.StateRootProof memory) { - return BeaconChainProofs.StateRootProof(getBeaconStateRoot(), abi.encodePacked(getStateRootProof())); - } - - /// @notice this function just generates a valid proof so that we can test other functionalities of the withdrawal flow - function _getWithdrawalProof() internal returns (BeaconChainProofs.WithdrawalProof memory) { - IEigenPod newPod = eigenPodManager.getPod(podOwner); - - //make initial deposit - cheats.startPrank(podOwner); - cheats.expectEmit(true, true, true, true, address(newPod)); - emit EigenPodStaked(pubkey); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - - if(!IS_DENEB){ - emit log("NOT DENEB"); - } - bytes memory withdrawalProof = IS_DENEB ? abi.encodePacked(getWithdrawalProofDeneb()) : abi.encodePacked(getWithdrawalProofCapella()); - bytes memory timestampProof = IS_DENEB ? abi.encodePacked(getTimestampProofDeneb()) : abi.encodePacked(getTimestampProofCapella()); - { - bytes32 blockRoot = getBlockRoot(); - bytes32 slotRoot = getSlotRoot(); - bytes32 timestampRoot = getTimestampRoot(); - bytes32 executionPayloadRoot = getExecutionPayloadRoot(); - return - BeaconChainProofs.WithdrawalProof( - abi.encodePacked(withdrawalProof), - abi.encodePacked(getSlotProof()), - abi.encodePacked(getExecutionPayloadProof()), - abi.encodePacked(timestampProof), - abi.encodePacked(getHistoricalSummaryProof()), - uint64(getBlockRootIndex()), - uint64(getHistoricalSummaryIndex()), - uint64(getWithdrawalIndex()), - blockRoot, - slotRoot, - timestampRoot, - executionPayloadRoot - ); - } - } - - - function _setOracleBlockRoot() internal { - bytes32 latestBlockRoot = getLatestBlockRoot(); - //set beaconStateRoot - beaconChainOracle.setOracleBlockRootAtTimestamp(latestBlockRoot); - } - - function _computeTimestampAtSlot(uint64 slot) internal pure returns (uint64) { - return uint64(GOERLI_GENESIS_TIME + slot * SECONDS_PER_SLOT); - } - - function _deployInternalFunctionTester() internal { - podInternalFunctionTester = new EPInternalFunctions( - ethPOSDeposit, - delayedWithdrawalRouter, - IEigenPodManager(podManagerAddress), - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - GOERLI_GENESIS_TIME - ); - } -} - -contract Relayer is Test { - function verifyWithdrawal( - bytes32 beaconStateRoot, - bytes32[] calldata withdrawalFields, - BeaconChainProofs.WithdrawalProof calldata proofs - ) public view { - BeaconChainProofs.verifyWithdrawal(beaconStateRoot, withdrawalFields, proofs, type(uint64).max); - } -} - - -//TODO: Integration Tests from old EPM unit tests: - // queues a withdrawal of "beacon chain ETH shares" from this address to itself - // fuzzed input amountGwei is sized-down, since it must be in GWEI and gets sized-up to be WEI -// TODO: reimplement similar test - // function testQueueWithdrawalBeaconChainETHToSelf(uint128 amountGwei) - // public returns (IEigenPodManager.BeaconChainQueuedWithdrawal memory, bytes32 /*withdrawalRoot*/) - // { - // // scale fuzzed amount up to be a whole amount of GWEI - // uint256 amount = uint256(amountGwei) * 1e9; - // address staker = address(this); - // address withdrawer = staker; - - // testRestakeBeaconChainETHSuccessfully(staker, amount); - - // (IEigenPodManager.BeaconChainQueuedWithdrawal memory queuedWithdrawal, bytes32 withdrawalRoot) = - // _createQueuedWithdrawal(staker, amount, withdrawer); - - // return (queuedWithdrawal, withdrawalRoot); - // } -// TODO: reimplement similar test - // function testQueueWithdrawalBeaconChainETHToDifferentAddress(address withdrawer, uint128 amountGwei) - // public - // filterFuzzedAddressInputs(withdrawer) - // returns (IEigenPodManager.BeaconChainQueuedWithdrawal memory, bytes32 /*withdrawalRoot*/) - // { - // // scale fuzzed amount up to be a whole amount of GWEI - // uint256 amount = uint256(amountGwei) * 1e9; - // address staker = address(this); - - // testRestakeBeaconChainETHSuccessfully(staker, amount); - - // (IEigenPodManager.BeaconChainQueuedWithdrawal memory queuedWithdrawal, bytes32 withdrawalRoot) = - // _createQueuedWithdrawal(staker, amount, withdrawer); - - // return (queuedWithdrawal, withdrawalRoot); - // } -// TODO: reimplement similar test - - // function testQueueWithdrawalBeaconChainETHFailsNonWholeAmountGwei(uint256 nonWholeAmount) external { - // // this also filters out the zero case, which will revert separately - // cheats.assume(nonWholeAmount % GWEI_TO_WEI != 0); - // cheats.expectRevert(bytes("EigenPodManager._queueWithdrawal: cannot queue a withdrawal of Beacon Chain ETH for an non-whole amount of gwei")); - // eigenPodManager.queueWithdrawal(nonWholeAmount, address(this)); - // } - - // function testQueueWithdrawalBeaconChainETHFailsZeroAmount() external { - // cheats.expectRevert(bytes("EigenPodManager._queueWithdrawal: amount must be greater than zero")); - // eigenPodManager.queueWithdrawal(0, address(this)); - // } - -// TODO: reimplement similar test - // function testCompleteQueuedWithdrawal() external { - // address staker = address(this); - // uint256 withdrawalAmount = 1e18; - - // // withdrawalAmount is converted to GWEI here - // (IEigenPodManager.BeaconChainQueuedWithdrawal memory queuedWithdrawal, bytes32 withdrawalRoot) = - // testQueueWithdrawalBeaconChainETHToSelf(uint128(withdrawalAmount / 1e9)); - - // IEigenPod eigenPod = eigenPodManager.getPod(staker); - // uint256 eigenPodBalanceBefore = address(eigenPod).balance; - - // uint256 middlewareTimesIndex = 0; - - // // actually complete the withdrawal - // cheats.startPrank(staker); - // cheats.expectEmit(true, true, true, true, address(eigenPodManager)); - // emit BeaconChainETHWithdrawalCompleted( - // queuedWithdrawal.podOwner, - // queuedWithdrawal.shares, - // queuedWithdrawal.nonce, - // queuedWithdrawal.delegatedAddress, - // queuedWithdrawal.withdrawer, - // withdrawalRoot - // ); - // eigenPodManager.completeQueuedWithdrawal(queuedWithdrawal, middlewareTimesIndex); - // cheats.stopPrank(); - - // // TODO: make EigenPodMock do something so we can verify that it gets called appropriately? - // uint256 eigenPodBalanceAfter = address(eigenPod).balance; - - // // verify that the withdrawal root does bit exist after queuing - // require(!eigenPodManager.withdrawalRootPending(withdrawalRoot), "withdrawalRootPendingBefore is true!"); - // } - -// TODO: reimplement similar test - // // creates a queued withdrawal of "beacon chain ETH shares", from `staker`, of `amountWei`, "to" the `withdrawer` - // function _createQueuedWithdrawal(address staker, uint256 amountWei, address withdrawer) - // internal - // returns (IEigenPodManager.BeaconChainQueuedWithdrawal memory queuedWithdrawal, bytes32 withdrawalRoot) - // { - // // create the struct, for reference / to return - // queuedWithdrawal = IEigenPodManager.BeaconChainQueuedWithdrawal({ - // shares: amountWei, - // podOwner: staker, - // nonce: eigenPodManager.cumulativeWithdrawalsQueued(staker), - // startBlock: uint32(block.number), - // delegatedTo: delegationManagerMock.delegatedTo(staker), - // withdrawer: withdrawer - // }); - - // // verify that the withdrawal root does not exist before queuing - // require(!eigenPodManager.withdrawalRootPending(withdrawalRoot), "withdrawalRootPendingBefore is true!"); - - // // get staker nonce and shares before queuing - // uint256 nonceBefore = eigenPodManager.cumulativeWithdrawalsQueued(staker); - // int256 sharesBefore = eigenPodManager.podOwnerShares(staker); - - // // actually create the queued withdrawal, and check for event emission - // cheats.startPrank(staker); - - // cheats.expectEmit(true, true, true, true, address(eigenPodManager)); - // emit BeaconChainETHWithdrawalQueued( - // queuedWithdrawal.podOwner, - // queuedWithdrawal.shares, - // queuedWithdrawal.nonce, - // queuedWithdrawal.delegatedAddress, - // queuedWithdrawal.withdrawer, - // eigenPodManager.calculateWithdrawalRoot(queuedWithdrawal) - // ); - // withdrawalRoot = eigenPodManager.queueWithdrawal(amountWei, withdrawer); - // cheats.stopPrank(); - - // // verify that the withdrawal root does exist after queuing - // require(eigenPodManager.withdrawalRootPending(withdrawalRoot), "withdrawalRootPendingBefore is false!"); - - // // verify that staker nonce incremented correctly and shares decremented correctly - // uint256 nonceAfter = eigenPodManager.cumulativeWithdrawalsQueued(staker); - // int256 sharesAfter = eigenPodManager.podOwnerShares(staker); - // require(nonceAfter == nonceBefore + 1, "nonce did not increment correctly on queuing withdrawal"); - // require(sharesAfter + amountWei == sharesBefore, "shares did not decrement correctly on queuing withdrawal"); - - // return (queuedWithdrawal, withdrawalRoot); - // } - - //Integration Test - // function testFullWithdrawalProofWithWrongWithdrawalFields(bytes32[] memory wrongWithdrawalFields) public { - // Relayer relay = new Relayer(); - // uint256 WITHDRAWAL_FIELD_TREE_HEIGHT = 2; - - // setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - // BeaconChainProofs.WithdrawalProof memory proofs = _getWithdrawalProof(); - // bytes32 beaconStateRoot = getBeaconStateRoot(); - // cheats.assume(wrongWithdrawalFields.length != 2 ** WITHDRAWAL_FIELD_TREE_HEIGHT); - // validatorFields = getValidatorFields(); - - // cheats.expectRevert(bytes("BeaconChainProofs.verifyWithdrawal: withdrawalFields has incorrect length")); - // relay.verifyWithdrawal(beaconStateRoot, wrongWithdrawalFields, proofs); - // } - - // // Integration Test - // function testMismatchedWithdrawalProofInputs(uint64 numValidators, uint64 numValidatorProofs) external { - // cheats.assume(numValidators < numValidatorProofs && numValidatorProofs < 5); - // setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - // bytes[] memory validatorFieldsProofArray = new bytes[](numValidatorProofs); - // for (uint256 index = 0; index < numValidators; index++) { - // validatorFieldsProofArray[index] = abi.encodePacked(getValidatorProof()); - // } - // bytes32[][] memory validatorFieldsArray = new bytes32[][](numValidators); - // for (uint256 index = 0; index < validatorFieldsArray.length; index++) { - // validatorFieldsArray[index] = getValidatorFields(); - // } - // BeaconChainProofs.StateRootProof memory stateRootProofStruct = _getStateRootProof(); - // BeaconChainProofs.WithdrawalProof[] memory withdrawalProofsArray = new BeaconChainProofs.WithdrawalProof[](1); - - // withdrawalProofsArray[0] = _getWithdrawalProof(); - - // bytes32[][] memory withdrawalFieldsArray = new bytes32[][](1); - // withdrawalFieldsArray[0] = withdrawalFields; - - // cheats.expectRevert(bytes("EigenPod.verifyAndProcessWithdrawals: inputs must be same length")); - // pod.verifyAndProcessWithdrawals(0, stateRootProofStruct, withdrawalProofsArray, validatorFieldsProofArray, validatorFieldsArray, withdrawalFieldsArray); - // } diff --git a/src/test/events/IEigenPodEvents.sol b/src/test/events/IEigenPodEvents.sol index 20d37557f..f6302272b 100644 --- a/src/test/events/IEigenPodEvents.sol +++ b/src/test/events/IEigenPodEvents.sol @@ -2,9 +2,12 @@ pragma solidity ^0.8.12; interface IEigenPodEvents { - /// @notice Emitted when an ETH validator stakes via this eigenPod + // @notice Emitted when an ETH validator stakes via this eigenPod event EigenPodStaked(bytes pubkey); + /// @notice Emitted when a pod owner updates the proof submitter address + event ProofSubmitterUpdated(address prevProofSubmitter, address newProofSubmitter); + /// @notice Emitted when an ETH validator's withdrawal credentials are successfully verified to be pointed to this eigenPod event ValidatorRestaked(uint40 validatorIndex); @@ -12,22 +15,6 @@ interface IEigenPodEvents { // is the validator's balance that is credited on EigenLayer. event ValidatorBalanceUpdated(uint40 validatorIndex, uint64 balanceTimestamp, uint64 newValidatorBalanceGwei); - /// @notice Emitted when an ETH validator is prove to have withdrawn from the beacon chain - event FullWithdrawalRedeemed( - uint40 validatorIndex, - uint64 withdrawalTimestamp, - address indexed recipient, - uint64 withdrawalAmountGwei - ); - - /// @notice Emitted when a partial withdrawal claim is successfully redeemed - event PartialWithdrawalRedeemed( - uint40 validatorIndex, - uint64 withdrawalTimestamp, - address indexed recipient, - uint64 partialWithdrawalAmountGwei - ); - /// @notice Emitted when restaked beacon chain ETH is withdrawn from the eigenPod. event RestakedBeaconChainETHWithdrawn(address indexed recipient, uint256 amount); @@ -37,6 +24,15 @@ interface IEigenPodEvents { /// @notice Emitted when ETH is received via the `receive` fallback event NonBeaconChainETHReceived(uint256 amountReceived); - /// @notice Emitted when ETH that was previously received via the `receive` fallback is withdrawn - event NonBeaconChainETHWithdrawn(address indexed recipient, uint256 amountWithdrawn); + /// @notice Emitted when a checkpoint is created + event CheckpointCreated(uint64 indexed checkpointTimestamp, bytes32 indexed beaconBlockRoot, uint256 validatorCount); + + /// @notice Emitted when a checkpoint is finalized + event CheckpointFinalized(uint64 indexed checkpointTimestamp, int256 totalShareDeltaWei); + + /// @notice Emitted when a validator is proven for a given checkpoint + event ValidatorCheckpointed(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex); + + /// @notice Emitted when a validaor is proven to have 0 balance at a given checkpoint + event ValidatorWithdrawn(uint64 indexed checkpointTimestamp, uint40 indexed validatorIndex); } diff --git a/src/test/events/IEigenPodManagerEvents.sol b/src/test/events/IEigenPodManagerEvents.sol index 50caf34bf..79c11d663 100644 --- a/src/test/events/IEigenPodManagerEvents.sol +++ b/src/test/events/IEigenPodManagerEvents.sol @@ -2,9 +2,6 @@ pragma solidity ^0.8.12; interface IEigenPodManagerEvents { - /// @notice Emitted to notify the update of the beaconChainOracle address - event BeaconOracleUpdated(address indexed newOracleAddress); - /// @notice Emitted to notify that the denebForkTimestamp has been set event DenebForkTimestampUpdated(uint64 denebForkTimestamp); @@ -13,4 +10,7 @@ interface IEigenPodManagerEvents { /// @notice Emitted when the balance of an EigenPod is updated event PodSharesUpdated(address indexed podOwner, int256 sharesDelta); + + /// @notice Emitted every time the total shares of a pod are updated + event NewTotalShares(address indexed podOwner, int256 newTotalShares); } diff --git a/src/test/harnesses/EigenPodHarness.sol b/src/test/harnesses/EigenPodHarness.sol index 50582dfe7..f76e00e1f 100644 --- a/src/test/harnesses/EigenPodHarness.sol +++ b/src/test/harnesses/EigenPodHarness.sol @@ -4,19 +4,15 @@ pragma solidity ^0.8.12; import "../../contracts/pods/EigenPod.sol"; import "forge-std/Test.sol"; -contract EPInternalFunctions is EigenPod, Test { +contract EigenPodHarness is EigenPod { constructor( IETHPOSDeposit _ethPOS, - IDelayedWithdrawalRouter _delayedWithdrawalRouter, IEigenPodManager _eigenPodManager, - uint64 _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, uint64 _GENESIS_TIME ) EigenPod( _ethPOS, - _delayedWithdrawalRouter, _eigenPodManager, - _MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, _GENESIS_TIME ) {} @@ -29,14 +25,12 @@ contract EPInternalFunctions is EigenPod, Test { } function verifyWithdrawalCredentials( - uint64 oracleTimestamp, bytes32 beaconStateRoot, uint40 validatorIndex, bytes calldata validatorFieldsProof, bytes32[] calldata validatorFields ) public returns (uint256) { return _verifyWithdrawalCredentials( - oracleTimestamp, beaconStateRoot, validatorIndex, validatorFieldsProof, @@ -44,75 +38,6 @@ contract EPInternalFunctions is EigenPod, Test { ); } - function verifyAndProcessWithdrawal( - bytes32 beaconStateRoot, - BeaconChainProofs.WithdrawalProof calldata withdrawalProof, - bytes calldata validatorFieldsProof, - bytes32[] calldata validatorFields, - bytes32[] calldata withdrawalFields - ) public returns (IEigenPod.VerifiedWithdrawal memory) { - return _verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalProof, - validatorFieldsProof, - validatorFields, - withdrawalFields - ); - } - - function processFullWithdrawal( - uint40 validatorIndex, - bytes32 validatorPubkeyHash, - uint64 withdrawalHappenedTimestamp, - address recipient, - uint64 withdrawalAmountGwei, - ValidatorInfo memory validatorInfo - ) public returns(IEigenPod.VerifiedWithdrawal memory) { - return _processFullWithdrawal( - validatorIndex, - validatorPubkeyHash, - withdrawalHappenedTimestamp, - recipient, - withdrawalAmountGwei, - validatorInfo - ); - } - - function processPartialWithdrawal( - uint40 validatorIndex, - uint64 withdrawalHappenedTimestamp, - address recipient, - uint64 withdrawalAmountGwei - ) public returns(IEigenPod.VerifiedWithdrawal memory) { - return _processPartialWithdrawal( - validatorIndex, - withdrawalHappenedTimestamp, - recipient, - withdrawalAmountGwei - ); - } - - function verifyBalanceUpdate( - uint64 oracleTimestamp, - uint40 validatorIndex, - bytes32 beaconStateRoot, - bytes calldata validatorFieldsProofs, - bytes32[] calldata validatorFields, - uint64 mostRecentBalanceUpdateTimestamp - ) - public returns (int256) - { - bytes32 pkhash = validatorFields[0]; - _validatorPubkeyHashToInfo[pkhash].mostRecentBalanceUpdateTimestamp = mostRecentBalanceUpdateTimestamp; - return _verifyBalanceUpdate( - oracleTimestamp, - validatorIndex, - beaconStateRoot, - validatorFieldsProofs, - validatorFields - ); - } - function setValidatorStatus(bytes32 pkhash, VALIDATOR_STATUS status) public { _validatorPubkeyHashToInfo[pkhash].status = status; } @@ -120,8 +45,4 @@ contract EPInternalFunctions is EigenPod, Test { function setValidatorRestakedBalance(bytes32 pkhash, uint64 restakedBalanceGwei) public { _validatorPubkeyHashToInfo[pkhash].restakedBalanceGwei = restakedBalanceGwei; } - - function setMostRecentWithdrawalTimestamp(uint64 _mostRecentWithdrawalTimestamp) public { - mostRecentWithdrawalTimestamp = _mostRecentWithdrawalTimestamp; - } - } +} diff --git a/src/test/integration/IntegrationBase.t.sol b/src/test/integration/IntegrationBase.t.sol index af993a656..dc232a98c 100644 --- a/src/test/integration/IntegrationBase.t.sol +++ b/src/test/integration/IntegrationBase.t.sol @@ -44,13 +44,13 @@ abstract contract IntegrationBase is IntegrationDeployer { uint[] memory tokenBalances; if (forkType == MAINNET && !isUpgraded) { - stakerName = string.concat("- M1_Staker", numStakers.toString()); + stakerName = string.concat("M1_Staker", numStakers.toString()); (staker, strategies, tokenBalances) = _randUser(stakerName); stakersToMigrate.push(staker); } else { - stakerName = string.concat("- Staker", numStakers.toString()); + stakerName = string.concat("Staker", numStakers.toString()); (staker, strategies, tokenBalances) = _randUser(stakerName); } @@ -73,7 +73,7 @@ abstract contract IntegrationBase is IntegrationDeployer { uint[] memory tokenBalances; if (forkType == MAINNET && !isUpgraded) { - string memory operatorName = string.concat("- M1_Operator", numOperators.toString()); + string memory operatorName = string.concat("M1_Operator", numOperators.toString()); // Create an operator for M1. We omit native ETH because we want to // check staker/operator shares, and we don't award native ETH shares in M1 @@ -86,9 +86,9 @@ abstract contract IntegrationBase is IntegrationDeployer { operatorsToMigrate.push(operator); } else { - string memory operatorName = string.concat("- Operator", numOperators.toString()); + string memory operatorName = string.concat("Operator", numOperators.toString()); - (operator, strategies, tokenBalances) = _randUser(operatorName); + (operator, strategies, tokenBalances) = _randUser_NoETH(operatorName); uint[] memory addedShares = _calculateExpectedShares(strategies, tokenBalances); @@ -104,6 +104,24 @@ abstract contract IntegrationBase is IntegrationDeployer { return (operator, strategies, tokenBalances); } + /// @dev Send a random amount of ETH (up to 10 gwei) to the destination via `call`, + /// triggering its fallback function. Sends a gwei-divisible amount as well as a + /// non-gwei-divisible amount. + /// + /// Total sent == `gweiSent + remainderSent` + function _sendRandomETH(address destination) internal returns (uint64 gweiSent, uint remainderSent) { + gweiSent = uint64(_randUint({ min: 1 , max: 10 })); + remainderSent = _randUint({ min: 1, max: 100 }); + uint totalSent = (gweiSent * GWEI_TO_WEI) + remainderSent; + + cheats.deal(address(this), address(this).balance + totalSent); + bool r; + bytes memory d; + (r, d) = destination.call{ value: totalSent }(""); + + return (gweiSent, remainderSent); + } + /// @dev If we're on mainnet, upgrade contracts to M2 and migrate stakers/operators function _upgradeEigenLayerContracts() internal { if (forkType == MAINNET) { @@ -114,11 +132,6 @@ abstract contract IntegrationBase is IntegrationDeployer { emit log("===Migrating Stakers/Operators==="); - // Enable restaking for stakers' pods - for (uint i = 0; i < stakersToMigrate.length; i++) { - stakersToMigrate[i].activateRestaking(); - } - // Register operators with DelegationManager for (uint i = 0; i < operatorsToMigrate.length; i++) { operatorsToMigrate[i].registerAsOperator(); @@ -129,15 +142,7 @@ abstract contract IntegrationBase is IntegrationDeployer { // Bump block.timestamp forward to allow verifyWC proofs for migrated pods emit log("advancing block time to start of next epoch:"); - uint64 curEpoch = _timeStampToEpoch(uint64(block.timestamp)); - uint64 nextEpochStartTime = _nextEpochStartTimestamp(curEpoch); - - emit log_named_uint("- current time", block.timestamp); - emit log_named_uint("- current epoch", curEpoch); - emit log_named_uint("- next epoch starts at", nextEpochStartTime); - - cheats.warp(nextEpochStartTime); - beaconChain.setNextTimestamp(nextEpochStartTime); + beaconChain.advanceEpoch(); emit log("======"); @@ -154,21 +159,29 @@ abstract contract IntegrationBase is IntegrationDeployer { } } - /// From EigenPod.sol, using genesis time configured in ExistingDeploymentParser - function _timeStampToEpoch(uint64 timestamp) internal view returns (uint64) { - require(timestamp >= EIGENPOD_GENESIS_TIME, "EigenPod._timestampToEpoch: timestamp is before genesis"); - return (timestamp - EIGENPOD_GENESIS_TIME) / BeaconChainProofs.SECONDS_PER_EPOCH; - } + /// @dev Choose a random subset of validators (selects AT LEAST ONE) + function _choose(uint40[] memory validators) internal returns (uint40[] memory) { + uint rand = _randUint({ min: 1, max: validators.length ** 2 }); + + uint40[] memory result = new uint40[](validators.length); + uint newLen; + for (uint i = 0; i < validators.length; i++) { + // if bit set, add validator + if (rand >> i & 1 == 1) { + result[newLen] = validators[i]; + newLen++; + } + } + + // Manually update length of result + assembly { mstore(result, newLen) } - /// From EigenPod.sol, using genesis time configured in ExistingDeploymentParser - function _nextEpochStartTimestamp(uint64 epoch) internal view returns (uint64) { - return - EIGENPOD_GENESIS_TIME + ((1 + epoch) * BeaconChainProofs.SECONDS_PER_EPOCH); + return result; } - /** - * Common assertions: - */ + /******************************************************************************* + COMMON ASSERTIONS + *******************************************************************************/ function assert_HasNoDelegatableShares(User user, string memory err) internal { (IStrategy[] memory strategies, uint[] memory shares) = @@ -287,13 +300,41 @@ abstract contract IntegrationBase is IntegrationDeployer { ) internal { assertEq(withdrawalRoot, delegationManager.calculateWithdrawalRoot(withdrawal), err); } + + function assert_PodBalance_Eq( + User staker, + uint expectedBalance, + string memory err + ) internal { + EigenPod pod = staker.pod(); + assertEq(address(pod).balance, expectedBalance, err); + } + + function assert_ProofsRemainingEqualsActive( + User staker, + string memory err + ) internal { + EigenPod pod = staker.pod(); + assertEq(pod.currentCheckpoint().proofsRemaining, pod.activeValidatorCount(), err); + } + + function assert_CheckpointPodBalance( + User staker, + uint64 expectedPodBalanceGwei, + string memory err + ) internal { + EigenPod pod = staker.pod(); + assertEq(pod.currentCheckpoint().podBalanceGwei, expectedPodBalanceGwei, err); + } /******************************************************************************* SNAPSHOT ASSERTIONS TIME TRAVELERS ONLY BEYOND THIS POINT *******************************************************************************/ - /// Snapshot assertions for delegationManager.operatorShares: + /******************************************************************************* + SNAPSHOT ASSERTIONS: OPERATOR SHARES + *******************************************************************************/ /// @dev Check that the operator has `addedShares` additional operator shares // for each strategy since the last snapshot @@ -371,7 +412,9 @@ abstract contract IntegrationBase is IntegrationDeployer { } } - /// Snapshot assertions for strategyMgr.stakerStrategyShares and eigenPodMgr.podOwnerShares: + /******************************************************************************* + SNAPSHOT ASSERTIONS: STAKER SHARES + *******************************************************************************/ /// @dev Check that the staker has `addedShares` additional delegatable shares /// for each strategy since the last snapshot @@ -391,6 +434,20 @@ abstract contract IntegrationBase is IntegrationDeployer { } } + function assert_Snap_Added_StakerShares( + User staker, + IStrategy strat, + uint _addedShares, + string memory err + ) internal { + IStrategy[] memory strategies = new IStrategy[](1); + uint[] memory addedShares = new uint[](1); + strategies[0] = strat; + addedShares[0] = _addedShares; + + assert_Snap_Added_StakerShares(staker, strategies, addedShares, err); + } + /// @dev Check that the staker has `removedShares` fewer delegatable shares /// for each strategy since the last snapshot function assert_Snap_Removed_StakerShares( @@ -409,6 +466,20 @@ abstract contract IntegrationBase is IntegrationDeployer { } } + function assert_Snap_Removed_StakerShares( + User staker, + IStrategy strat, + uint _removedShares, + string memory err + ) internal { + IStrategy[] memory strategies = new IStrategy[](1); + uint[] memory removedShares = new uint[](1); + strategies[0] = strat; + removedShares[0] = _removedShares; + + assert_Snap_Removed_StakerShares(staker, strategies, removedShares, err); + } + /// @dev Check that the staker's delegatable shares in ALL strategies have not changed /// since the last snapshot function assert_Snap_Unchanged_StakerShares( @@ -427,6 +498,26 @@ abstract contract IntegrationBase is IntegrationDeployer { } } + function assert_Snap_Delta_StakerShares( + User staker, + IStrategy[] memory strategies, + int[] memory shareDeltas, + string memory err + ) internal { + int[] memory curShares = _getStakerSharesInt(staker, strategies); + // Use timewarp to get previous staker shares + int[] memory prevShares = _getPrevStakerSharesInt(staker, strategies); + + // For each strategy, check (prev + added == cur) + for (uint i = 0; i < strategies.length; i++) { + assertEq(prevShares[i] + shareDeltas[i], curShares[i], err); + } + } + + /******************************************************************************* + SNAPSHOT ASSERTIONS: STRATEGY SHARES + *******************************************************************************/ + function assert_Snap_Removed_StrategyShares( IStrategy[] memory strategies, uint[] memory removedShares, @@ -466,23 +557,9 @@ abstract contract IntegrationBase is IntegrationDeployer { } } - function assert_Snap_Delta_StakerShares( - User staker, - IStrategy[] memory strategies, - int[] memory shareDeltas, - string memory err - ) internal { - int[] memory curShares = _getStakerSharesInt(staker, strategies); - // Use timewarp to get previous staker shares - int[] memory prevShares = _getPrevStakerSharesInt(staker, strategies); - - // For each strategy, check (prev + added == cur) - for (uint i = 0; i < strategies.length; i++) { - assertEq(prevShares[i] + shareDeltas[i], curShares[i], err); - } - } - - /// Snapshot assertions for underlying token balances: + /******************************************************************************* + SNAPSHOT ASSERTIONS: UNDERLYING TOKEN + *******************************************************************************/ /// @dev Check that the staker has `addedTokens` additional underlying tokens // since the last snapshot @@ -543,7 +620,9 @@ abstract contract IntegrationBase is IntegrationDeployer { } } - /// Other snapshot assertions: + /******************************************************************************* + SNAPSHOT ASSERTIONS: QUEUED WITHDRAWALS + *******************************************************************************/ function assert_Snap_Added_QueuedWithdrawals( User staker, @@ -569,6 +648,161 @@ abstract contract IntegrationBase is IntegrationDeployer { assertEq(prevQueuedWithdrawal + 1, curQueuedWithdrawal, err); } + /******************************************************************************* + SNAPSHOT ASSERTIONS: EIGENPODS + *******************************************************************************/ + + function assert_Snap_Added_ActiveValidatorCount( + User staker, + uint addedValidators, + string memory err + ) internal { + uint curActiveValidatorCount = _getActiveValidatorCount(staker); + uint prevActiveValidatorCount = _getPrevActiveValidatorCount(staker); + + assertEq(prevActiveValidatorCount + addedValidators, curActiveValidatorCount, err); + } + + function assert_Snap_Removed_ActiveValidatorCount( + User staker, + uint exitedValidators, + string memory err + ) internal { + uint curActiveValidatorCount = _getActiveValidatorCount(staker); + uint prevActiveValidatorCount = _getPrevActiveValidatorCount(staker); + + assertEq(curActiveValidatorCount + exitedValidators, prevActiveValidatorCount, err); + } + + function assert_Snap_Unchanged_ActiveValidatorCount( + User staker, + string memory err + ) internal { + uint curActiveValidatorCount = _getActiveValidatorCount(staker); + uint prevActiveValidatorCount = _getPrevActiveValidatorCount(staker); + + assertEq(curActiveValidatorCount, prevActiveValidatorCount, err); + } + + function assert_Snap_Added_ActiveValidators( + User staker, + uint40[] memory addedValidators, + string memory err + ) internal { + bytes32[] memory pubkeyHashes = beaconChain.getPubkeyHashes(addedValidators); + + IEigenPod.VALIDATOR_STATUS[] memory curStatuses = _getValidatorStatuses(staker, pubkeyHashes); + IEigenPod.VALIDATOR_STATUS[] memory prevStatuses = _getPrevValidatorStatuses(staker, pubkeyHashes); + + for (uint i = 0; i < curStatuses.length; i++) { + assertTrue(prevStatuses[i] == IEigenPod.VALIDATOR_STATUS.INACTIVE, err); + assertTrue(curStatuses[i] == IEigenPod.VALIDATOR_STATUS.ACTIVE, err); + } + } + + function assert_Snap_Removed_ActiveValidators( + User staker, + uint40[] memory exitedValidators, + string memory err + ) internal { + bytes32[] memory pubkeyHashes = beaconChain.getPubkeyHashes(exitedValidators); + + IEigenPod.VALIDATOR_STATUS[] memory curStatuses = _getValidatorStatuses(staker, pubkeyHashes); + IEigenPod.VALIDATOR_STATUS[] memory prevStatuses = _getPrevValidatorStatuses(staker, pubkeyHashes); + + for (uint i = 0; i < curStatuses.length; i++) { + assertTrue(prevStatuses[i] == IEigenPod.VALIDATOR_STATUS.ACTIVE, err); + assertTrue(curStatuses[i] == IEigenPod.VALIDATOR_STATUS.WITHDRAWN, err); + } + } + + function assert_Snap_Created_Checkpoint( + User staker, + string memory err + ) internal { + uint64 curCheckpointTimestamp = _getCheckpointTimestamp(staker); + uint64 prevCheckpointTimestamp = _getPrevCheckpointTimestamp(staker); + + assertEq(prevCheckpointTimestamp, 0, err); + assertTrue(curCheckpointTimestamp != 0, err); + } + + function assert_Snap_Removed_Checkpoint( + User staker, + string memory err + ) internal { + uint64 curCheckpointTimestamp = _getCheckpointTimestamp(staker); + uint64 prevCheckpointTimestamp = _getPrevCheckpointTimestamp(staker); + + assertEq(curCheckpointTimestamp, 0, err); + assertTrue(prevCheckpointTimestamp != 0, err); + } + + function assert_Snap_Unchanged_Checkpoint( + User staker, + string memory err + ) internal { + uint64 curCheckpointTimestamp = _getCheckpointTimestamp(staker); + uint64 prevCheckpointTimestamp = _getPrevCheckpointTimestamp(staker); + + assertEq(curCheckpointTimestamp, prevCheckpointTimestamp, err); + } + + function assert_Snap_Updated_LastCheckpoint( + User staker, + string memory err + ) internal { + // Sorry for the confusing naming... the pod variable is called `lastCheckpointTimestamp` + uint64 curLastCheckpointTimestamp = _getLastCheckpointTimestamp(staker); + uint64 prevLastCheckpointTimestamp = _getPrevLastCheckpointTimestamp(staker); + + assertTrue(curLastCheckpointTimestamp > prevLastCheckpointTimestamp, err); + } + + function assert_Snap_Added_PodBalanceToWithdrawable( + User staker, + string memory err + ) internal { + uint64 curWithdrawableRestakedGwei = _getWithdrawableRestakedGwei(staker); + uint64 prevWithdrawableRestakedGwei = _getPrevWithdrawableRestakedGwei(staker); + + uint64 prevCheckpointPodBalanceGwei = _getPrevCheckpointPodBalanceGwei(staker); + + assertEq(prevWithdrawableRestakedGwei + prevCheckpointPodBalanceGwei, curWithdrawableRestakedGwei, err); + } + + function assert_Snap_Added_WithdrawableGwei( + User staker, + uint64 addedGwei, + string memory err + ) internal { + uint64 curWithdrawableRestakedGwei = _getWithdrawableRestakedGwei(staker); + uint64 prevWithdrawableRestakedGwei = _getPrevWithdrawableRestakedGwei(staker); + + assertEq(prevWithdrawableRestakedGwei + addedGwei, curWithdrawableRestakedGwei, err); + } + + function assert_Snap_Added_BalanceExitedGwei( + User staker, + uint64 addedGwei, + string memory err + ) internal { + uint64 curCheckpointTimestamp = _getCheckpointTimestamp(staker); + uint64 prevCheckpointTimestamp = _getPrevCheckpointTimestamp(staker); + + // If we just finalized a checkpoint, that's the timestamp we want to use + // to look up checkpoint balances exited + uint64 targetTimestamp = curCheckpointTimestamp; + if (curCheckpointTimestamp != prevCheckpointTimestamp) { + targetTimestamp = prevCheckpointTimestamp; + } + + uint64 curExitedBalanceGwei = _getCheckpointBalanceExited(staker, targetTimestamp); + uint64 prevExitedBalanceGwei = _getPrevCheckpointBalanceExited(staker, targetTimestamp); + + assertEq(prevExitedBalanceGwei + addedGwei, curExitedBalanceGwei, err); + } + /******************************************************************************* UTILITY METHODS *******************************************************************************/ @@ -621,24 +855,31 @@ abstract contract IntegrationBase is IntegrationDeployer { IStrategy strat = strategies[i]; if (strat == BEACONCHAIN_ETH_STRAT) { - // TODO - could choose and set a "next updatable validator" at random here - uint40 validator = staker.getUpdatableValidator(); - uint64 beaconBalanceGwei = beaconChain.balanceOfGwei(validator); - - // For native eth, add or remove a random amount of Gwei - minimum 1 - // and max of the current beacon chain balance - int64 deltaGwei = int64(int(_randUint({ min: 1, max: beaconBalanceGwei }))); - bool addTokens = _randBool(); - deltaGwei = addTokens ? deltaGwei : -deltaGwei; - + // For native ETH, we're either going to slash the staker's validators, + // or award them consensus rewards. In either case, the magnitude of + // the balance update depends on the staker's active validator count + uint activeValidatorCount = staker.pod().activeValidatorCount(); + int64 deltaGwei; + if (_randBool()) { + uint40[] memory validators = staker.getActiveValidators(); + emit log_named_uint("slashing validators", validators.length); + + deltaGwei = -int64(beaconChain.slashValidators(validators)); + beaconChain.advanceEpoch_NoRewards(); + + emit log_named_int("slashed amount", deltaGwei); + } else { + emit log("generating consensus rewards for validators"); + + deltaGwei = int64(uint64(activeValidatorCount) * beaconChain.CONSENSUS_REWARD_AMOUNT_GWEI()); + beaconChain.advanceEpoch_NoWithdraw(); + } + tokenDeltas[i] = int(deltaGwei) * int(GWEI_TO_WEI); - // stakerShareDeltas[i] = _calculateSharesDelta(newPodBalanceGwei, oldPodBalanceGwei); - stakerShareDeltas[i] = _calcNativeETHStakerShareDelta(staker, validator, beaconBalanceGwei, deltaGwei); + stakerShareDeltas[i] = tokenDeltas[i]; operatorShareDeltas[i] = _calcNativeETHOperatorShareDelta(staker, stakerShareDeltas[i]); - emit log_named_uint("current beacon balance (gwei): ", beaconBalanceGwei); - // emit log_named_uint("current validator pod balance (gwei): ", oldPodBalanceGwei); emit log_named_int("beacon balance delta (gwei): ", deltaGwei); emit log_named_int("staker share delta (gwei): ", stakerShareDeltas[i] / int(GWEI_TO_WEI)); emit log_named_int("operator share delta (gwei): ", operatorShareDeltas[i] / int(GWEI_TO_WEI)); @@ -656,38 +897,6 @@ abstract contract IntegrationBase is IntegrationDeployer { return (tokenDeltas, stakerShareDeltas, operatorShareDeltas); } - function _calcNativeETHStakerShareDelta( - User staker, - uint40 validatorIndex, - uint64 beaconBalanceGwei, - int64 deltaGwei - ) internal view returns (int) { - uint64 oldPodBalanceGwei = - staker - .pod() - .validatorPubkeyHashToInfo(beaconChain.pubkeyHash(validatorIndex)) - .restakedBalanceGwei; - - uint64 newPodBalanceGwei = _calcPodBalance(beaconBalanceGwei, deltaGwei); - - return (int(uint(newPodBalanceGwei)) - int(uint(oldPodBalanceGwei))) * int(GWEI_TO_WEI); - } - - function _calcPodBalance(uint64 beaconBalanceGwei, int64 deltaGwei) internal pure returns (uint64) { - uint64 podBalanceGwei; - if (deltaGwei < 0) { - podBalanceGwei = beaconBalanceGwei - uint64(uint(int(-deltaGwei))); - } else { - podBalanceGwei = beaconBalanceGwei + uint64(uint(int(deltaGwei))); - } - - if (podBalanceGwei > MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) { - podBalanceGwei = MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; - } - - return podBalanceGwei; - } - function _calcNativeETHOperatorShareDelta(User staker, int shareDelta) internal view returns (int) { int curPodOwnerShares = eigenPodManager.podOwnerShares(address(staker)); int newPodOwnerShares = curPodOwnerShares + shareDelta; @@ -916,4 +1125,73 @@ abstract contract IntegrationBase is IntegrationDeployer { return shares; } + + function _getActiveValidatorCount(User staker) internal view returns (uint) { + EigenPod pod = staker.pod(); + return pod.activeValidatorCount(); + } + + function _getPrevActiveValidatorCount(User staker) internal timewarp() returns (uint) { + return _getActiveValidatorCount(staker); + } + + function _getValidatorStatuses(User staker, bytes32[] memory pubkeyHashes) internal view returns (IEigenPod.VALIDATOR_STATUS[] memory) { + EigenPod pod = staker.pod(); + IEigenPod.VALIDATOR_STATUS[] memory statuses = new IEigenPod.VALIDATOR_STATUS[](pubkeyHashes.length); + + for (uint i = 0; i < statuses.length; i++) { + statuses[i] = pod.validatorStatus(pubkeyHashes[i]); + } + + return statuses; + } + + function _getPrevValidatorStatuses(User staker, bytes32[] memory pubkeyHashes) internal timewarp() returns (IEigenPod.VALIDATOR_STATUS[] memory) { + return _getValidatorStatuses(staker, pubkeyHashes); + } + + function _getCheckpointTimestamp(User staker) internal view returns (uint64) { + EigenPod pod = staker.pod(); + return pod.currentCheckpointTimestamp(); + } + + function _getPrevCheckpointTimestamp(User staker) internal timewarp() returns (uint64) { + return _getCheckpointTimestamp(staker); + } + + function _getLastCheckpointTimestamp(User staker) internal view returns (uint64) { + EigenPod pod = staker.pod(); + return pod.lastCheckpointTimestamp(); + } + + function _getPrevLastCheckpointTimestamp(User staker) internal timewarp() returns (uint64) { + return _getLastCheckpointTimestamp(staker); + } + + function _getWithdrawableRestakedGwei(User staker) internal view returns (uint64) { + EigenPod pod = staker.pod(); + return pod.withdrawableRestakedExecutionLayerGwei(); + } + + function _getPrevWithdrawableRestakedGwei(User staker) internal timewarp() returns (uint64) { + return _getWithdrawableRestakedGwei(staker); + } + + function _getCheckpointPodBalanceGwei(User staker) internal view returns (uint64) { + EigenPod pod = staker.pod(); + return uint64(pod.currentCheckpoint().podBalanceGwei); + } + + function _getPrevCheckpointPodBalanceGwei(User staker) internal timewarp() returns (uint64) { + return _getCheckpointPodBalanceGwei(staker); + } + + function _getCheckpointBalanceExited(User staker, uint64 checkpointTimestamp) internal view returns (uint64) { + EigenPod pod = staker.pod(); + return pod.checkpointBalanceExitedGwei(checkpointTimestamp); + } + + function _getPrevCheckpointBalanceExited(User staker, uint64 checkpointTimestamp) internal timewarp() returns (uint64) { + return _getCheckpointBalanceExited(staker, checkpointTimestamp); + } } \ No newline at end of file diff --git a/src/test/integration/IntegrationChecks.t.sol b/src/test/integration/IntegrationChecks.t.sol index 9ca5e3fd6..2fc360581 100644 --- a/src/test/integration/IntegrationChecks.t.sol +++ b/src/test/integration/IntegrationChecks.t.sol @@ -7,7 +7,116 @@ import "src/test/integration/users/User_M1.t.sol"; /// @notice Contract that provides utility functions to reuse common test blocks & checks contract IntegrationCheckUtils is IntegrationBase { - + + /******************************************************************************* + EIGENPOD CHECKS + *******************************************************************************/ + + function check_VerifyWC_State( + User staker, + uint40[] memory validators, + uint64 beaconBalanceGwei + ) internal { + uint beaconBalanceWei = beaconBalanceGwei * GWEI_TO_WEI; + assert_Snap_Added_StakerShares(staker, BEACONCHAIN_ETH_STRAT, beaconBalanceWei, "staker should have added shares to beacon chain strat"); + assert_Snap_Added_ActiveValidatorCount(staker, validators.length, "staker should have increased active validator count"); + assert_Snap_Added_ActiveValidators(staker, validators, "validators should each be active"); + } + + function check_StartCheckpoint_State( + User staker + ) internal { + assert_ProofsRemainingEqualsActive(staker, "checkpoint proofs remaining should equal active validator count"); + assert_Snap_Created_Checkpoint(staker, "staker should have created a new checkpoint"); + } + + function check_StartCheckpoint_WithPodBalance_State( + User staker, + uint64 expectedPodBalanceGwei + ) internal { + check_StartCheckpoint_State(staker); + + assert_CheckpointPodBalance(staker, expectedPodBalanceGwei, "checkpoint podBalanceGwei should equal expected"); + } + + function check_StartCheckpoint_NoValidators_State( + User staker, + uint64 sharesAddedGwei + ) internal { + assert_Snap_Added_StakerShares(staker, BEACONCHAIN_ETH_STRAT, sharesAddedGwei * GWEI_TO_WEI, "should have added staker shares"); + assert_Snap_Added_WithdrawableGwei(staker, sharesAddedGwei, "should have added to withdrawable restaked gwei"); + + assert_Snap_Unchanged_ActiveValidatorCount(staker, "active validator count should remain 0"); + assert_Snap_Updated_LastCheckpoint(staker, "last checkpoint timestamp should have increased"); + assert_Snap_Unchanged_Checkpoint(staker, "current checkpoint timestamp should be unchanged"); + } + + function check_CompleteCheckpoint_State( + User staker + ) internal { + assert_Snap_Removed_Checkpoint(staker, "should have deleted active checkpoint"); + assert_Snap_Updated_LastCheckpoint(staker, "last checkpoint timestamp should be updated"); + assert_Snap_Added_PodBalanceToWithdrawable(staker, "pod balance should have been added to withdrawable restaked exec layer gwei"); + } + + function check_CompleteCheckpoint_EarnOnBeacon_State( + User staker, + uint64 beaconBalanceAdded + ) internal { + check_CompleteCheckpoint_State(staker); + + uint balanceAddedWei = beaconBalanceAdded * GWEI_TO_WEI; + assert_Snap_Added_StakerShares(staker, BEACONCHAIN_ETH_STRAT, balanceAddedWei, "should have increased shares by excess beacon balance"); + } + + function check_CompleteCheckpoint_WithPodBalance_State( + User staker, + uint64 expectedPodBalanceGwei + ) internal { + check_CompleteCheckpoint_State(staker); + + assert_Snap_Added_WithdrawableGwei(staker, expectedPodBalanceGwei, "should have added expected gwei to withdrawable restaked exec layer gwei"); + } + + function check_CompleteCheckpoint_WithSlashing_State( + User staker, + uint40[] memory slashedValidators, + uint64 slashedAmountGwei + ) internal { + check_CompleteCheckpoint_State(staker); + + assert_Snap_Removed_StakerShares(staker, BEACONCHAIN_ETH_STRAT, slashedAmountGwei * GWEI_TO_WEI, "should have reduced shares by slashed amount"); + assert_Snap_Removed_ActiveValidatorCount(staker, slashedValidators.length, "should have decreased active validator count"); + assert_Snap_Removed_ActiveValidators(staker, slashedValidators, "exited validators should each be WITHDRAWN"); + } + + function check_CompleteCheckpoint_WithCLSlashing_State( + User staker, + uint64 slashedAmountGwei + ) internal { + check_CompleteCheckpoint_State(staker); + + assert_Snap_Removed_StakerShares(staker, BEACONCHAIN_ETH_STRAT, slashedAmountGwei * GWEI_TO_WEI, "should have reduced shares by slashed amount"); + assert_Snap_Unchanged_ActiveValidatorCount(staker, "should not have changed active validator count"); + } + + function check_CompleteCheckpoint_WithExits_State( + User staker, + uint40[] memory exitedValidators, + uint64 exitedBalanceGwei + ) internal { + check_CompleteCheckpoint_WithPodBalance_State(staker, exitedBalanceGwei); + + assert_Snap_Unchanged_StakerShares(staker, "staker should not have changed shares"); + assert_Snap_Added_BalanceExitedGwei(staker, exitedBalanceGwei, "should have attributed expected gwei to exited balance"); + assert_Snap_Removed_ActiveValidatorCount(staker, exitedValidators.length, "should have decreased active validator count"); + assert_Snap_Removed_ActiveValidators(staker, exitedValidators, "exited validators should each be WITHDRAWN"); + } + + /******************************************************************************* + LST/DELEGATION CHECKS + *******************************************************************************/ + function check_Deposit_State( User staker, IStrategy[] memory strategies, diff --git a/src/test/integration/IntegrationDeployer.t.sol b/src/test/integration/IntegrationDeployer.t.sol index 227447256..d60a52d05 100644 --- a/src/test/integration/IntegrationDeployer.t.sol +++ b/src/test/integration/IntegrationDeployer.t.sol @@ -17,12 +17,10 @@ import "src/contracts/strategies/StrategyBase.sol"; import "src/contracts/strategies/StrategyBaseTVLLimits.sol"; import "src/contracts/pods/EigenPodManager.sol"; import "src/contracts/pods/EigenPod.sol"; -import "src/contracts/pods/DelayedWithdrawalRouter.sol"; import "src/contracts/permissions/PauserRegistry.sol"; import "src/test/mocks/EmptyContract.sol"; import "src/test/mocks/ETHDepositMock.sol"; -import "src/test/integration/mocks/BeaconChainOracleMock.t.sol"; import "src/test/integration/mocks/BeaconChainMock.t.sol"; import "src/test/integration/users/User.t.sol"; @@ -42,6 +40,10 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { uint256 holeskyForkId; uint64 constant DENEB_FORK_TIMESTAMP = 1705473120; + // Beacon chain genesis time when running locally + // Multiple of 12 for sanity's sake + uint64 constant GENESIS_TIME_LOCAL = 1 hours * 12; + uint64 constant GENESIS_TIME_MAINNET = 1606824023; TimeMachine public timeMachine; @@ -59,7 +61,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { // Mock Contracts to deploy ETHPOSDepositMock ethPOSDeposit; - BeaconChainOracleMock public beaconChainOracle; BeaconChainMock public beaconChain; // Admin Addresses @@ -100,8 +101,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { uint8 internal constant PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE = 3; uint8 internal constant PAUSED_EIGENPODS_VERIFY_WITHDRAWAL = 4; uint8 internal constant PAUSED_NON_PROOF_WITHDRAWALS = 5; - // DelayedWithdrawalRouter - uint8 internal constant PAUSED_DELAYED_WITHDRAWAL_CLAIMS = 0; // Flags uint constant FLAG = 1; @@ -223,7 +222,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { // Deploy mocks EmptyContract emptyContract = new EmptyContract(); ethPOSDeposit = new ETHPOSDepositMock(); - beaconChainOracle = new BeaconChainOracleMock(); /** * First, deploy upgradeable proxy contracts that **will point** to the implementations. Since the implementation contracts are @@ -241,9 +239,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { eigenPodManager = EigenPodManager( address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) ); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); avsDirectory = AVSDirectory( address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) ); @@ -254,10 +249,8 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { // Deploy EigenPod Contracts eigenPodImplementation = new EigenPod( ethPOSDeposit, - delayedWithdrawalRouter, eigenPodManager, - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - 0 + GENESIS_TIME_LOCAL ); eigenPodBeacon = new UpgradeableBeacon(address(eigenPodImplementation)); @@ -273,7 +266,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { slasher, delegationManager ); - delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); avsDirectoryImplementation = new AVSDirectory(delegationManager); strategyFactoryImplementation = new StrategyFactory(strategyManager); @@ -324,24 +316,11 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { address(eigenPodManagerImplementation), abi.encodeWithSelector( EigenPodManager.initialize.selector, - address(beaconChainOracle), eigenLayerReputedMultisig, // initialOwner eigenLayerPauserReg, 0 // initialPausedStatus ) ); - // Delayed Withdrawal Router - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation), - abi.encodeWithSelector( - DelayedWithdrawalRouter.initialize.selector, - eigenLayerReputedMultisig, // initialOwner - eigenLayerPauserReg, - 0, // initialPausedStatus - withdrawalDelayBlocks - ) - ); // AVSDirectory eigenLayerProxyAdmin.upgradeAndCall( TransparentUpgradeableProxy(payable(address(avsDirectory))), @@ -389,14 +368,10 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { allStrats.push(BEACONCHAIN_ETH_STRAT); allTokens.push(NATIVE_ETH); - // Create time machine and set block timestamp forward so we can create EigenPod proofs in the past + // Create time machine and beacon chain. Set block time to beacon chain genesis time + cheats.warp(GENESIS_TIME_LOCAL); timeMachine = new TimeMachine(); - timeMachine.setProofGenStartTime(2 hours); - // Create mock beacon chain / proof gen interface - beaconChain = new BeaconChainMock(timeMachine, beaconChainOracle, eigenPodManager); - - //set deneb fork timestamp - eigenPodManager.setDenebForkTimestamp(type(uint64).max); + beaconChain = new BeaconChainMock(eigenPodManager, GENESIS_TIME_LOCAL); } /** @@ -414,10 +389,8 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { // Deploy EigenPod Contracts eigenPodImplementation = new EigenPod( ethPOSDeposit, - delayedWithdrawalRouter, eigenPodManager, - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - 0 + GENESIS_TIME_MAINNET ); eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); // Deploy AVSDirectory, contract has not been deployed on mainnet yet @@ -436,7 +409,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { slasher, delegationManager ); - delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); avsDirectoryImplementation = new AVSDirectory(delegationManager); // Second, upgrade the proxy contracts to point to the implementations @@ -460,11 +432,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { TransparentUpgradeableProxy(payable(address(eigenPodManager))), address(eigenPodManagerImplementation) ); - // Delayed Withdrawal Router - eigenLayerProxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation) - ); // AVSDirectory, upgrade and initalized eigenLayerProxyAdmin.upgradeAndCall( TransparentUpgradeableProxy(payable(address(avsDirectory))), @@ -494,14 +461,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { eigenPodManager.unpause(0); strategyManager.unpause(0); - eigenPodManager.updateBeaconChainOracle(beaconChainOracle); - timeMachine.setProofGenStartTime(0); - beaconChain.setNextTimestamp(timeMachine.proofGenStartTime()); - - if (eigenPodManager.denebForkTimestamp() == type(uint64).max) { - //set deneb fork timestamp if not set - eigenPodManager.setDenebForkTimestamp(DENEB_FORK_TIMESTAMP); - } cheats.stopPrank(); ethStrats.push(BEACONCHAIN_ETH_STRAT); @@ -524,9 +483,7 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { // Deploy EigenPod Contracts eigenPodImplementation = new EigenPod( ethPOSDeposit, - delayedWithdrawalRouter, eigenPodManager, - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, 0 ); eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); @@ -546,7 +503,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { slasher, delegationManager ); - delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); avsDirectoryImplementation = new AVSDirectory(delegationManager); // Second, upgrade the proxy contracts to point to the implementations @@ -570,11 +526,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { TransparentUpgradeableProxy(payable(address(eigenPodManager))), address(eigenPodManagerImplementation) ); - // Delayed Withdrawal Router - eigenLayerProxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation) - ); // AVSDirectory, upgrade and initalized eigenLayerProxyAdmin.upgradeAndCall( TransparentUpgradeableProxy(payable(address(avsDirectory))), @@ -604,14 +555,6 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { eigenPodManager.unpause(0); strategyManager.unpause(0); - eigenPodManager.updateBeaconChainOracle(beaconChainOracle); - timeMachine.setProofGenStartTime(0); - beaconChain.setNextTimestamp(timeMachine.proofGenStartTime()); - - if (eigenPodManager.denebForkTimestamp() == type(uint64).max) { - //set deneb fork timestamp if not set - eigenPodManager.setDenebForkTimestamp(DENEB_FORK_TIMESTAMP); - } cheats.stopPrank(); ethStrats.push(BEACONCHAIN_ETH_STRAT); @@ -729,50 +672,43 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { allTokens.push(strategy.underlyingToken()); } - // Create time machine and set block timestamp forward so we can create EigenPod proofs in the past + // Create time machine and mock beacon chain timeMachine = new TimeMachine(); - beaconChainOracle = new BeaconChainOracleMock(); - // Create mock beacon chain / proof gen interface - beaconChain = new BeaconChainMock(timeMachine, beaconChainOracle, eigenPodManager); + beaconChain = new BeaconChainMock(eigenPodManager, GENESIS_TIME_MAINNET); } else if (forkType == HOLESKY) { revert("_deployOrFetchContracts - holesky tests currently broken sorry"); - // cheats.selectFork(holeskyForkId); - string memory deploymentInfoPath = "script/configs/holesky/Holesky_current_deployment.config.json"; - _parseDeployedContracts(deploymentInfoPath); - - // Add deployed strategies to lstStrats and allStrats - for (uint i; i < deployedStrategyArray.length; i++) { - IStrategy strategy = IStrategy(deployedStrategyArray[i]); - - if (tokensNotTested[address(strategy.underlyingToken())]) { - continue; - } - - // Add to lstStrats and allStrats - lstStrats.push(strategy); - allStrats.push(strategy); - allTokens.push(strategy.underlyingToken()); - } - - // Update deposit contract to be a mock - ethPOSDeposit = new ETHPOSDepositMock(); - eigenPodImplementation = new EigenPod( - ethPOSDeposit, - eigenPodImplementation.delayedWithdrawalRouter(), - eigenPodImplementation.eigenPodManager(), - eigenPodImplementation.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR(), - 0 - ); - // Create time machine and set block timestamp forward so we can create EigenPod proofs in the past - timeMachine = new TimeMachine(); - beaconChainOracle = new BeaconChainOracleMock(); - // Create mock beacon chain / proof gen interface - beaconChain = new BeaconChainMock(timeMachine, beaconChainOracle, eigenPodManager); - - cheats.startPrank(executorMultisig); - eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); - eigenPodManager.updateBeaconChainOracle(beaconChainOracle); - cheats.stopPrank(); + // // cheats.selectFork(holeskyForkId); + // string memory deploymentInfoPath = "script/configs/holesky/Holesky_current_deployment.config.json"; + // _parseDeployedContracts(deploymentInfoPath); + + // // Add deployed strategies to lstStrats and allStrats + // for (uint i; i < deployedStrategyArray.length; i++) { + // IStrategy strategy = IStrategy(deployedStrategyArray[i]); + + // if (tokensNotTested[address(strategy.underlyingToken())]) { + // continue; + // } + + // // Add to lstStrats and allStrats + // lstStrats.push(strategy); + // allStrats.push(strategy); + // allTokens.push(strategy.underlyingToken()); + // } + + // // Update deposit contract to be a mock + // ethPOSDeposit = new ETHPOSDepositMock(); + // eigenPodImplementation = new EigenPod( + // ethPOSDeposit, + // eigenPodImplementation.eigenPodManager(), + // 0 + // ); + // // Create time machine and mock beacon chain + // timeMachine = new TimeMachine(); + // beaconChain = new BeaconChainMock(eigenPodManager, GENESIS_TIME_MAINNET); + + // cheats.startPrank(executorMultisig); + // eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); + // cheats.stopPrank(); } else { revert("_deployOrFetchContracts: unimplemented forkType"); @@ -914,8 +850,9 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { strategies = new IStrategy[](1); tokenBalances = new uint[](1); - // Award the user with a random multiple of 32 ETH - uint amount = 32 ether * _randUint({ min: 1, max: 3 }); + // Award the user with a random amount of ETH + // This guarantees a multiple of 32 ETH (at least 1, up to/incl 5) + uint amount = 32 ether * _randUint({ min: 1, max: 5 }); cheats.deal(address(user), amount); strategies[0] = BEACONCHAIN_ETH_STRAT; @@ -936,8 +873,9 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser { strategies[i] = strat; } - // Award the user with a random multiple of 32 ETH - uint amount = 32 ether * _randUint({ min: 1, max: 3 }); + // Award the user with a random amount of ETH + // This guarantees a multiple of 32 ETH (at least 1, up to/incl 5) + uint amount = 32 ether * _randUint({ min: 1, max: 5 }); cheats.deal(address(user), amount); // Add BEACONCHAIN_ETH_STRAT and eth balance diff --git a/src/test/integration/TimeMachine.t.sol b/src/test/integration/TimeMachine.t.sol index 7158f9db8..aabb47d4b 100644 --- a/src/test/integration/TimeMachine.t.sol +++ b/src/test/integration/TimeMachine.t.sol @@ -10,8 +10,6 @@ contract TimeMachine is Test { bool pastExists = false; uint lastSnapshot; - uint64 public proofGenStartTime; - function createSnapshot() public returns (uint) { uint snapshot = cheats.snapshot(); lastSnapshot = snapshot; @@ -32,14 +30,4 @@ contract TimeMachine is Test { function warpToPresent(uint curState) public { cheats.revertTo(curState); } - - /// @dev Sets the timestamp we use for proof gen to now, - /// then sets block timestamp to now + secondsAgo. - /// - /// This means we can create mock proofs using an oracle time - /// of `proofGenStartTime`. - function setProofGenStartTime(uint secondsAgo) public { - proofGenStartTime = uint64(block.timestamp); - cheats.warp(block.timestamp + secondsAgo); - } } diff --git a/src/test/integration/deprecatedInterfaces/mainnet/IEigenPod.sol b/src/test/integration/deprecatedInterfaces/mainnet/IEigenPod.sol index 72a698e84..0171653be 100644 --- a/src/test/integration/deprecatedInterfaces/mainnet/IEigenPod.sol +++ b/src/test/integration/deprecatedInterfaces/mainnet/IEigenPod.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.12; import "./BeaconChainProofs.sol"; import "./IEigenPodManager.sol"; -import "./IBeaconChainOracle.sol"; /** * @notice DEPRECATED INTERFACE at commit hash https://github.com/Layr-Labs/eigenlayer-contracts/tree/0139d6213927c0a7812578899ddd3dda58051928 diff --git a/src/test/integration/mocks/BeaconChainMock.t.sol b/src/test/integration/mocks/BeaconChainMock.t.sol index ec5619850..81958fef8 100644 --- a/src/test/integration/mocks/BeaconChainMock.t.sol +++ b/src/test/integration/mocks/BeaconChainMock.t.sol @@ -7,79 +7,157 @@ import "src/contracts/libraries/BeaconChainProofs.sol"; import "src/contracts/libraries/Merkle.sol"; import "src/contracts/pods/EigenPodManager.sol"; -import "src/test/integration/TimeMachine.t.sol"; -import "src/test/integration/mocks/BeaconChainOracleMock.t.sol"; +import "src/test/integration/mocks/EIP_4788_Oracle_Mock.t.sol"; +import "src/test/integration/utils/PrintUtils.t.sol"; -struct CredentialsProofs { - uint64 oracleTimestamp; - BeaconChainProofs.StateRootProof stateRootProof; - uint40[] validatorIndices; - bytes[] validatorFieldsProofs; - bytes32[][] validatorFields; +struct ValidatorFieldsProof { + bytes32[] validatorFields; + bytes validatorFieldsProof; +} + +struct BalanceRootProof { + bytes32 balanceRoot; + bytes proof; } -struct BeaconWithdrawal { - uint64 oracleTimestamp; +struct CheckpointProofs { + BeaconChainProofs.BalanceContainerProof balanceContainerProof; + BeaconChainProofs.BalanceProof[] balanceProofs; +} + +struct CredentialProofs { + uint64 beaconTimestamp; BeaconChainProofs.StateRootProof stateRootProof; - BeaconChainProofs.WithdrawalProof[] withdrawalProofs; bytes[] validatorFieldsProofs; bytes32[][] validatorFields; - bytes32[][] withdrawalFields; } -struct BalanceUpdate { - uint64 oracleTimestamp; +struct StaleBalanceProofs { + uint64 beaconTimestamp; BeaconChainProofs.StateRootProof stateRootProof; - uint40[] validatorIndices; - bytes[] validatorFieldsProofs; - bytes32[][] validatorFields; + BeaconChainProofs.ValidatorProof validatorProof; } -contract BeaconChainMock is Test { +contract BeaconChainMock is PrintUtils { Vm cheats = Vm(HEVM_ADDRESS); struct Validator { + bool isDummy; + bool isSlashed; bytes32 pubkeyHash; - uint40 validatorIndex; bytes withdrawalCreds; uint64 effectiveBalanceGwei; + uint64 activationEpoch; + uint64 exitEpoch; } + + /// @dev All withdrawals are processed with index == 0 + uint constant GWEI_TO_WEI = 1e9; + uint constant ZERO_NODES_LENGTH = 100; + + // Rewards given to each validator during epoch processing + uint64 public constant CONSENSUS_REWARD_AMOUNT_GWEI = 1; + uint64 public constant SLASH_AMOUNT_GWEI = 10; + + /// PROOF CONSTANTS (PROOF LENGTHS, FIELD SIZES): + + // see https://eth2book.info/capella/part3/containers/state/#beaconstate + uint constant BEACON_STATE_FIELDS = 32; + // see https://eth2book.info/capella/part3/containers/blocks/#beaconblock + uint constant BEACON_BLOCK_FIELDS = 5; + + uint immutable BLOCKROOT_PROOF_LEN = 32 * BeaconChainProofs.BEACON_BLOCK_HEADER_TREE_HEIGHT; + uint immutable VAL_FIELDS_PROOF_LEN = 32 * ( + (BeaconChainProofs.VALIDATOR_TREE_HEIGHT + 1) + BeaconChainProofs.BEACON_STATE_TREE_HEIGHT + ); + uint immutable BALANCE_CONTAINER_PROOF_LEN = 32 * ( + BeaconChainProofs.BEACON_BLOCK_HEADER_TREE_HEIGHT + BeaconChainProofs.BEACON_STATE_TREE_HEIGHT + ); + uint immutable BALANCE_PROOF_LEN = 32 * (BeaconChainProofs.BALANCE_TREE_HEIGHT + 1); - uint40 nextValidatorIndex = 0; + uint64 genesisTime; uint64 public nextTimestamp; + + EigenPodManager eigenPodManager; + EIP_4788_Oracle_Mock constant EIP_4788_ORACLE = EIP_4788_Oracle_Mock(0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02); - // Sequential list of created Validators - // Validator[] validators; - // mapping(uint40 => Validator) validators; + /** + * BeaconState containers, used for proofgen: + * https://eth2book.info/capella/part3/containers/state/#beaconstate + */ - mapping(uint40 => Validator) validators; + // Validator container, references every validator created so far + Validator[] validators; - BeaconChainOracleMock oracle; - EigenPodManager eigenPodManager; + // Current balance container, keeps a balance for every validator + // + // Since balances are stored in groups of 4, it's easier to make + // this a mapping rather than an array. If it were an array, its + // length would be validators.length / 4; + mapping(uint40 => bytes32) balances; - /// @dev All withdrawals are processed with index == 0 - uint64 constant WITHDRAWAL_INDEX = 0; - uint constant GWEI_TO_WEI = 1e9; + /** + * Generated proofs for each block timestamp: + */ + + // Maps block.timestamp -> calculated beacon block roots + mapping(uint64 => bytes32) beaconBlockRoots; + + // Keeps track of the index of the last validator we've seen during epoch processing + uint lastIndexProcessed; + uint64 curTimestamp; + + // Maps block.timestamp -> beacon state root and proof + mapping(uint64 => BeaconChainProofs.StateRootProof) stateRootProofs; + + // Maps block.timestamp -> balance container root and proof + mapping(uint64 => BeaconChainProofs.BalanceContainerProof) balanceContainerProofs; + + // Maps block.timestamp -> validatorIndex -> credential proof for that timestamp + mapping(uint64 => mapping(uint40 => ValidatorFieldsProof)) validatorFieldsProofs; + + // Maps block.timestamp -> balanceRootIndex -> balance proof for that timestamp + mapping(uint64 => mapping(uint40 => BalanceRootProof)) balanceRootProofs; + + bytes32[] zeroNodes; - constructor(TimeMachine timeMachine, BeaconChainOracleMock beaconChainOracle, EigenPodManager _eigenPodManager) { - nextTimestamp = timeMachine.proofGenStartTime(); - oracle = beaconChainOracle; + constructor(EigenPodManager _eigenPodManager, uint64 _genesisTime) { + genesisTime = _genesisTime; eigenPodManager = _eigenPodManager; + + // Create mock 4788 oracle + cheats.etch(address(EIP_4788_ORACLE), type(EIP_4788_Oracle_Mock).runtimeCode); + + // Calculate nodes of empty merkle tree + bytes32 curNode = Merkle.merkleizeSha256(new bytes32[](8)); + zeroNodes = new bytes32[](ZERO_NODES_LENGTH); + zeroNodes[0] = curNode; + + for (uint i = 1; i < zeroNodes.length; i++) { + zeroNodes[i] = sha256(abi.encodePacked(curNode, curNode)); + curNode = zeroNodes[i]; + } } - - /** - * @dev Processes a deposit for a new validator and returns the - * information needed to prove withdrawal credentials. - * - * For now, this returns empty proofs that will pass in the oracle, - * but in the future this should use FFI to return a valid proof. - */ - function newValidator( - uint balanceWei, + + function NAME() public pure override returns (string memory) { + return "BeaconChain"; + } + + /******************************************************************************* + EXTERNAL METHODS + *******************************************************************************/ + + /// @dev Creates a new validator by: + /// - Creating the validator container + /// - Setting their current/effective balance + /// - Assigning them a new, unique index + function newValidator( bytes memory withdrawalCreds - ) public returns (uint40, CredentialsProofs memory) { - emit log_named_uint("- BeaconChain.newValidator with balance: ", balanceWei); + ) public payable returns (uint40) { + _logM("newValidator"); + + uint balanceWei = msg.value; // These checks mimic the checks made in the beacon chain deposit contract // @@ -91,702 +169,694 @@ contract BeaconChainMock is Test { uint depositAmount = balanceWei / GWEI_TO_WEI; require(depositAmount <= type(uint64).max, "BeaconChainMock.newValidator: deposit value too high"); - // Create unique index for new validator - uint40 validatorIndex = nextValidatorIndex; - nextValidatorIndex++; + // Create new validator and return its unique index + return _createValidator(withdrawalCreds, uint64(depositAmount)); + } + + /// @dev Initiate an exit by: + /// - Updating the validator's exit epoch + /// - Decreasing current balance to 0 + /// - Withdrawing the balance to the validator's withdrawal credentials + /// NOTE that the validator's effective balance is unchanged until advanceEpoch is called + /// @return exitedBalanceGwei The balance exited to the withdrawal address + /// + /// This partially mimics the beacon chain's behavior, which is: + /// 1. when an exit is initiated, the validator's exit/withdrawable epochs are immediately set + /// 2. in a future slot (as part of the withdrawal queue), the validator's current balance is set to 0 + /// - at the end of this slot, the eth is withdrawn to the withdrawal credentials + /// 3. when the epoch finalizes, the validator's effective balance is updated + /// + /// Because this mock beacon chain doesn't implement a withdrawal queue or per-slot processing, + /// `exitValidator` combines steps 1 and 2 into this method. + /// + /// TODO we may need to advance a slot here to maintain the properties we want in startCheckpoint + function exitValidator(uint40 validatorIndex) public returns (uint64 exitedBalanceGwei) { + _logM("exitValidator"); + + // Update validator.exitEpoch + Validator storage v = validators[validatorIndex]; + require(!v.isDummy, "BeaconChainMock: attempting to exit dummy validator. We need those for proofgen >:("); + require(v.exitEpoch == BeaconChainProofs.FAR_FUTURE_EPOCH, "BeaconChainMock: validator already exited"); + v.exitEpoch = currentEpoch() + 1; + + // Set current balance to 0 + exitedBalanceGwei = _currentBalanceGwei(validatorIndex); + _setCurrentBalance(validatorIndex, 0); - // Create new validator and record in state - Validator memory validator = Validator({ - pubkeyHash: keccak256(abi.encodePacked(validatorIndex)), - validatorIndex: validatorIndex, - withdrawalCreds: withdrawalCreds, - effectiveBalanceGwei: uint64(depositAmount) - }); - validators[validatorIndex] = validator; + // Send current balance to pod + address destination = _toAddress(validators[validatorIndex].withdrawalCreds); + cheats.deal(destination, address(destination).balance + uint(uint(exitedBalanceGwei) * GWEI_TO_WEI)); - return (validator.validatorIndex, _genCredentialsProof(validator)); + return exitedBalanceGwei; } - /** - * @dev Exit a validator from the beacon chain, given its validatorIndex - * The passed-in validatorIndex should correspond to a validator created - * via `newValidator` above. - * - * This method will return the exit proofs needed to process eigenpod withdrawals. - * Additionally, it will send the withdrawal amount to the validator's withdrawal - * destination. - */ - function exitValidator(uint40 validatorIndex) public returns (BeaconWithdrawal memory) { - emit log_named_uint("- BeaconChain.exitValidator: ", validatorIndex); + function slashValidators(uint40[] memory _validators) public returns (uint64 slashedBalanceGwei) { + _logM("slashValidators"); - Validator memory validator = validators[validatorIndex]; + for (uint i = 0; i < _validators.length; i++) { + uint40 validatorIndex = _validators[i]; + Validator storage v = validators[validatorIndex]; + require(!v.isDummy, "BeaconChainMock: attempting to exit dummy validator. We need those for proofgen >:("); - // Get the withdrawal amount and destination - uint amountToWithdraw = validator.effectiveBalanceGwei * GWEI_TO_WEI; - address destination = _toAddress(validator.withdrawalCreds); + // Mark slashed and initiate validator exit + if (!v.isSlashed) { + v.isSlashed = true; + v.exitEpoch = currentEpoch() + 1; + } + + // Calculate slash amount + uint64 curBalanceGwei = _currentBalanceGwei(validatorIndex); + if (SLASH_AMOUNT_GWEI > curBalanceGwei) { + slashedBalanceGwei += curBalanceGwei; + curBalanceGwei = 0; + } else { + slashedBalanceGwei += SLASH_AMOUNT_GWEI; + curBalanceGwei -= SLASH_AMOUNT_GWEI; + } - // Generate exit proofs for a full exit - BeaconWithdrawal memory withdrawal = _genExitProof(validator); + // Decrease current balance (effective balance updated during epoch processing) + _setCurrentBalance(validatorIndex, curBalanceGwei); + } - // Update state - set validator balance to zero and send balance to withdrawal destination - validators[validatorIndex].effectiveBalanceGwei = 0; - cheats.deal(destination, destination.balance + amountToWithdraw); + return slashedBalanceGwei; + } - return withdrawal; + /// @dev Move forward one epoch on the beacon chain, taking care of important epoch processing: + /// - Award ALL validators CONSENSUS_REWARD_AMOUNT + /// - Withdraw any balance over 32 ETH + /// - Withdraw any balance for exited validators + /// - Effective balances updated (NOTE: we do not use hysteresis!) + /// - Move time forward one epoch + /// - State root calculated and credential/balance proofs generated for all validators + /// - Send state root to 4788 oracle + /// + /// Note: + /// - DOES generate consensus rewards for ALL non-exited validators + /// - DOES withdraw in excess of 32 ETH / if validator is exited + function advanceEpoch() public { + _logM("advanceEpoch"); + + _generateRewards(); + _withdrawExcess(); + + _advanceEpoch(); } - /** - * Note: `delta` is expected to be a raw token amount. This method will convert the delta to Gwei - */ - function updateBalance(uint40 validatorIndex, int delta) public returns (BalanceUpdate memory) { - delta /= int(GWEI_TO_WEI); + /// @dev Like `advanceEpoch`, but does NOT generate consensus rewards for validators. + /// This amount is added to each validator's current balance before effective balances + /// are updated. + /// + /// Note: + /// - does NOT generate consensus rewards + /// - DOES withdraw in excess of 32 ETH / if validator is exited + function advanceEpoch_NoRewards() public { + _logM("advanceEpoch_NoRewards"); - emit log_named_uint("- BeaconChain.updateBalance for validator: ", validatorIndex); - emit log_named_int("- BeaconChain.updateBalance delta gwei: ", delta); - - // Apply delta and update validator balance in state - uint64 newBalance; - if (delta <= 0) { - newBalance = validators[validatorIndex].effectiveBalanceGwei - uint64(uint(-delta)); - } else { - newBalance = validators[validatorIndex].effectiveBalanceGwei + uint64(uint(delta)); - } - validators[validatorIndex].effectiveBalanceGwei = newBalance; - - // Generate balance update proof - Validator memory validator = validators[validatorIndex]; - BalanceUpdate memory update = _genBalanceUpdateProof(validator); + _withdrawExcess(); - return update; + _advanceEpoch(); } - function setNextTimestamp(uint64 timestamp) public { - nextTimestamp = timestamp; + /// @dev Like `advanceEpoch`, but explicitly does NOT withdraw if balances + /// are over 32 ETH. This exists to support tests that check share increases solely + /// due to beacon chain balance changes. + /// + /// Note: + /// - DOES generate consensus rewards for ALL non-exited validators + /// - does NOT withdraw in excess of 32 ETH + /// - does NOT withdraw if validator is exited + function advanceEpoch_NoWithdraw() public { + _logM("advanceEpoch_NoWithdraw"); + + _generateRewards(); + + _advanceEpoch(); } - function balanceOfGwei(uint40 validatorIndex) public view returns (uint64) { - return validators[validatorIndex].effectiveBalanceGwei; + /// @dev Iterate over all validators. If the validator is still active, + /// add CONSENSUS_REWARD_AMOUNT_GWEI to its current balance + function _generateRewards() internal { + uint totalRewarded; + for (uint i = 0; i < validators.length; i++) { + Validator storage v = validators[i]; + if (v.isDummy) continue; // don't process dummy validators + + // If validator has not initiated exit, add rewards to their current balance + if (v.exitEpoch == BeaconChainProofs.FAR_FUTURE_EPOCH) { + uint64 balanceGwei = _currentBalanceGwei(uint40(i)); + balanceGwei += CONSENSUS_REWARD_AMOUNT_GWEI; + totalRewarded++; + + _setCurrentBalance(uint40(i), balanceGwei); + } + } + + _log("- generated rewards for num validators", totalRewarded); } - function pubkeyHash(uint40 validatorIndex) public view returns (bytes32) { - return validators[validatorIndex].pubkeyHash; + /// @dev Iterate over all validators. If the validator has > 32 ETH current balance + /// OR is exited, withdraw the excess to the validator's withdrawal address. + function _withdrawExcess() internal { + uint totalExcessWei; + for (uint i = 0; i < validators.length; i++) { + Validator storage v = validators[i]; + if (v.isDummy) continue; // don't process dummy validators + + uint balanceWei = uint(_currentBalanceGwei(uint40(i))) * GWEI_TO_WEI; + address destination = _toAddress(v.withdrawalCreds); + uint excessBalanceWei; + uint64 newBalanceGwei = uint64(balanceWei / GWEI_TO_WEI); + + // If the validator has exited, withdraw any existing balance + // + // If the validator has > 32 ether, withdraw anything over that + if (v.exitEpoch != BeaconChainProofs.FAR_FUTURE_EPOCH) { + if (balanceWei == 0) continue; + + excessBalanceWei = balanceWei; + newBalanceGwei = 0; + } else if (balanceWei > 32 ether) { + excessBalanceWei = balanceWei - 32 ether; + newBalanceGwei = 32 gwei; + } + + // Send ETH to withdrawal address + cheats.deal(destination, address(destination).balance + excessBalanceWei); + totalExcessWei += excessBalanceWei; + + // Update validator's current balance + _setCurrentBalance(uint40(i), newBalanceGwei); + } + + if (totalExcessWei != 0) + _log("- withdrew excess balance", totalExcessWei); } - /** - * INTERNAL/HELPER METHODS: - */ + function _advanceEpoch() public { + // Update effective balances for each validator + for (uint i = 0; i < validators.length; i++) { + Validator storage v = validators[i]; + if (v.isDummy) continue; // don't process dummy validators - /** - * @dev For a new validator, generate the beacon chain block root and merkle proof - * needed to prove withdrawal credentials to an EigenPod. - * - * The generated block root is sent to the `BeaconChainOracleMock`, and can be - * queried using `proof.oracleTimestamp` to validate the generated proof. - */ - function _genCredentialsProof(Validator memory validator) internal returns (CredentialsProofs memory) { - CredentialsProofs memory proof; - - proof.validatorIndices = new uint40[](1); - proof.validatorIndices[0] = validator.validatorIndex; - - // Create validatorFields for the new validator - proof.validatorFields = new bytes32[][](1); - proof.validatorFields[0] = new bytes32[](2 ** BeaconChainProofs.VALIDATOR_FIELD_TREE_HEIGHT); - proof.validatorFields[0][BeaconChainProofs.VALIDATOR_PUBKEY_INDEX] = validator.pubkeyHash; - proof.validatorFields[0][BeaconChainProofs.VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX] = - bytes32(validator.withdrawalCreds); - proof.validatorFields[0][BeaconChainProofs.VALIDATOR_BALANCE_INDEX] = - _toLittleEndianUint64(validator.effectiveBalanceGwei); - - // Calculate beaconStateRoot using validator index and an empty proof: - proof.validatorFieldsProofs = new bytes[](1); - proof.validatorFieldsProofs[0] = new bytes(VAL_FIELDS_PROOF_LEN); - bytes32 validatorRoot = Merkle.merkleizeSha256(proof.validatorFields[0]); - uint index = _calcValProofIndex(validator.validatorIndex); - - bytes32 beaconStateRoot = Merkle.processInclusionProofSha256({ - proof: proof.validatorFieldsProofs[0], - leaf: validatorRoot, - index: index - }); + // Get current balance and trim anything over 32 ether + uint64 balanceGwei = _currentBalanceGwei(uint40(i)); + if (balanceGwei > 32 gwei) { + balanceGwei = 32 gwei; + } - // Calculate blockRoot using beaconStateRoot and an empty proof: - bytes memory blockRootProof = new bytes(BLOCKROOT_PROOF_LEN); - bytes32 blockRoot = Merkle.processInclusionProofSha256({ - proof: blockRootProof, - leaf: beaconStateRoot, - index: BeaconChainProofs.STATE_ROOT_INDEX - }); + v.effectiveBalanceGwei = balanceGwei; + } - proof.stateRootProof = BeaconChainProofs.StateRootProof({ - beaconStateRoot: beaconStateRoot, - proof: blockRootProof + _log("- updated effective balances"); + + // Move forward one epoch + // _log("-- current time", block.timestamp); + _log("-- current epoch", currentEpoch()); + + uint64 curEpoch = currentEpoch(); + cheats.warp(_nextEpochStartTimestamp(curEpoch)); + curTimestamp = uint64(block.timestamp); + + // _log("-- new time", block.timestamp); + _log("- jumped to next epoch", currentEpoch()); + + _log("- building beacon state trees"); + + // Log total number of validators and number being processed for the first time + if (validators.length > 0) { + lastIndexProcessed = validators.length - 1; + } else { + // generate an empty root if we don't have any validators + EIP_4788_ORACLE.setBlockRoot(curTimestamp, keccak256("")); + + _log("-- no validators; added empty block root"); + return; + } + + // Build merkle tree for validators + bytes32 validatorsRoot = _buildMerkleTree({ + leaves: _getValidatorLeaves(), + treeHeight: BeaconChainProofs.VALIDATOR_TREE_HEIGHT + 1, + tree: trees[curTimestamp].validatorTree + }); + // _log("-- validator container root", validatorsRoot); + + // Build merkle tree for current balances + bytes32 balanceContainerRoot = _buildMerkleTree({ + leaves: _getBalanceLeaves(), + treeHeight: BeaconChainProofs.BALANCE_TREE_HEIGHT + 1, + tree: trees[curTimestamp].balancesTree + }); + // _log("-- balances container root", balanceContainerRoot); + + // Build merkle tree for BeaconState + bytes32 beaconStateRoot = _buildMerkleTree({ + leaves: _getBeaconStateLeaves(validatorsRoot, balanceContainerRoot), + treeHeight: BeaconChainProofs.BEACON_STATE_TREE_HEIGHT, + tree: trees[curTimestamp].stateTree }); + // _log("-- beacon state root", beaconStateRoot); - // Send the block root to the oracle and increment timestamp: - proof.oracleTimestamp = uint64(nextTimestamp); + // Build merkle tree for BeaconBlock + bytes32 beaconBlockRoot = _buildMerkleTree({ + leaves: _getBeaconBlockLeaves(beaconStateRoot), + treeHeight: BeaconChainProofs.BEACON_BLOCK_HEADER_TREE_HEIGHT, + tree: trees[curTimestamp].blockTree + }); + _log("-- beacon block root", beaconBlockRoot); - oracle.setBlockRoot(nextTimestamp, blockRoot); - nextTimestamp++; + // Push new block root to oracle + EIP_4788_ORACLE.setBlockRoot(curTimestamp, beaconBlockRoot); - return proof; + // Pre-generate proofs to pass to EigenPod methods + _genStateRootProof(beaconStateRoot); + _genBalanceContainerProof(balanceContainerRoot); + _genCredentialProofs(); + _genBalanceProofs(); } - - /** - * @dev Generates the proofs and roots needed to prove a validator's exit from - * the beacon chain. - * - * The generated beacon block root is sent to `BeaconChainOracleMock`, and can - * be queried using `withdrawal.oracleTimestamp` to validate the generated proof. - * - * Since a withdrawal proof requires proving multiple leaves in the same tree, this - * method uses `_genConvergentProofs` to calculate proofs and roots for intermediate - * subtrees, while retaining the information needed to supply an eigenpod with a proof. - * - * The overall merkle tree being proven looks like this: - * - * - beaconBlockRoot (submitted to oracle at end) - * -- beaconStateRoot - * ---- validatorFieldsRoot - * ---- blockRoot (from historical summaries) - * -------- slotRoot - * -------- executionPayloadRoot - * ---------------- timestampRoot - * ---------------- withdrawalFieldsRoot - * - * This method first generates proofs for the lowest leaves, and uses the resulting - * intermediate hashes to generate proofs for higher leaves. Eventually, all of these - * roots are calculated and the final beaconBlockRoot can be calculated and sent to the - * oracle. - */ - function _genExitProof(Validator memory validator) internal returns (BeaconWithdrawal memory) { - BeaconWithdrawal memory withdrawal; - uint64 withdrawalEpoch = uint64(block.timestamp); - - // Get a new, unique timestamp for queries to the oracle - withdrawal.oracleTimestamp = uint64(nextTimestamp); - nextTimestamp++; - - // Initialize proof arrays - BeaconChainProofs.WithdrawalProof memory withdrawalProof = _initWithdrawalProof({ - withdrawalEpoch: withdrawalEpoch, - withdrawalIndex: WITHDRAWAL_INDEX, - oracleTimestamp: withdrawal.oracleTimestamp - }); - // Calculate withdrawalFields and record the validator's index and withdrawal amount - withdrawal.withdrawalFields = new bytes32[][](1); - withdrawal.withdrawalFields[0] = new bytes32[](2 ** BeaconChainProofs.WITHDRAWAL_FIELD_TREE_HEIGHT); - withdrawal.withdrawalFields[0][BeaconChainProofs.WITHDRAWAL_VALIDATOR_INDEX_INDEX] = - _toLittleEndianUint64(validator.validatorIndex); - withdrawal.withdrawalFields[0][BeaconChainProofs.WITHDRAWAL_VALIDATOR_AMOUNT_INDEX] = - _toLittleEndianUint64(validator.effectiveBalanceGwei); - - { - /** - * Generate proofs then root for subtree: - * - * executionPayloadRoot - * - timestampRoot (withdrawalProof.timestampProof) - * - withdrawalFieldsRoot (withdrawalProof.withdrawalProof) - */ - withdrawalProof.executionPayloadRoot = _genExecPayloadProofs({ - withdrawalProof: withdrawalProof, - withdrawalRoot: Merkle.merkleizeSha256(withdrawal.withdrawalFields[0]) - }); - } + /******************************************************************************* + INTERNAL FUNCTIONS + *******************************************************************************/ - { - /** - * Generate proofs then root for subtree: - * - * blockRoot (historical summaries) - * - slotRoot (withdrawalProof.slotProof) - * - executionPayloadRoot (withdrawalProof.executionPayloadProof) - */ - withdrawalProof.blockRoot = _genBlockRootProofs({ - withdrawalProof: withdrawalProof - }); - } + function _createValidator(bytes memory withdrawalCreds, uint64 balanceGwei) internal returns (uint40) { + uint40 validatorIndex = uint40(validators.length); - // validatorFields - withdrawal.validatorFields = new bytes32[][](1); - withdrawal.validatorFields[0] = new bytes32[](2 ** BeaconChainProofs.VALIDATOR_FIELD_TREE_HEIGHT); - withdrawal.validatorFields[0][BeaconChainProofs.VALIDATOR_PUBKEY_INDEX] = validator.pubkeyHash; - withdrawal.validatorFields[0][BeaconChainProofs.VALIDATOR_WITHDRAWABLE_EPOCH_INDEX] = - _toLittleEndianUint64(withdrawalEpoch); - - withdrawal.validatorFieldsProofs = new bytes[](1); - withdrawal.validatorFieldsProofs[0] = new bytes(VAL_FIELDS_PROOF_LEN); - - { - /** - * Generate proofs then root for subtree: - * - * beaconStateRoot - * - validatorFieldsRoot (withdrawal.validatorFieldsProofs[0]) - * - blockRoot (historical summaries) (withdrawalProof.historicalSummaryBlockRootProof) - */ - withdrawal.stateRootProof.beaconStateRoot = _genBeaconStateRootProofs({ - withdrawalProof: withdrawalProof, - validatorFieldsProof: withdrawal.validatorFieldsProofs[0], - validatorIndex: validator.validatorIndex, - validatorRoot: Merkle.merkleizeSha256(withdrawal.validatorFields[0]) - }); + // HACK to make balance proofs work. Every 4 validators we create + // a dummy validator with empty withdrawal credentials and a unique + // balance value. This ensures that each balanceRoot is unique, which + // allows our efficient beacon state builder to work. + // + // For more details on this hack see _buildMerkleTree + if (validatorIndex % 4 == 0) { + uint64 dummyBalanceGwei = type(uint64).max - uint64(validators.length); + + bytes memory _dummyPubkey = new bytes(48); + assembly { mstore(add(48, _dummyPubkey), validatorIndex) } + validators.push(Validator({ + isDummy: true, + isSlashed: false, + pubkeyHash: sha256(abi.encodePacked(_dummyPubkey, bytes16(0))), + withdrawalCreds: "", + effectiveBalanceGwei: dummyBalanceGwei, + activationEpoch: BeaconChainProofs.FAR_FUTURE_EPOCH, + exitEpoch: BeaconChainProofs.FAR_FUTURE_EPOCH + })); + _setCurrentBalance(validatorIndex, dummyBalanceGwei); + + validatorIndex++; } - withdrawal.withdrawalProofs = new BeaconChainProofs.WithdrawalProof[](1); - withdrawal.withdrawalProofs[0] = withdrawalProof; + // Use pubkey format from `EigenPod._calculateValidatorPubkeyHash` + bytes memory _pubkey = new bytes(48); + assembly { mstore(add(48, _pubkey), validatorIndex) } + validators.push(Validator({ + isDummy: false, + isSlashed: false, + pubkeyHash: sha256(abi.encodePacked(_pubkey, bytes16(0))), + withdrawalCreds: withdrawalCreds, + effectiveBalanceGwei: balanceGwei, + activationEpoch: currentEpoch(), + exitEpoch: BeaconChainProofs.FAR_FUTURE_EPOCH + })); + _setCurrentBalance(validatorIndex, balanceGwei); - // Calculate beaconBlockRoot using beaconStateRoot and an empty proof: - withdrawal.stateRootProof.proof = new bytes(BLOCKROOT_PROOF_LEN); - bytes32 beaconBlockRoot = Merkle.processInclusionProofSha256({ - proof: withdrawal.stateRootProof.proof, - leaf: withdrawal.stateRootProof.beaconStateRoot, - index: BeaconChainProofs.STATE_ROOT_INDEX - }); + return validatorIndex; + } - // Send the block root to the oracle - oracle.setBlockRoot(withdrawal.oracleTimestamp, beaconBlockRoot); - return withdrawal; + struct Tree { + mapping(bytes32 => bytes32) siblings; + mapping(bytes32 => bytes32) parents; } - function _genBalanceUpdateProof(Validator memory validator) internal returns (BalanceUpdate memory) { - BalanceUpdate memory update; + struct MerkleTrees { + Tree validatorTree; + Tree balancesTree; + Tree stateTree; + Tree blockTree; + } - update.validatorIndices = new uint40[](1); - update.validatorIndices[0] = validator.validatorIndex; + /// Timestamp -> merkle trees constructed at that timestamp + /// Used to generate proofs + mapping(uint64 => MerkleTrees) trees; + + /// @dev Builds a merkle tree using the given leaves and height + /// -- if the leaves given are not complete (i.e. the depth should have more leaves), + /// a pre-calculated zero-node is used to complete the tree. + /// -- each pair of nodes is stored in `siblings`, and their parent in `parents`. + /// These mappings are used to build proofs for any individual leaf + /// @return The root of the merkle tree + /// + /// HACK: this sibling/parent method of tree construction relies on all passed-in leaves + /// being unique, so that we don't overwrite siblings/parents. This is simple for trees + /// like the validator tree, as each leaf is a validator's unique validatorFields. + /// However, for the balances tree, the leaves may not be distinct. To get around this, + /// _createValidator adds "dummy" validators every 4 validators created, with a unique + /// balance value. This ensures each balance root is unique. + function _buildMerkleTree( + bytes32[] memory leaves, + uint treeHeight, + Tree storage tree + ) internal returns (bytes32) { + for (uint depth = 0; depth < treeHeight; depth++) { + uint newLength = (leaves.length + 1) / 2; + bytes32[] memory newLeaves = new bytes32[](newLength); + + // Hash each pair of nodes in this level of the tree + for (uint i = 0; i < newLength; i++) { + uint leftIdx = 2 * i; + uint rightIdx = leftIdx + 1; + + // Get left leaf + bytes32 leftLeaf = leaves[leftIdx]; + + // Calculate right leaf + bytes32 rightLeaf; + if (rightIdx < leaves.length) { + rightLeaf = leaves[rightIdx]; + } else { + rightLeaf = _getZeroNode(depth); + } - // Create validatorFields showing the balance update - update.validatorFields = new bytes32[][](1); - update.validatorFields[0] = new bytes32[](2 ** BeaconChainProofs.VALIDATOR_FIELD_TREE_HEIGHT); - update.validatorFields[0][BeaconChainProofs.VALIDATOR_PUBKEY_INDEX] = validator.pubkeyHash; - update.validatorFields[0][BeaconChainProofs.VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX] = - bytes32(validator.withdrawalCreds); - update.validatorFields[0][BeaconChainProofs.VALIDATOR_BALANCE_INDEX] = - _toLittleEndianUint64(validator.effectiveBalanceGwei); + // Hash left and right + bytes32 result = sha256(abi.encodePacked(leftLeaf, rightLeaf)); + newLeaves[i] = result; + + // Record results, used to generate individual proofs later: + // Record left and right as siblings + tree.siblings[leftLeaf] = rightLeaf; + tree.siblings[rightLeaf] = leftLeaf; + // Record the result as the parent of left and right + tree.parents[leftLeaf] = result; + tree.parents[rightLeaf] = result; + } - // Calculate beaconStateRoot using validator index and an empty proof: - update.validatorFieldsProofs = new bytes[](1); - update.validatorFieldsProofs[0] = new bytes(VAL_FIELDS_PROOF_LEN); - bytes32 validatorRoot = Merkle.merkleizeSha256(update.validatorFields[0]); - uint index = _calcValProofIndex(validator.validatorIndex); + // Move up one level + leaves = newLeaves; + } - bytes32 beaconStateRoot = Merkle.processInclusionProofSha256({ - proof: update.validatorFieldsProofs[0], - leaf: validatorRoot, - index: index - }); + require(leaves.length == 1, "BeaconChainMock._buildMerkleTree: invalid tree somehow"); + return leaves[0]; + } - // Calculate blockRoot using beaconStateRoot and an empty proof: - bytes memory blockRootProof = new bytes(BLOCKROOT_PROOF_LEN); - bytes32 blockRoot = Merkle.processInclusionProofSha256({ - proof: blockRootProof, - leaf: beaconStateRoot, - index: BeaconChainProofs.STATE_ROOT_INDEX - }); + function _genStateRootProof(bytes32 beaconStateRoot) internal { + bytes memory proof = new bytes(BLOCKROOT_PROOF_LEN); + bytes32 curNode = beaconStateRoot; + + uint depth = 0; + for (uint i = 0; i < BeaconChainProofs.BEACON_BLOCK_HEADER_TREE_HEIGHT; i++) { + bytes32 sibling = trees[curTimestamp].blockTree.siblings[curNode]; - update.stateRootProof = BeaconChainProofs.StateRootProof({ + // proof[j] = sibling; + assembly { + mstore( + add(proof, add(32, mul(32, i))), + sibling + ) + } + + curNode = trees[curTimestamp].blockTree.parents[curNode]; + depth++; + } + + stateRootProofs[curTimestamp] = BeaconChainProofs.StateRootProof({ beaconStateRoot: beaconStateRoot, - proof: blockRootProof + proof: proof }); - - // Send the block root to the oracle and increment timestamp: - update.oracleTimestamp = uint64(nextTimestamp); - oracle.setBlockRoot(nextTimestamp, blockRoot); - nextTimestamp++; - - return update; } - /** - * @dev Generates converging merkle proofs for timestampRoot and withdrawalRoot - * under the executionPayloadRoot. - * - * `withdrawalProof.timestampProof` and `withdrawalProof.withdrawalProof` are - * directly updated here. - * - * @return executionPayloadRoot - */ - function _genExecPayloadProofs( - BeaconChainProofs.WithdrawalProof memory withdrawalProof, - bytes32 withdrawalRoot - ) internal view returns (bytes32) { - - uint withdrawalProofIndex = - (BeaconChainProofs.WITHDRAWALS_INDEX << (BeaconChainProofs.WITHDRAWALS_TREE_HEIGHT + 1)) | - uint(withdrawalProof.withdrawalIndex); - - /** - * Generate merkle proofs for timestampRoot and withdrawalRoot - * that converge at or before executionPayloadRoot. - * - * timestampProof length: 4 - * withdrawalProof length: 9 - */ - _genConvergentProofs({ - shortProof: withdrawalProof.timestampProof, - shortIndex: BeaconChainProofs.TIMESTAMP_INDEX, - shortLeaf: withdrawalProof.timestampRoot, - longProof: withdrawalProof.withdrawalProof, - longIndex: withdrawalProofIndex, - longLeaf: withdrawalRoot - }); + function _genBalanceContainerProof(bytes32 balanceContainerRoot) internal { + bytes memory proof = new bytes(BALANCE_CONTAINER_PROOF_LEN); + bytes32 curNode = balanceContainerRoot; - // Use generated proofs to calculate tree root and verify both proofs - // result in the same root: - bytes32 execPayloadRoot = Merkle.processInclusionProofSha256({ - proof: withdrawalProof.timestampProof, - leaf: withdrawalProof.timestampRoot, - index: BeaconChainProofs.TIMESTAMP_INDEX - }); + uint totalHeight = BALANCE_CONTAINER_PROOF_LEN / 32; + uint depth = 0; + for (uint i = 0; i < BeaconChainProofs.BEACON_STATE_TREE_HEIGHT; i++) { + bytes32 sibling = trees[curTimestamp].stateTree.siblings[curNode]; - bytes32 expectedRoot = Merkle.processInclusionProofSha256({ - proof: withdrawalProof.withdrawalProof, - leaf: withdrawalRoot, - index: withdrawalProofIndex - }); + // proof[j] = sibling; + assembly { + mstore( + add(proof, add(32, mul(32, i))), + sibling + ) + } - require(execPayloadRoot == expectedRoot, "_genExecPayloadProofs: mismatched roots"); - - return execPayloadRoot; - } + curNode = trees[curTimestamp].stateTree.parents[curNode]; + depth++; + } - /** - * @dev Generates converging merkle proofs for slotRoot and executionPayloadRoot - * under the block root (historical summaries). - * - * `withdrawalProof.slotProof` and `withdrawalProof.executionPayloadProof` are - * directly updated here. - * - * @return historical summary block root - */ - function _genBlockRootProofs( - BeaconChainProofs.WithdrawalProof memory withdrawalProof - ) internal view returns (bytes32) { - - uint slotRootIndex = BeaconChainProofs.SLOT_INDEX; - uint execPayloadIndex = - (BeaconChainProofs.BODY_ROOT_INDEX << BeaconChainProofs.BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT) | - BeaconChainProofs.EXECUTION_PAYLOAD_INDEX; - - /** - * Generate merkle proofs for slotRoot and executionPayloadRoot - * that converge at or before block root. - * - * slotProof length: 3 - * executionPayloadProof length: 7 - */ - _genConvergentProofs({ - shortProof: withdrawalProof.slotProof, - shortIndex: slotRootIndex, - shortLeaf: withdrawalProof.slotRoot, - longProof: withdrawalProof.executionPayloadProof, - longIndex: execPayloadIndex, - longLeaf: withdrawalProof.executionPayloadRoot - }); + for (uint i = depth; i < totalHeight; i++) { + bytes32 sibling = trees[curTimestamp].blockTree.siblings[curNode]; - // Use generated proofs to calculate tree root and verify both proofs - // result in the same root: - bytes32 blockRoot = Merkle.processInclusionProofSha256({ - proof: withdrawalProof.slotProof, - leaf: withdrawalProof.slotRoot, - index: slotRootIndex - }); + // proof[j] = sibling; + assembly { + mstore( + add(proof, add(32, mul(32, i))), + sibling + ) + } - bytes32 expectedRoot = Merkle.processInclusionProofSha256({ - proof: withdrawalProof.executionPayloadProof, - leaf: withdrawalProof.executionPayloadRoot, - index: execPayloadIndex - }); + curNode = trees[curTimestamp].blockTree.parents[curNode]; + depth++; + } - require(blockRoot == expectedRoot, "_genBlockRootProofs: mismatched roots"); - - return blockRoot; + balanceContainerProofs[curTimestamp] = BeaconChainProofs.BalanceContainerProof({ + balanceContainerRoot: balanceContainerRoot, + proof: proof + }); } - /** - * @dev Generates converging merkle proofs for block root and validatorRoot - * under the beaconStateRoot. - * - * `withdrawalProof.historicalSummaryBlockRootProof` and `validatorFieldsProof` are - * directly updated here. - * - * @return beaconStateRoot - */ - function _genBeaconStateRootProofs( - BeaconChainProofs.WithdrawalProof memory withdrawalProof, - bytes memory validatorFieldsProof, - uint40 validatorIndex, - bytes32 validatorRoot - ) internal view returns (bytes32) { - uint blockHeaderIndex = _calcBlockHeaderIndex(withdrawalProof); - uint validatorProofIndex = _calcValProofIndex(validatorIndex); - - /** - * Generate merkle proofs for validatorRoot and blockRoot - * that converge at or before beaconStateRoot. - * - * historicalSummaryBlockRootProof length: 44 - * validatorFieldsProof length: 46 - */ - _genConvergentProofs({ - shortProof: withdrawalProof.historicalSummaryBlockRootProof, - shortIndex: blockHeaderIndex, - shortLeaf: withdrawalProof.blockRoot, - longProof: validatorFieldsProof, - longIndex: validatorProofIndex, - longLeaf: validatorRoot - }); + function _genCredentialProofs() internal { + mapping(uint40 => ValidatorFieldsProof) storage vfProofs = validatorFieldsProofs[curTimestamp]; - // Use generated proofs to calculate tree root and verify both proofs - // result in the same root: - bytes32 beaconStateRoot = Merkle.processInclusionProofSha256({ - proof: withdrawalProof.historicalSummaryBlockRootProof, - leaf: withdrawalProof.blockRoot, - index: blockHeaderIndex - }); + // Calculate credential proofs for each validator + for (uint i = 0; i < validators.length; i++) { - bytes32 expectedRoot = Merkle.processInclusionProofSha256({ - proof: validatorFieldsProof, - leaf: validatorRoot, - index: validatorProofIndex - }); + bytes memory proof = new bytes(VAL_FIELDS_PROOF_LEN); + bytes32[] memory validatorFields = _getValidatorFields(uint40(i)); + bytes32 curNode = Merkle.merkleizeSha256(validatorFields); - require(beaconStateRoot == expectedRoot, "_genBeaconStateRootProofs: mismatched roots"); - - return beaconStateRoot; - } + // Validator fields leaf -> validator container root + uint depth = 0; + for (uint j = 0; j < 1 + BeaconChainProofs.VALIDATOR_TREE_HEIGHT; j++) { + bytes32 sibling = trees[curTimestamp].validatorTree.siblings[curNode]; - /** - * @dev Generates converging merkle proofs given two leaves and empty proofs. - * Basics: - * - `shortProof` and `longProof` start as empty proofs initialized to the correct - * length for their respective paths. - * - At the end of the method, `shortProof` and `longProof` are still entirely empty - * EXCEPT at the point where the proofs would normally converge under the root hash. - * - At this point, `shortProof` will be assigned the current hash for the `longLeaf` proof - * ... and `longProof` will be assigned the current hash for the `shortLeaf` proof - * - * Steps: - * 1. Because the beacon chain has trees and leaves at varying heights, this method - * first calculates the root of the longer proof's subtree so that the remaining - * proof length is the same for both leaves. - * 2. This method simultaneously computes each leaf's remaining proof step-by-step, - * performing effectively the same steps as `Merkle.processInclusionProof256`. - * 3. At each step, we check to see if the current indices represent sibling leaves. - * 4. If `shortIndex` and `longIndex` are siblings: - * - longProof[longProof_i] = curShortHash - * - shortProof[shortProof_i] = curLongHash - * - * ... Once we've found this convergence and placed each sibling's current hash in - * its opposing sibling's proof, we're done! - * @param shortProof An empty proof initialized to the correct length for the shorter proof path - * @param shortIndex The index of the - */ - function _genConvergentProofs( - bytes memory shortProof, - uint shortIndex, - bytes32 shortLeaf, - bytes memory longProof, - uint longIndex, - bytes32 longLeaf - ) internal view { - require(longProof.length >= shortProof.length, "_genConvergentProofs: invalid input"); - - bytes32[1] memory curShortHash = [shortLeaf]; - bytes32[1] memory curLongHash = [longLeaf]; - - // Calculate root of long subtree - uint longProofOffset = longProof.length - shortProof.length; - for (uint i = 32; i <= longProofOffset; i += 32) { - if (longIndex % 2 == 0) { + // proof[j] = sibling; assembly { - mstore(0x00, mload(curLongHash)) - mstore(0x20, mload(add(longProof, i))) - } - } else { - assembly { - mstore(0x00, mload(add(longProof, i))) - mstore(0x20, mload(curLongHash)) + mstore( + add(proof, add(32, mul(32, j))), + sibling + ) } + + curNode = trees[curTimestamp].validatorTree.parents[curNode]; + depth++; } - // Compute hash and divide index - assembly { - if iszero(staticcall(sub(gas(), 2000), 2, 0x00, 0x40, curLongHash, 0x20)) { - revert(0, 0) + // Validator container root -> beacon state root + for ( + uint j = depth; + j < 1 + BeaconChainProofs.VALIDATOR_TREE_HEIGHT + BeaconChainProofs.BEACON_STATE_TREE_HEIGHT; + j++ + ) { + bytes32 sibling = trees[curTimestamp].stateTree.siblings[curNode]; + + // proof[j] = sibling; + assembly { + mstore( + add(proof, add(32, mul(32, j))), + sibling + ) } - longIndex := div(longIndex, 2) + + curNode = trees[curTimestamp].stateTree.parents[curNode]; + depth++; } + + vfProofs[uint40(i)].validatorFields = validatorFields; + vfProofs[uint40(i)].validatorFieldsProof = proof; } + } - { - // Now that we've calculated the longest sub-tree, continue merklizing both trees simultaneously. - // When we reach two leaf indices s.t. A is even and B == A + 1, or vice versa, we know we have - // found the point where the two sub-trees converge. - uint longProof_i = 32 + longProofOffset; - uint shortProof_i = 32; - bool foundConvergence; - for (; longProof_i <= longProof.length; ) { - if (_areSiblings(longIndex, shortIndex)) { - foundConvergence = true; - assembly { - mstore(add(longProof, longProof_i), mload(curShortHash)) - mstore(add(shortProof, shortProof_i), mload(curLongHash)) - } - - break; - } - - // Compute next hash for longProof - { - if (longIndex % 2 == 0) { - assembly { - mstore(0x00, mload(curLongHash)) - mstore(0x20, mload(add(longProof, longProof_i))) - } - } else { - assembly { - mstore(0x00, mload(add(longProof, longProof_i))) - mstore(0x20, mload(curLongHash)) - } - } - - // Compute hash and divide index - assembly { - if iszero(staticcall(sub(gas(), 2000), 2, 0x00, 0x40, curLongHash, 0x20)) { - revert(0, 0) - } - longIndex := div(longIndex, 2) - } - } - - // Compute next hash for shortProof - { - if (shortIndex % 2 == 0) { - assembly { - mstore(0x00, mload(curShortHash)) - mstore(0x20, mload(add(shortProof, shortProof_i))) - } - } else { - assembly { - mstore(0x00, mload(add(shortProof, shortProof_i))) - mstore(0x20, mload(curShortHash)) - } - } - - // Compute hash and divide index - assembly { - if iszero(staticcall(sub(gas(), 2000), 2, 0x00, 0x40, curShortHash, 0x20)) { - revert(0, 0) - } - shortIndex := div(shortIndex, 2) - } + function _genBalanceProofs() internal { + mapping(uint40 => BalanceRootProof) storage brProofs = balanceRootProofs[curTimestamp]; + + // Calculate current balance proofs for each balance root + uint numBalanceRoots = _numBalanceRoots(); + for (uint i = 0; i < numBalanceRoots; i++) { + + bytes memory proof = new bytes(BALANCE_PROOF_LEN); + bytes32 balanceRoot = balances[uint40(i)]; + bytes32 curNode = balanceRoot; + + // Balance root leaf -> balances container root + uint depth = 0; + for (uint j = 0; j < 1 + BeaconChainProofs.BALANCE_TREE_HEIGHT; j++) { + bytes32 sibling = trees[curTimestamp].balancesTree.siblings[curNode]; + + // proof[j] = sibling; + assembly { + mstore( + add(proof, add(32, mul(32, j))), + sibling + ) } - longProof_i += 32; - shortProof_i += 32; + curNode = trees[curTimestamp].balancesTree.parents[curNode]; + depth++; } - require(foundConvergence, "proofs did not converge!"); + brProofs[uint40(i)].balanceRoot = balanceRoot; + brProofs[uint40(i)].proof = proof; } } - /** - * PROOF LENGTHS, MISC CONSTANTS, AND OTHER HELPERS: - */ + function _getValidatorLeaves() internal view returns (bytes32[] memory) { + bytes32[] memory leaves = new bytes32[](validators.length); + + // Place each validator's validatorFields into tree + for (uint i = 0; i < validators.length; i++) { + leaves[i] = Merkle.merkleizeSha256( + _getValidatorFields(uint40(i)) + ); + } - uint immutable BLOCKROOT_PROOF_LEN = 32 * BeaconChainProofs.BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT; - uint immutable VAL_FIELDS_PROOF_LEN = 32 * ( - (BeaconChainProofs.VALIDATOR_TREE_HEIGHT + 1) + BeaconChainProofs.BEACON_STATE_FIELD_TREE_HEIGHT - ); + return leaves; + } - uint immutable WITHDRAWAL_PROOF_LEN_CAPELLA = 32 * ( - BeaconChainProofs.EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_CAPELLA + - BeaconChainProofs.WITHDRAWALS_TREE_HEIGHT + 1 - ); + function _getBalanceLeaves() internal view returns (bytes32[] memory) { + // Place each validator's current balance into tree + bytes32[] memory leaves = new bytes32[](_numBalanceRoots()); + for (uint i = 0; i < leaves.length; i++) { + leaves[i] = balances[uint40(i)]; + } - uint immutable WITHDRAWAL_PROOF_LEN_DENEB= 32 * ( - BeaconChainProofs.EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_DENEB + - BeaconChainProofs.WITHDRAWALS_TREE_HEIGHT + 1 - ); + return leaves; + } - uint immutable EXECPAYLOAD_PROOF_LEN = 32 * ( - BeaconChainProofs.BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT + - BeaconChainProofs.BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT - ); - uint immutable SLOT_PROOF_LEN = 32 * ( - BeaconChainProofs.BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT - ); - uint immutable TIMESTAMP_PROOF_LEN_CAPELLA = 32 * ( - BeaconChainProofs.EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_CAPELLA - ); - uint immutable TIMESTAMP_PROOF_LEN_DENEB = 32 * ( - BeaconChainProofs.EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_DENEB - ); - uint immutable HISTSUMMARY_PROOF_LEN = 32 * ( - BeaconChainProofs.BEACON_STATE_FIELD_TREE_HEIGHT + - BeaconChainProofs.HISTORICAL_SUMMARIES_TREE_HEIGHT + - BeaconChainProofs.BLOCK_ROOTS_TREE_HEIGHT + 2 - ); + function _numBalanceRoots() internal view returns (uint) { + // Each balance leaf is shared by 4 validators. This uses div_ceil + // to calculate the number of balance leaves + return (validators.length == 0) ? + 0 : ((validators.length - 1) / 4) + 1; + } - uint immutable HIST_SUMMARIES_PROOF_INDEX = BeaconChainProofs.HISTORICAL_SUMMARIES_INDEX << ( - BeaconChainProofs.HISTORICAL_SUMMARIES_TREE_HEIGHT + 1 + - BeaconChainProofs.BLOCK_ROOTS_TREE_HEIGHT + 1 - ); + function _getBeaconStateLeaves(bytes32 validatorsRoot, bytes32 balancesRoot) internal pure returns (bytes32[] memory) { + bytes32[] memory leaves = new bytes32[](BEACON_STATE_FIELDS); - function _initWithdrawalProof( - uint64 withdrawalEpoch, - uint64 withdrawalIndex, - uint64 oracleTimestamp - ) internal view returns (BeaconChainProofs.WithdrawalProof memory) { - uint256 withdrawalProofLength; - uint256 timestampProofLength; - if (block.timestamp > eigenPodManager.denebForkTimestamp()) { - withdrawalProofLength = WITHDRAWAL_PROOF_LEN_DENEB; - timestampProofLength = TIMESTAMP_PROOF_LEN_DENEB; - } else { - withdrawalProofLength = WITHDRAWAL_PROOF_LEN_CAPELLA; - timestampProofLength = TIMESTAMP_PROOF_LEN_CAPELLA; + // Pre-populate leaves with dummy values so sibling/parent tracking is correct + for (uint i = 0; i < leaves.length; i++) { + leaves[i] = bytes32(i + 1); } - return BeaconChainProofs.WithdrawalProof({ - withdrawalProof: new bytes(withdrawalProofLength), - slotProof: new bytes(SLOT_PROOF_LEN), - executionPayloadProof: new bytes(EXECPAYLOAD_PROOF_LEN), - timestampProof: new bytes(timestampProofLength), - historicalSummaryBlockRootProof: new bytes(HISTSUMMARY_PROOF_LEN), - blockRootIndex: 0, - historicalSummaryIndex: 0, - withdrawalIndex: withdrawalIndex, - blockRoot: bytes32(0), - slotRoot: _toLittleEndianUint64(withdrawalEpoch * BeaconChainProofs.SLOTS_PER_EPOCH), - timestampRoot: _toLittleEndianUint64(oracleTimestamp), - executionPayloadRoot: bytes32(0) - }); + + // Place validatorsRoot and balancesRoot into tree + leaves[BeaconChainProofs.VALIDATOR_CONTAINER_INDEX] = validatorsRoot; + leaves[BeaconChainProofs.BALANCE_CONTAINER_INDEX] = balancesRoot; + return leaves; } - function _calcBlockHeaderIndex(BeaconChainProofs.WithdrawalProof memory withdrawalProof) internal view returns (uint) { - return - HIST_SUMMARIES_PROOF_INDEX | - (uint(withdrawalProof.historicalSummaryIndex) << (BeaconChainProofs.BLOCK_ROOTS_TREE_HEIGHT + 1)) | - (BeaconChainProofs.BLOCK_SUMMARY_ROOT_INDEX << BeaconChainProofs.BLOCK_ROOTS_TREE_HEIGHT) | - uint(withdrawalProof.blockRootIndex); + function _getBeaconBlockLeaves(bytes32 beaconStateRoot) internal pure returns (bytes32[] memory) { + bytes32[] memory leaves = new bytes32[](BEACON_BLOCK_FIELDS); + + // Pre-populate leaves with dummy values so sibling/parent tracking is correct + for (uint i = 0; i < leaves.length; i++) { + leaves[i] = bytes32(i + 1); + } + + // Place beaconStateRoot into tree + leaves[BeaconChainProofs.STATE_ROOT_INDEX] = beaconStateRoot; + return leaves; + } + + function _currentBalanceGwei(uint40 validatorIndex) internal view returns (uint64) { + return currentBalance(validatorIndex); + } + + function currentEpoch() public view returns (uint64) { + require(block.timestamp >= genesisTime, "BeaconChain.currentEpoch: current time is before genesis time"); + return uint64((block.timestamp - genesisTime) / BeaconChainProofs.SECONDS_PER_EPOCH); + } + + /// @dev Returns the validator's exit epoch + function exitEpoch(uint40 validatorIndex) public view returns (uint64) { + return validators[validatorIndex].exitEpoch; + } + + function totalEffectiveBalanceWei(uint40[] memory validatorIndices) public view returns (uint) { + uint total; + for (uint i = 0; i < validatorIndices.length; i++) { + total += uint(validators[validatorIndices[i]].effectiveBalanceGwei * GWEI_TO_WEI); + } + + return total; + } + + /// @dev Returns the validator's effective balance, in gwei + function effectiveBalance(uint40 validatorIndex) public view returns (uint64) { + return validators[validatorIndex].effectiveBalanceGwei; + } + + /// @dev Returns the validator's current balance, in gwei + function currentBalance(uint40 validatorIndex) public view returns (uint64) { + return BeaconChainProofs.getBalanceAtIndex( + getBalanceRoot(validatorIndex), + validatorIndex + ); + } + + function getBalanceRoot(uint40 validatorIndex) public view returns (bytes32) { + return balances[validatorIndex / 4]; + } + + function _getBalanceRootIndex(uint40 validatorIndex) internal pure returns (uint40) { + return validatorIndex / 4; + } + + function _getValidatorFields(uint40 validatorIndex) internal view returns (bytes32[] memory) { + bytes32[] memory vFields = new bytes32[](8); + Validator memory v = validators[validatorIndex]; + + vFields[BeaconChainProofs.VALIDATOR_PUBKEY_INDEX] = v.pubkeyHash; + vFields[BeaconChainProofs.VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX] = bytes32(v.withdrawalCreds); + vFields[BeaconChainProofs.VALIDATOR_BALANCE_INDEX] = _toLittleEndianUint64(v.effectiveBalanceGwei); + vFields[BeaconChainProofs.VALIDATOR_SLASHED_INDEX] = bytes32(abi.encode(v.isSlashed)); + vFields[BeaconChainProofs.VALIDATOR_ACTIVATION_EPOCH_INDEX] = _toLittleEndianUint64(v.activationEpoch); + vFields[BeaconChainProofs.VALIDATOR_EXIT_EPOCH_INDEX] = _toLittleEndianUint64(v.exitEpoch); + + return vFields; + } + + /// @dev Update the validator's current balance + function _setCurrentBalance(uint40 validatorIndex, uint64 newBalanceGwei) internal { + bytes32 balanceRoot = balances[validatorIndex / 4]; + balanceRoot = _calcBalanceRoot(balanceRoot, validatorIndex, newBalanceGwei); + + balances[validatorIndex / 4] = balanceRoot; + } + + /// From EigenPod.sol + function _nextEpochStartTimestamp(uint64 epoch) internal view returns (uint64) { + return + genesisTime + ((1 + epoch) * BeaconChainProofs.SECONDS_PER_EPOCH); } function _calcValProofIndex(uint40 validatorIndex) internal pure returns (uint) { return - (BeaconChainProofs.VALIDATOR_TREE_ROOT_INDEX << (BeaconChainProofs.VALIDATOR_TREE_HEIGHT + 1)) | + (BeaconChainProofs.VALIDATOR_CONTAINER_INDEX << (BeaconChainProofs.VALIDATOR_TREE_HEIGHT + 1)) | uint(validatorIndex); } - /// @dev Returns true if a and b are sibling indices in the same sub-tree. - /// - /// i.e. the indices belong two child nodes that share a parent: - /// [A, B] or [B, A] - function _areSiblings(uint a, uint b) internal pure returns (bool) { - return - (a % 2 == 0 && b == a + 1) || (b % 2 == 0 && a == b + 1); + function _calcBalanceProofIndex(uint40 balanceRootIndex) internal pure returns (uint) { + return + (BeaconChainProofs.BALANCE_CONTAINER_INDEX << (BeaconChainProofs.BALANCE_TREE_HEIGHT + 1)) | + uint(balanceRootIndex); + } + + function _getZeroNode(uint depth) internal view returns (bytes32) { + require(depth < ZERO_NODES_LENGTH, "_getZeroNode: invalid depth"); + + return zeroNodes[depth]; } /// @dev Opposite of Endian.fromLittleEndianUint64 @@ -807,6 +877,22 @@ contract BeaconChainMock is Test { return bytes32(lenum << 192); } + /// @dev Opposite of BeaconChainProofs.getBalanceAtIndex, calculates a new balance + /// root by updating the balance at validatorIndex + /// @return The new, updated balance root + function _calcBalanceRoot(bytes32 balanceRoot, uint40 validatorIndex, uint64 newBalanceGwei) internal pure returns (bytes32) { + // Clear out old balance + uint bitShiftAmount = 256 - (64 * ((validatorIndex % 4) + 1)); + uint mask = ~(uint(0xFFFFFFFFFFFFFFFF) << bitShiftAmount); + uint clearedRoot = uint(balanceRoot) & mask; + + // Convert validator balance to little endian and shift to correct position + uint leBalance = uint(_toLittleEndianUint64(newBalanceGwei)); + uint shiftedBalance = leBalance >> (192 - bitShiftAmount); + + return bytes32(clearedRoot | shiftedBalance); + } + /// @dev Helper to convert 32-byte withdrawal credentials to an address function _toAddress(bytes memory withdrawalCreds) internal pure returns (address a) { bytes32 creds = bytes32(withdrawalCreds); @@ -814,4 +900,108 @@ contract BeaconChainMock is Test { assembly { a := and(creds, mask) } } + + /******************************************************************************* + VIEW METHODS + *******************************************************************************/ + + function getCredentialProofs(uint40[] memory _validators) public view returns (CredentialProofs memory) { + // If we have not advanced an epoch since a validator was created, no proofs have been + // generated for that validator. We check this here and revert early so we don't return + // empty proofs. + for (uint i = 0; i < _validators.length; i++) { + require( + _validators[i] <= lastIndexProcessed, + "BeaconChain.getCredentialProofs: validator has not been included in beacon chain state (DID YOU CALL advanceEpoch YET?)" + ); + } + + CredentialProofs memory proofs = CredentialProofs({ + beaconTimestamp: curTimestamp, + stateRootProof: stateRootProofs[curTimestamp], + validatorFieldsProofs: new bytes[](_validators.length), + validatorFields: new bytes32[][](_validators.length) + }); + + // Get proofs for each validator + for (uint i = 0; i < _validators.length; i++) { + ValidatorFieldsProof memory proof = validatorFieldsProofs[curTimestamp][_validators[i]]; + proofs.validatorFieldsProofs[i] = proof.validatorFieldsProof; + proofs.validatorFields[i] = proof.validatorFields; + } + + return proofs; + } + + function getCheckpointProofs(uint40[] memory _validators, uint64 timestamp) public view returns (CheckpointProofs memory) { + // If we have not advanced an epoch since a validator was created, no proofs have been + // generated for that validator. We check this here and revert early so we don't return + // empty proofs. + for (uint i = 0; i < _validators.length; i++) { + require( + _validators[i] <= lastIndexProcessed, + "BeaconChain.getCredentialProofs: no checkpoint proof found (did you call advanceEpoch yet?)" + ); + } + + CheckpointProofs memory proofs = CheckpointProofs({ + balanceContainerProof: balanceContainerProofs[timestamp], + balanceProofs: new BeaconChainProofs.BalanceProof[](_validators.length) + }); + + // Get proofs for each validator + for (uint i = 0; i < _validators.length; i++) { + uint40 validatorIndex = _validators[i]; + uint40 balanceRootIndex = _getBalanceRootIndex(validatorIndex); + BalanceRootProof memory proof = balanceRootProofs[timestamp][balanceRootIndex]; + + proofs.balanceProofs[i] = BeaconChainProofs.BalanceProof({ + pubkeyHash: validators[validatorIndex].pubkeyHash, + balanceRoot: proof.balanceRoot, + proof: proof.proof + }); + } + + return proofs; + } + + function getStaleBalanceProofs(uint40 validatorIndex) public view returns (StaleBalanceProofs memory) { + ValidatorFieldsProof memory vfProof = validatorFieldsProofs[curTimestamp][validatorIndex]; + return StaleBalanceProofs({ + beaconTimestamp: curTimestamp, + stateRootProof: stateRootProofs[curTimestamp], + validatorProof: BeaconChainProofs.ValidatorProof({ + validatorFields: vfProof.validatorFields, + proof: vfProof.validatorFieldsProof + }) + }); + } + + function balanceOfGwei(uint40 validatorIndex) public view returns (uint64) { + return validators[validatorIndex].effectiveBalanceGwei; + } + + function pubkeyHash(uint40 validatorIndex) public view returns (bytes32) { + return validators[validatorIndex].pubkeyHash; + } + + function pubkey(uint40 validatorIndex) public pure returns (bytes memory) { + bytes memory _pubkey = new bytes(48); + assembly { mstore(add(48, _pubkey), validatorIndex) } + return _pubkey; + } + + function getPubkeyHashes(uint40[] memory _validators) public view returns (bytes32[] memory) { + bytes32[] memory pubkeyHashes = new bytes32[](_validators.length); + + for (uint i = 0; i < _validators.length; i++) { + pubkeyHashes[i] = validators[_validators[i]].pubkeyHash; + } + + return pubkeyHashes; + } + + function isActive(uint40 validatorIndex) public view returns (bool) { + return validators[validatorIndex].exitEpoch == BeaconChainProofs.FAR_FUTURE_EPOCH; + } } diff --git a/src/test/integration/mocks/BeaconChainOracleMock.t.sol b/src/test/integration/mocks/BeaconChainOracleMock.t.sol deleted file mode 100644 index b5a401c1f..000000000 --- a/src/test/integration/mocks/BeaconChainOracleMock.t.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.12; - -import "src/contracts/interfaces/IBeaconChainOracle.sol"; - -contract BeaconChainOracleMock is IBeaconChainOracle { - - mapping(uint64 => bytes32) blockRoots; - - function timestampToBlockRoot(uint timestamp) public view returns (bytes32) { - return blockRoots[uint64(timestamp)]; - } - - function setBlockRoot(uint64 timestamp, bytes32 blockRoot) public { - blockRoots[timestamp] = blockRoot; - } -} diff --git a/src/test/integration/mocks/EIP_4788_Oracle_Mock.t.sol b/src/test/integration/mocks/EIP_4788_Oracle_Mock.t.sol new file mode 100644 index 000000000..b83aac72a --- /dev/null +++ b/src/test/integration/mocks/EIP_4788_Oracle_Mock.t.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +contract EIP_4788_Oracle_Mock { + + mapping(uint => bytes32) blockRoots; + + uint constant HISTORY_BUFFER_LENGTH = 8191; + + fallback() external { + require(msg.data.length == 32, "4788OracleMock.fallback: malformed msg.data"); + + uint timestamp = abi.decode(msg.data, (uint)); + require(timestamp != 0, "4788OracleMock.fallback: timestamp is 0"); + + bytes32 blockRoot = blockRoots[timestamp]; + require(blockRoot != 0, "4788OracleMock.fallback: no block root found. DID YOU USE CHEATS.WARP?"); + + assembly { + mstore(0, blockRoot) + return(0, 32) + } + } + + function timestampToBlockRoot(uint timestamp) public view returns (bytes32) { + return blockRoots[uint64(timestamp)]; + } + + function setBlockRoot(uint64 timestamp, bytes32 blockRoot) public { + blockRoots[timestamp] = blockRoot; + } +} diff --git a/src/test/integration/tests/Upgrade_Setup.t.sol b/src/test/integration/tests/Upgrade_Setup.t.sol index b1b2f2edd..cbfb4eb45 100644 --- a/src/test/integration/tests/Upgrade_Setup.t.sol +++ b/src/test/integration/tests/Upgrade_Setup.t.sol @@ -101,10 +101,5 @@ contract IntegrationMainnetFork_UpgradeSetup is IntegrationCheckUtils { eigenPodManager.delegationManager() == delegationManager, "eigenPodManager: delegationManager contract address not set correctly" ); - // DelayedWithdrawalRouter - require( - delayedWithdrawalRouter.eigenPodManager() == eigenPodManager, - "delayedWithdrawalRouterContract: eigenPodManager address not set correctly" - ); } } \ No newline at end of file diff --git a/src/test/integration/tests/eigenpod/VerifyWC_StartCP_CompleteCP.t.sol b/src/test/integration/tests/eigenpod/VerifyWC_StartCP_CompleteCP.t.sol new file mode 100644 index 000000000..fd641bab2 --- /dev/null +++ b/src/test/integration/tests/eigenpod/VerifyWC_StartCP_CompleteCP.t.sol @@ -0,0 +1,756 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "src/test/integration/IntegrationChecks.t.sol"; +import "src/test/integration/users/User.t.sol"; + +contract Integration_VerifyWC_StartCP_CompleteCP is IntegrationCheckUtils { + + modifier r(uint24 _rand) { + _configRand({ + _randomSeed: _rand, + _assetTypes: HOLDS_ETH, + _userTypes: DEFAULT + }); + + _; + } + + function test_GasMetering() public r(0) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + // Deal user 20 full stakers worth of ETH + emit log_named_string("Dealing 20 * 32 ETH to", staker.NAME()); + cheats.deal(address(staker), 32 ether * 20); + cheats.pauseGasMetering(); + + (uint40[] memory validators, ) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + EigenPod pod = staker.pod(); + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); + + cheats.startPrank(address(staker)); + cheats.resumeGasMetering(); + + uint startGas = gasleft(); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); + uint endGas = gasleft(); + cheats.pauseGasMetering(); + uint totalGas = startGas - endGas; + emit log_named_uint("== num validators", validators.length); + emit log_named_uint("== verifyWC gas", totalGas); + + // check_VerifyWC_State(staker, validators, beaconBalanceWei); + + beaconChain.advanceEpoch(); + // check pod balances have increased + + staker.startCheckpoint(); + // check_StartCheckpoint_State(staker); + + CheckpointProofs memory cpProofs = beaconChain.getCheckpointProofs(validators, pod.currentCheckpointTimestamp()); + + cheats.resumeGasMetering(); + startGas = gasleft(); + pod.verifyCheckpointProofs({ + balanceContainerProof: cpProofs.balanceContainerProof, + proofs: cpProofs.balanceProofs + }); + endGas = gasleft(); + cheats.pauseGasMetering(); + totalGas = startGas - endGas; + emit log_named_uint("== checkpoint gas", totalGas); + + // check_CompleteCheckpoint_State(staker); + // revert(); + } + + /******************************************************************************* + VERIFY -> START -> COMPLETE CHECKPOINT + (TIMING VARIANTS) + *******************************************************************************/ + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + function test_VerifyWC_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_State(staker); + } + + /// 1. Verify validators' withdrawal credentials + /// 2. Verify validators' withdrawal credentials again + /// => This should fail + function test_VerifyWC_VerifyWC_Fails(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + cheats.expectRevert("EigenPod._verifyWithdrawalCredentials: validator must be inactive to prove withdrawal credentials"); + staker.verifyWithdrawalCredentials(validators); + } + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// 3. start a checkpoint again + /// => This should fail + function test_VerifyWC_StartCP_StartCP_Fails(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + cheats.expectRevert("EigenPod._startCheckpoint: must finish previous checkpoint before starting another"); + staker.startCheckpoint(); + } + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// 4. start a checkpoint without advancing a block + /// => this should fail + function test_VerifyWC_StartCP_CompleteCP_StartCP_Fails(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_State(staker); + + cheats.expectRevert("EigenPod._startCheckpoint: cannot checkpoint twice in one block"); + staker.startCheckpoint(); + } + + /// 1. Verify validators' withdrawal credentials + /// -- move forward 1 or more epochs + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + function test_VerifyWC_Advance_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + // Advance epoch without generating consensus rewards + beaconChain.advanceEpoch_NoRewards(); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_State(staker); + } + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// -- move forward 1 or more epochs + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + function test_VerifyWC_StartCP_Advance_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + // Advance epoch without generating consensus rewards + beaconChain.advanceEpoch_NoRewards(); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_State(staker); + } + + /******************************************************************************* + VERIFY -> START -> COMPLETE CHECKPOINT + (EXIT TO POD VARIANTS) + *******************************************************************************/ + + /// -- Fully exit validators before verifying withdrawal credentials + /// 1. Verify validators' withdrawal credentials + /// => This should fail + function test_ExitValidators_VerifyWC_Fails(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, ) = staker.startValidators(); + staker.exitValidators(validators); + beaconChain.advanceEpoch_NoRewards(); + + cheats.expectRevert("EigenPod._verifyWithdrawalCredentials: validator must not be exiting"); + staker.verifyWithdrawalCredentials(validators); + } + + /// 1. Verify validators' withdrawal credentials + /// -- fully exit validators to pod + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + function test_VerifyWC_ExitValidators_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + // Fully exit one or more validators and advance epoch without generating rewards + uint40[] memory subset = _choose(validators); + uint64 exitedBalanceGwei = staker.exitValidators(subset); + beaconChain.advanceEpoch_NoRewards(); + + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, exitedBalanceGwei); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithExits_State(staker, subset, exitedBalanceGwei); + } + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// -- fully exit validators to pod + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + /// -- move forward an epoch + /// 4. start a checkpoint + /// 5. complete a checkpoint + /// => exited balance should be reflected in 4 and 5 + function test_VerifyWC_StartCP_ExitValidators_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + // Fully exit one or more validators and advance epoch without generating rewards + uint40[] memory subset = _choose(validators); + uint64 exitedBalanceGwei = staker.exitValidators(subset); + beaconChain.advanceEpoch_NoRewards(); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_State(staker); + + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, exitedBalanceGwei); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithExits_State(staker, subset, exitedBalanceGwei); + } + + /******************************************************************************* + VERIFY -> START -> COMPLETE CHECKPOINT + (SLASH TO POD VARIANTS) + *******************************************************************************/ + + /// -- get slashed on beacon chain + /// 1. Try to verify validators' withdrawal credentials + /// => this should fail + function test_SlashToPod_VerifyWC_Fails(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, ) = staker.startValidators(); + beaconChain.slashValidators(validators); + // Advance epoch, withdrawing slashed validators to pod + beaconChain.advanceEpoch_NoRewards(); + + cheats.expectRevert("EigenPod._verifyWithdrawalCredentials: validator must not be exiting"); + staker.verifyWithdrawalCredentials(validators); + } + + /// 1. Verify validators' withdrawal credentials + /// -- get slashed on beacon chain; exit to pod + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => after 3, shares should decrease by slashed amount + function test_VerifyWC_SlashToPod_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + // Advance epoch without generating rewards + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + uint64 slashedBalanceGwei = beaconChain.slashValidators(validators); + beaconChain.advanceEpoch_NoRewards(); + + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, beaconBalanceGwei - slashedBalanceGwei); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithSlashing_State(staker, validators, slashedBalanceGwei); + } + + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// -- get slashed on beacon chain; exit to pod + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + /// -- move forward an epoch + /// 4. start a checkpoint + /// 5. complete a checkpoint + /// => slashed balance should be reflected in 4 and 5 + function test_VerifyWC_StartCP_SlashToPod_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + // Advance epoch without generating rewards + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + uint64 slashedBalanceGwei = beaconChain.slashValidators(validators); + beaconChain.advanceEpoch_NoRewards(); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_State(staker); + + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, beaconBalanceGwei - slashedBalanceGwei); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithSlashing_State(staker, validators, slashedBalanceGwei); + } + + /******************************************************************************* + VERIFY -> PROVE STALE BALANCE -> COMPLETE CHECKPOINT + *******************************************************************************/ + + /// 1. Verify validators' withdrawal credentials + /// -- get slashed on beacon chain; exit to pod + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => after 3, shares should decrease by slashed amount + function test_VerifyWC_SlashToPod_VerifyStale_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + // Advance epoch without generating rewards + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + uint64 slashedBalanceGwei = beaconChain.slashValidators(validators); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyStaleBalance(validators[0]); + check_StartCheckpoint_WithPodBalance_State(staker, beaconBalanceGwei - slashedBalanceGwei); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithSlashing_State(staker, validators, slashedBalanceGwei); + } + + /// 1. Verify validators' withdrawal credentials + /// -- get slashed on beacon chain; do not exit to pod + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => after 3, shares should decrease by slashed amount + function test_VerifyWC_SlashToCL_VerifyStale_CompleteCP_SlashAgain(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + // Advance epoch without generating rewards + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + // Slash validators but do not process exits to pod + uint64 slashedBalanceGwei = beaconChain.slashValidators(validators); + beaconChain.advanceEpoch_NoWithdraw(); + + staker.verifyStaleBalance(validators[0]); + check_StartCheckpoint_WithPodBalance_State(staker, 0); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithCLSlashing_State(staker, slashedBalanceGwei); + + // Slash validators again but do not process exits to pod + uint64 secondSlashedBalanceGwei = beaconChain.slashValidators(validators); + beaconChain.advanceEpoch_NoWithdraw(); + + staker.verifyStaleBalance(validators[0]); + check_StartCheckpoint_WithPodBalance_State(staker, 0); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithCLSlashing_State(staker, secondSlashedBalanceGwei); + } + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// -- get slashed on beacon chain; exit to pod + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + /// -- move forward an epoch + /// 4. start a checkpoint + /// 5. complete a checkpoint + /// => slashed balance should be reflected in 4 and 5 + function test_VerifyWC_StartCP_SlashToPod_CompleteCP_VerifyStale(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + // Advance epoch without generating rewards + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + uint64 slashedBalanceGwei = beaconChain.slashValidators(validators); + beaconChain.advanceEpoch_NoRewards(); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_State(staker); + + staker.verifyStaleBalance(validators[0]); + check_StartCheckpoint_WithPodBalance_State(staker, beaconBalanceGwei - slashedBalanceGwei); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithSlashing_State(staker, validators, slashedBalanceGwei); + } + + /******************************************************************************* + VERIFY -> START -> COMPLETE CHECKPOINT + (EARN ON CL VARIANTS) + *******************************************************************************/ + + /// -- earn rewards on beacon chain (not withdrawn to pod) + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => after 3, shares increase by rewards earned on beacon chain + function test_EarnOnBeacon_VerifyWC_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + // Advance epoch and generate consensus rewards, but don't withdraw to pod + beaconChain.advanceEpoch_NoWithdraw(); + uint64 beaconBalanceIncreaseGwei = uint64(validators.length) * beaconChain.CONSENSUS_REWARD_AMOUNT_GWEI(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_EarnOnBeacon_State(staker, beaconBalanceIncreaseGwei); + } + + /// 1. Verify validators' withdrawal credentials + /// -- earn rewards on beacon chain (not withdrawn to pod) + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => after 3, shares increase by rewards earned on beacon chain + function test_VerifyWC_EarnOnBeacon_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + // Advance epoch and generate consensus rewards, but don't withdraw to pod + beaconChain.advanceEpoch_NoWithdraw(); + uint64 beaconBalanceIncreaseGwei = uint64(validators.length) * beaconChain.CONSENSUS_REWARD_AMOUNT_GWEI(); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_EarnOnBeacon_State(staker, beaconBalanceIncreaseGwei); + } + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// -- earn rewards on beacon chain (not withdrawn to pod) + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + function test_VerifyWC_StartCP_EarnOnBeacon_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + + // Advance epoch and generate consensus rewards, but don't withdraw to pod + beaconChain.advanceEpoch_NoWithdraw(); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_EarnOnBeacon_State(staker, 0); + } + + /******************************************************************************* + VERIFY -> START -> COMPLETE CHECKPOINT + (EARN TO POD VARIANTS) + *******************************************************************************/ + + /// -- earn rewards on beacon chain (withdrawn to pod) + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => after 3, shares increase by rewards withdrawn to pod + function test_EarnToPod_VerifyWC_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + // Advance epoch, generating consensus rewards and withdrawing anything over 32 ETH + beaconChain.advanceEpoch(); + uint64 expectedWithdrawnGwei = uint64(validators.length) * beaconChain.CONSENSUS_REWARD_AMOUNT_GWEI(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, expectedWithdrawnGwei); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithPodBalance_State(staker, expectedWithdrawnGwei); + } + + /// 1. Verify validators' withdrawal credentials + /// -- earn rewards on beacon chain (withdrawn to pod) + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => after 3, shares increase by rewards withdrawn to pod + function test_VerifyWC_EarnToPod_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + // Advance epoch, generating consensus rewards and withdrawing anything over 32 ETH + beaconChain.advanceEpoch(); + uint64 expectedWithdrawnGwei = uint64(validators.length) * beaconChain.CONSENSUS_REWARD_AMOUNT_GWEI(); + + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, expectedWithdrawnGwei); + + staker.completeCheckpoint(); + check_CompleteCheckpoint_WithPodBalance_State(staker, expectedWithdrawnGwei); + } + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// -- earn rewards on beacon chain (withdrawn to pod) + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + function test_VerifyWC_StartCP_EarnToPod_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + beaconChain.advanceEpoch_NoRewards(); + + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, 0); + + // Advance epoch, generating consensus rewards and withdrawing anything over 32 ETH + beaconChain.advanceEpoch(); + uint64 expectedWithdrawnGwei = uint64(validators.length) * beaconChain.CONSENSUS_REWARD_AMOUNT_GWEI(); + + staker.completeCheckpoint(); + // `pod.balance == gweiSent + remainderSent + assert_PodBalance_Eq(staker, (expectedWithdrawnGwei * GWEI_TO_WEI), "pod balance should equal expected"); + check_CompleteCheckpoint_WithPodBalance_State(staker, 0); + } + + /******************************************************************************* + VERIFY -> START -> COMPLETE CHECKPOINT + (NATIVE ETH VARIANTS) + *******************************************************************************/ + + /// -- Pod receives native ETH via fallback + /// 1. start a checkpoint + /// => checkpoint should auto-complete, awarding shares for ETH in pod + function test_NativeETH_StartCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + // Send a random amount of ETH to staker's fallback + (uint64 gweiSent, ) = _sendRandomETH(address(staker.pod())); + + // Move forward an epoch so we generate a state root that can be queried in startCheckpoint + beaconChain.advanceEpoch(); + + // should behave identically to partial withdrawals captured by the "earn to pod" variants + staker.startCheckpoint(); + check_StartCheckpoint_NoValidators_State(staker, gweiSent); + } + + /// -- Pod receives native ETH via fallback + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => after 3, shares should account for native ETH + function test_NativeETH_VerifyWC_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + // Send a random amount of ETH to staker's fallback + (uint64 gweiSent, uint remainderSent) = _sendRandomETH(address(staker.pod())); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + // should behave identically to partial withdrawals captured by the "earn to pod" variants + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, gweiSent); + + staker.completeCheckpoint(); + // check that `pod.balance == withdrawableRestakedExecutionLayerGwei + remainderSent + assert_PodBalance_Eq(staker, (gweiSent * GWEI_TO_WEI) + remainderSent, "pod balance should equal expected"); + check_CompleteCheckpoint_WithPodBalance_State(staker, gweiSent); + } + + /// 1. Verify validators' withdrawal credentials + /// -- Pod receives native ETH via fallback + /// 2. start a checkpoint + /// 3. complete a checkpoint + /// => after 3, shares should account for native ETH + function test_VerifyWC_NativeETH_StartCP_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + // Send a random amount of ETH to staker's fallback + (uint64 gweiSent, uint remainderSent) = _sendRandomETH(address(staker.pod())); + + // should behave identically to partial withdrawals captured by the "earn to pod" variants + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, gweiSent); + + staker.completeCheckpoint(); + // check that `pod.balance == withdrawableRestakedExecutionLayerGwei + remainderSent + assert_PodBalance_Eq(staker, (gweiSent * GWEI_TO_WEI) + remainderSent, "pod balance should equal expected"); + check_CompleteCheckpoint_WithPodBalance_State(staker, gweiSent); + } + + /// 1. Verify validators' withdrawal credentials + /// 2. start a checkpoint + /// -- Pod receives native ETH via fallback + /// 3. complete a checkpoint + /// => no change in shares between 1 and 3 + function test_VerifyWC_StartCP_NativeETH_CompleteCP(uint24 _rand) public r(_rand) { + (User staker, ,) = _newRandomStaker(); + _upgradeEigenLayerContracts(); + + (uint40[] memory validators, uint64 beaconBalanceGwei) = staker.startValidators(); + beaconChain.advanceEpoch_NoRewards(); + + staker.verifyWithdrawalCredentials(validators); + check_VerifyWC_State(staker, validators, beaconBalanceGwei); + + // should behave identically to partial withdrawals captured by the "earn to pod" variants + // ... if we didn't have any partial withdrawals! + staker.startCheckpoint(); + check_StartCheckpoint_WithPodBalance_State(staker, 0); + + // Send a random amount of ETH to staker's fallback + (uint64 gweiSent, uint remainderSent) = _sendRandomETH(address(staker.pod())); + + staker.completeCheckpoint(); + // `pod.balance == gweiSent + remainderSent + assert_PodBalance_Eq(staker, (gweiSent * GWEI_TO_WEI) + remainderSent, "pod balance should equal expected"); + check_CompleteCheckpoint_WithPodBalance_State(staker, 0); + } +} \ No newline at end of file diff --git a/src/test/integration/users/User.t.sol b/src/test/integration/users/User.t.sol index ca304c844..7875e56c6 100644 --- a/src/test/integration/users/User.t.sol +++ b/src/test/integration/users/User.t.sol @@ -13,8 +13,11 @@ import "src/contracts/interfaces/IStrategy.sol"; import "src/test/integration/TimeMachine.t.sol"; import "src/test/integration/mocks/BeaconChainMock.t.sol"; -import "src/test/integration/mocks/BeaconChainOracleMock.t.sol"; +import "src/test/integration/utils/PrintUtils.t.sol"; +struct Validator { + uint40 index; +} interface IUserDeployer { function delegationManager() external view returns (DelegationManager); @@ -22,23 +25,20 @@ interface IUserDeployer { function eigenPodManager() external view returns (EigenPodManager); function timeMachine() external view returns (TimeMachine); function beaconChain() external view returns (BeaconChainMock); - function beaconChainOracle() external view returns (address); } -contract User is Test { +contract User is PrintUtils { Vm cheats = Vm(HEVM_ADDRESS); DelegationManager delegationManager; StrategyManager strategyManager; EigenPodManager eigenPodManager; - TimeMachine timeMachine; + BeaconChainMock beaconChain; - /// @dev Native restaker state vars + string _NAME; - BeaconChainMock beaconChain; - BeaconChainOracleMock beaconChainOracle; // User's EigenPod and each of their validator indices within that pod EigenPod public pod; uint40[] validators; @@ -47,8 +47,6 @@ contract User is Test { IERC20 constant NATIVE_ETH = IERC20(0xbeaC0eeEeeeeEEeEeEEEEeeEEeEeeeEeeEEBEaC0); uint constant GWEI_TO_WEI = 1e9; - string public NAME; - constructor(string memory name) { IUserDeployer deployer = IUserDeployer(msg.sender); @@ -58,10 +56,9 @@ contract User is Test { timeMachine = deployer.timeMachine(); beaconChain = deployer.beaconChain(); - beaconChainOracle = BeaconChainOracleMock(deployer.beaconChainOracle()); _createPod(); - NAME = name; + _NAME = name; } modifier createSnapshot() virtual { @@ -71,12 +68,16 @@ contract User is Test { receive() external payable {} - /** - * DelegationManager methods: - */ + function NAME() public view override returns (string memory) { + return _NAME; + } + + /******************************************************************************* + DELEGATIONMANAGER METHODS + *******************************************************************************/ function registerAsOperator() public createSnapshot virtual { - emit log(_name(".registerAsOperator")); + _logM("registerAsOperator"); IDelegationManager.OperatorDetails memory details = IDelegationManager.OperatorDetails({ __deprecated_earningsReceiver: address(this), @@ -87,86 +88,9 @@ contract User is Test { delegationManager.registerAsOperator(details, "metadata"); } - /// @dev For each strategy/token balance, call the relevant deposit method - function depositIntoEigenlayer(IStrategy[] memory strategies, uint[] memory tokenBalances) public createSnapshot virtual { - emit log(_name(".depositIntoEigenlayer")); - - for (uint i = 0; i < strategies.length; i++) { - IStrategy strat = strategies[i]; - uint tokenBalance = tokenBalances[i]; - - if (strat == BEACONCHAIN_ETH_STRAT) { - // We're depositing via `eigenPodManager.stake`, which only accepts - // deposits of exactly 32 ether. - require(tokenBalance % 32 ether == 0, "User.depositIntoEigenlayer: balance must be multiple of 32 eth"); - - // For each multiple of 32 ether, deploy a new validator to the same pod - uint numValidators = tokenBalance / 32 ether; - for (uint j = 0; j < numValidators; j++) { - eigenPodManager.stake{ value: 32 ether }("", "", bytes32(0)); - - (uint40 newValidatorIndex, CredentialsProofs memory proofs) = - beaconChain.newValidator({ - balanceWei: 32 ether, - withdrawalCreds: _podWithdrawalCredentials() - }); - - validators.push(newValidatorIndex); - emit log_named_uint("oracle timestamp", proofs.oracleTimestamp); - pod.verifyWithdrawalCredentials({ - oracleTimestamp: proofs.oracleTimestamp, - stateRootProof: proofs.stateRootProof, - validatorIndices: proofs.validatorIndices, - validatorFieldsProofs: proofs.validatorFieldsProofs, - validatorFields: proofs.validatorFields - }); - } - } else { - IERC20 underlyingToken = strat.underlyingToken(); - underlyingToken.approve(address(strategyManager), tokenBalance); - strategyManager.depositIntoStrategy(strat, underlyingToken, tokenBalance); - } - } - } - - function updateBalances(IStrategy[] memory strategies, int[] memory tokenDeltas) public createSnapshot virtual { - emit log(_name(".updateBalances")); - - for (uint i = 0; i < strategies.length; i++) { - IStrategy strat = strategies[i]; - int delta = tokenDeltas[i]; - - if (strat == BEACONCHAIN_ETH_STRAT) { - // TODO - right now, we just grab the first validator - uint40 validator = getUpdatableValidator(); - BalanceUpdate memory update = beaconChain.updateBalance(validator, delta); - - int sharesBefore = eigenPodManager.podOwnerShares(address(this)); - - pod.verifyBalanceUpdates({ - oracleTimestamp: update.oracleTimestamp, - validatorIndices: update.validatorIndices, - stateRootProof: update.stateRootProof, - validatorFieldsProofs: update.validatorFieldsProofs, - validatorFields: update.validatorFields - }); - - int sharesAfter = eigenPodManager.podOwnerShares(address(this)); - - emit log_named_int("pod owner shares before: ", sharesBefore); - emit log_named_int("pod owner shares after: ", sharesAfter); - } else { - uint tokens = uint(delta); - IERC20 underlyingToken = strat.underlyingToken(); - underlyingToken.approve(address(strategyManager), tokens); - strategyManager.depositIntoStrategy(strat, underlyingToken, tokens); - } - } - } - /// @dev Delegate to the operator without a signature function delegateTo(User operator) public createSnapshot virtual { - emit log_named_string(_name(".delegateTo: "), operator.NAME()); + _logM("delegateTo", operator.NAME()); ISignatureUtils.SignatureWithExpiry memory emptySig; delegationManager.delegateTo(address(operator), emptySig, bytes32(0)); @@ -174,7 +98,7 @@ contract User is Test { /// @dev Undelegate from operator function undelegate() public createSnapshot virtual returns(IDelegationManager.Withdrawal[] memory){ - emit log(_name(".undelegate")); + _logM("undelegate"); IDelegationManager.Withdrawal[] memory expectedWithdrawals = _getExpectedWithdrawalStructsForStaker(address(this)); delegationManager.undelegate(address(this)); @@ -191,7 +115,7 @@ contract User is Test { /// @dev Force undelegate staker function forceUndelegate(User staker) public createSnapshot virtual returns(IDelegationManager.Withdrawal[] memory){ - emit log_named_string(_name(".forceUndelegate: "), staker.NAME()); + _logM("forceUndelegate", staker.NAME()); IDelegationManager.Withdrawal[] memory expectedWithdrawals = _getExpectedWithdrawalStructsForStaker(address(staker)); delegationManager.undelegate(address(staker)); @@ -203,7 +127,7 @@ contract User is Test { IStrategy[] memory strategies, uint[] memory shares ) public createSnapshot virtual returns (IDelegationManager.Withdrawal[] memory) { - emit log(_name(".queueWithdrawals")); + _logM("queueWithdrawals"); address operator = delegationManager.delegatedTo(address(this)); address withdrawer = address(this); @@ -238,7 +162,7 @@ contract User is Test { } function completeWithdrawalsAsTokens(IDelegationManager.Withdrawal[] memory withdrawals) public createSnapshot virtual returns (IERC20[][] memory) { - emit log(_name(".completeWithdrawalsAsTokens")); + _logM("completeWithdrawalsAsTokens"); IERC20[][] memory tokens = new IERC20[][](withdrawals.length); @@ -250,13 +174,13 @@ contract User is Test { } function completeWithdrawalAsTokens(IDelegationManager.Withdrawal memory withdrawal) public createSnapshot virtual returns (IERC20[] memory) { - emit log(_name(".completeWithdrawalAsTokens")); + _logM("completeWithdrawalsAsTokens"); return _completeQueuedWithdrawal(withdrawal, true); } function completeWithdrawalsAsShares(IDelegationManager.Withdrawal[] memory withdrawals) public createSnapshot virtual returns (IERC20[][] memory) { - emit log(_name(".completeWithdrawalsAsShares")); + _logM("completeWithdrawalAsShares"); IERC20[][] memory tokens = new IERC20[][](withdrawals.length); @@ -268,23 +192,122 @@ contract User is Test { } function completeWithdrawalAsShares(IDelegationManager.Withdrawal memory withdrawal) public createSnapshot virtual returns (IERC20[] memory) { - emit log(_name(".completeWithdrawalAsShares")); + _logM("completeWithdrawalAsShares"); return _completeQueuedWithdrawal(withdrawal, false); } - /// @notice We set the proof generation start time to be after the timestamp that pod restaking is activated - /// We do this to prevent proofIsForValidTimestamp modifier from reverting - function activateRestaking() public createSnapshot { - emit log(_name(".activateRestaking")); - - emit log_named_uint("pre-activation, most recent wd timestamp", pod.mostRecentWithdrawalTimestamp()); + /******************************************************************************* + BEACON CHAIN METHODS + *******************************************************************************/ + + /// @dev Uses any ETH held by the User to start validators on the beacon chain + /// @return A list of created validator indices + /// @return The amount of wei sent to the beacon chain + /// Note: If the user does not have enough ETH to start a validator, this method reverts + /// Note: This method also advances one epoch forward on the beacon chain, so that + /// withdrawal credential proofs are generated for each validator. + function startValidators() public createSnapshot virtual returns (uint40[] memory, uint64) { + _logM("startValidators"); + + return _startValidators(); + } + + function exitValidators(uint40[] memory _validators) public createSnapshot virtual returns (uint64 exitedBalanceGwei) { + _logM("exitValidators"); + + return _exitValidators(_validators); + } + + /******************************************************************************* + EIGENPOD METHODS + *******************************************************************************/ + + function verifyWithdrawalCredentials( + uint40[] memory _validators + ) public createSnapshot virtual { + _logM("verifyWithdrawalCredentials"); + + _verifyWithdrawalCredentials(_validators); + } + + function startCheckpoint() public createSnapshot virtual { + _logM("startCheckpoint"); + + _startCheckpoint(); + } + + function completeCheckpoint() public createSnapshot virtual { + _logM("completeCheckpoint"); + + _completeCheckpoint(); + } + + function verifyStaleBalance(uint40 validatorIndex) public createSnapshot virtual { + _logM("verifyStaleBalance"); + + StaleBalanceProofs memory proof = beaconChain.getStaleBalanceProofs(validatorIndex); + + try pod.verifyStaleBalance({ + beaconTimestamp: proof.beaconTimestamp, + stateRootProof: proof.stateRootProof, + proof: proof.validatorProof + }) { } catch (bytes memory err) { + _revert(err); + } + } + + /******************************************************************************* + STRATEGY METHODS + *******************************************************************************/ + + /// @dev For each strategy/token balance, call the relevant deposit method + function depositIntoEigenlayer(IStrategy[] memory strategies, uint[] memory tokenBalances) public createSnapshot virtual { + _logM("depositIntoEigenlayer"); + + for (uint i = 0; i < strategies.length; i++) { + IStrategy strat = strategies[i]; + uint tokenBalance = tokenBalances[i]; - pod.activateRestaking(); + if (strat == BEACONCHAIN_ETH_STRAT) { + (uint40[] memory newValidators, ) = _startValidators(); + // Advance forward one epoch and generate credential and balance proofs for each validator + beaconChain.advanceEpoch_NoRewards(); + _verifyWithdrawalCredentials(newValidators); + } else { + IERC20 underlyingToken = strat.underlyingToken(); + underlyingToken.approve(address(strategyManager), tokenBalance); + strategyManager.depositIntoStrategy(strat, underlyingToken, tokenBalance); + } + } + } - emit log_named_uint("post-activation, most recent wd timestamp", pod.mostRecentWithdrawalTimestamp()); + function updateBalances(IStrategy[] memory strategies, int[] memory tokenDeltas) public createSnapshot virtual { + _logM("updateBalances"); + + for (uint i = 0; i < strategies.length; i++) { + IStrategy strat = strategies[i]; + int delta = tokenDeltas[i]; + + if (strat == BEACONCHAIN_ETH_STRAT) { + // If any balance update has occured, a checkpoint will pick it up + _startCheckpoint(); + if (pod.activeValidatorCount() != 0) { + _completeCheckpoint(); + } + } else { + uint tokens = uint(delta); + IERC20 underlyingToken = strat.underlyingToken(); + underlyingToken.approve(address(strategyManager), tokens); + strategyManager.depositIntoStrategy(strat, underlyingToken, tokens); + } + } } + /******************************************************************************* + INTERNAL METHODS + *******************************************************************************/ + function _completeQueuedWithdrawal( IDelegationManager.Withdrawal memory withdrawal, bool receiveAsTokens @@ -297,33 +320,18 @@ contract User is Test { if (strat == BEACONCHAIN_ETH_STRAT) { tokens[i] = NATIVE_ETH; - // If we're withdrawing as tokens, we need to process a withdrawal proof first + // If we're withdrawing native ETH as tokens, stop ALL validators + // and complete a checkpoint if (receiveAsTokens) { - emit log("exiting validators and processing withdrawals..."); - - uint numValidators = validators.length; - for (uint j = 0; j < numValidators; j++) { - emit log_named_uint("exiting validator ", j); - - uint40 validatorIndex = validators[j]; - BeaconWithdrawal memory proofs = beaconChain.exitValidator(validatorIndex); + _log("- exiting all validators and completing checkpoint"); + _exitValidators(getActiveValidators()); - uint64 withdrawableBefore = pod.withdrawableRestakedExecutionLayerGwei(); + beaconChain.advanceEpoch_NoRewards(); - pod.verifyAndProcessWithdrawals({ - oracleTimestamp: proofs.oracleTimestamp, - stateRootProof: proofs.stateRootProof, - withdrawalProofs: proofs.withdrawalProofs, - validatorFieldsProofs: proofs.validatorFieldsProofs, - validatorFields: proofs.validatorFields, - withdrawalFields: proofs.withdrawalFields - }); - - uint64 withdrawableAfter = pod.withdrawableRestakedExecutionLayerGwei(); - - emit log_named_uint("pod withdrawable before: ", withdrawableBefore); - emit log_named_uint("pod withdrawable after: ", withdrawableAfter); + _startCheckpoint(); + if (pod.activeValidatorCount() != 0) { + _completeCheckpoint(); } } } else { @@ -340,6 +348,118 @@ contract User is Test { pod = EigenPod(payable(eigenPodManager.createPod())); } + /// @dev Uses any ETH held by the User to start validators on the beacon chain + /// @return A list of created validator indices + /// @return The amount of wei sent to the beacon chain + /// Note: If the user does not have enough ETH to start a validator, this method reverts + /// Note: This method also advances one epoch forward on the beacon chain, so that + /// withdrawal credential proofs are generated for each validator. + function _startValidators() internal returns (uint40[] memory, uint64) { + uint balanceWei = address(this).balance; + + // Number of full validators: balance / 32 ETH + uint numValidators = balanceWei / 32 ether; + balanceWei -= (numValidators * 32 ether); + + // If we still have at least 1 ETH left over, we can create another (non-full) validator + // Note that in the mock beacon chain this validator will generate rewards like any other. + // The main point is to ensure pods are able to handle validators that have less than 32 ETH + uint lastValidatorBalance; + uint totalValidators = numValidators; + if (balanceWei >= 1 ether) { + lastValidatorBalance = balanceWei - (balanceWei % 1 gwei); + balanceWei -= lastValidatorBalance; + totalValidators++; + } + + require(totalValidators != 0, "startValidators: not enough ETH to start a validator"); + uint40[] memory newValidators = new uint40[](totalValidators); + uint64 totalBeaconBalanceGwei = uint64((address(this).balance - balanceWei) / GWEI_TO_WEI); + + _log("- creating new validators", newValidators.length); + _log("- depositing balance to beacon chain (gwei)", totalBeaconBalanceGwei); + + // Create each of the full validators + for (uint i = 0; i < numValidators; i++) { + uint40 validatorIndex = beaconChain.newValidator{ + value: 32 ether + }(_podWithdrawalCredentials()); + + newValidators[i] = validatorIndex; + validators.push(validatorIndex); + } + + // If we had a remainder, create the final, non-full validator + if (totalValidators == numValidators + 1) { + uint40 validatorIndex = beaconChain.newValidator{ + value: lastValidatorBalance + }(_podWithdrawalCredentials()); + + newValidators[newValidators.length - 1] = validatorIndex; + validators.push(validatorIndex); + } + + return (newValidators, totalBeaconBalanceGwei); + } + + function _exitValidators(uint40[] memory _validators) internal returns (uint64 exitedBalanceGwei) { + _log("- exiting num validators", _validators.length); + + for (uint i = 0; i < _validators.length; i++) { + exitedBalanceGwei += beaconChain.exitValidator(_validators[i]); + } + + _log("- exited balance to pod (gwei)", exitedBalanceGwei); + + return exitedBalanceGwei; + } + + function _startCheckpoint() internal { + try pod.startCheckpoint(false) {} catch (bytes memory err) { + _revert(err); + } + } + + function _completeCheckpoint() internal { + _log("- active validator count", pod.activeValidatorCount()); + _log("- proofs remaining", pod.currentCheckpoint().proofsRemaining); + + uint64 checkpointTimestamp = pod.currentCheckpointTimestamp(); + if (checkpointTimestamp == 0) { + revert("User._completeCheckpoint: no existing checkpoint"); + } + + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs(validators, checkpointTimestamp); + _log("- submitting num checkpoint proofs", proofs.balanceProofs.length); + + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); + } + + function _verifyWithdrawalCredentials(uint40[] memory _validators) internal { + CredentialProofs memory proofs = beaconChain.getCredentialProofs(_validators); + + try pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: _validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }) { } catch (bytes memory err) { + _revert(err); + } + } + + /// @dev Revert, passing through an error message + function _revert(bytes memory err) internal pure { + if (err.length != 0) { + assembly { revert(add(32, err), mload(err)) } + } + revert("reverted with unknown error"); + } + function _podWithdrawalCredentials() internal view returns (bytes memory) { return abi.encodePacked(bytes1(uint8(1)), bytes11(0), address(pod)); } @@ -373,12 +493,23 @@ contract User is Test { return expectedWithdrawals; } - function _name(string memory s) internal view returns (string memory) { - return string.concat(NAME, s); - } + function getActiveValidators() public view returns (uint40[] memory) { + uint40[] memory activeValidators = new uint40[](validators.length); + + uint numActive; + uint pos; + for(uint i = 0; i < validators.length; i++) { + if (beaconChain.isActive(validators[i])) { + activeValidators[pos] = validators[i]; + numActive++; + pos++; + } + } + + // Manually update length + assembly { mstore(activeValidators, numActive) } - function getUpdatableValidator() public view returns (uint40) { - return validators[0]; + return activeValidators; } } @@ -390,7 +521,8 @@ contract User_AltMethods is User { constructor(string memory name) User(name) {} function delegateTo(User operator) public createSnapshot override { - emit log_named_string(_name(".delegateTo: "), operator.NAME()); + _logM("delegateTo_ALT", operator.NAME()); + // Create empty data ISignatureUtils.SignatureWithExpiry memory emptySig; uint256 expiry = type(uint256).max; @@ -412,7 +544,7 @@ contract User_AltMethods is User { } function depositIntoEigenlayer(IStrategy[] memory strategies, uint[] memory tokenBalances) public createSnapshot override { - emit log(_name(".depositIntoEigenlayer")); + _logM("depositIntoEigenlayer_ALT"); uint256 expiry = type(uint256).max; for (uint i = 0; i < strategies.length; i++) { @@ -420,31 +552,10 @@ contract User_AltMethods is User { uint tokenBalance = tokenBalances[i]; if (strat == BEACONCHAIN_ETH_STRAT) { - // We're depositing via `eigenPodManager.stake`, which only accepts - // deposits of exactly 32 ether. - require(tokenBalance % 32 ether == 0, "User.depositIntoEigenlayer: balance must be multiple of 32 eth"); - - // For each multiple of 32 ether, deploy a new validator to the same pod - uint numValidators = tokenBalance / 32 ether; - for (uint j = 0; j < numValidators; j++) { - eigenPodManager.stake{ value: 32 ether }("", "", bytes32(0)); - - (uint40 newValidatorIndex, CredentialsProofs memory proofs) = - beaconChain.newValidator({ - balanceWei: 32 ether, - withdrawalCreds: _podWithdrawalCredentials() - }); - - validators.push(newValidatorIndex); - - pod.verifyWithdrawalCredentials({ - oracleTimestamp: proofs.oracleTimestamp, - stateRootProof: proofs.stateRootProof, - validatorIndices: proofs.validatorIndices, - validatorFieldsProofs: proofs.validatorFieldsProofs, - validatorFields: proofs.validatorFields - }); - } + (uint40[] memory newValidators, ) = _startValidators(); + // Advance forward one epoch and generate credential and balance proofs for each validator + beaconChain.advanceEpoch_NoRewards(); + _verifyWithdrawalCredentials(newValidators); } else { // Approve token IERC20 underlyingToken = strat.underlyingToken(); diff --git a/src/test/integration/users/User_M1.t.sol b/src/test/integration/users/User_M1.t.sol index c2f934130..3f914cfaf 100644 --- a/src/test/integration/users/User_M1.t.sol +++ b/src/test/integration/users/User_M1.t.sol @@ -41,7 +41,7 @@ contract User_M1 is User { IStrategy[] memory strategies, uint256[] memory tokenBalances ) public virtual createSnapshot { - emit log(_name(".depositIntoEigenlayer_M1")); + _logM("depositIntoEigenlayer_M1"); for (uint256 i = 0; i < strategies.length; i++) { IStrategy strat = strategies[i]; @@ -76,7 +76,7 @@ contract User_M1_AltMethods is User_M1 { IStrategy[] memory strategies, uint256[] memory tokenBalances ) public override createSnapshot { - emit log(_name(".depositIntoEigenlayer_M1_ALT")); + _logM(".depositIntoEigenlayer_M1_ALT"); uint256 expiry = type(uint256).max; for (uint256 i = 0; i < strategies.length; i++) { diff --git a/src/test/integration/utils/PrintUtils.t.sol b/src/test/integration/utils/PrintUtils.t.sol new file mode 100644 index 000000000..c80dd42ff --- /dev/null +++ b/src/test/integration/utils/PrintUtils.t.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; + +import "@openzeppelin/contracts/utils/Strings.sol"; + +abstract contract PrintUtils is Test { + + using Strings for *; + using StdStyle for *; + + string constant HEADER_DELIMITER = "=================================================="; + string constant SECTION_DELIMITER = "======"; + + /// @dev Inheriting contracts implement this method + function NAME() public virtual view returns (string memory); + + function _logHeader(string memory key) internal { + emit log(HEADER_DELIMITER); + + emit log(key); + + emit log(HEADER_DELIMITER); + } + + function _logHeader(string memory key, address a) internal { + emit log(HEADER_DELIMITER); + + emit log_named_string(key.cyan(), a.yellow()); + // emit log_named_address(key.cyan(), a); + + emit log(HEADER_DELIMITER); + } + + function _logSection(string memory key) internal { + emit log(string.concat( + SECTION_DELIMITER, + key, + SECTION_DELIMITER + )); + } + + function _logSection(string memory key, address a) internal { + emit log(string.concat( + SECTION_DELIMITER, + key.cyan(), + ": ", + a.yellow().dim(), + SECTION_DELIMITER + )); + } + + function _logAction(string memory key, string memory action) internal { + emit log_named_string( + key.cyan(), + action.italic() + ); + } + + /// @dev Log method name + function _logM(string memory method) internal { + emit log(string.concat( + NAME().cyan(), + ".", + method.italic() + )); + } + + function _logM(string memory method, string memory arg) internal { + emit log(string.concat( + NAME().cyan(), + ".", + method.italic(), + ":", + arg + )); + } + + function _log(string memory s) internal { + emit log(s); + } + + function _logGreen(string memory s) internal { + emit log(s.green()); + } + + function _logGreen(string memory s, string memory value) internal { + emit log_named_string(s, value.green()); + } + + function _logYellow(string memory s, string memory value) internal { + emit log_named_string(s, value.yellow()); + } + + function _log(string memory key, string memory value) internal { + emit log_named_string(key, value); + } + + function _log(string memory key, uint value) internal { + emit log_named_uint(key, value); + } + + function _log(string memory key, address value) internal { + emit log_named_string(key, value.yellow()); + } + + function _logDim(string memory key, address value) internal { + emit log_named_string(key.dim(), value.yellow().dim()); + } + + function _log(string memory key, bytes32 value) internal { + emit log_named_string(key, value.dimBytes32()); + } + + function _log(string memory key, bool value) internal { + emit log_named_string(key, value ? "true".green() : "false".magenta()); + } +} \ No newline at end of file diff --git a/src/test/mocks/BeaconChainOracleMock.sol b/src/test/mocks/BeaconChainOracleMock.sol deleted file mode 100644 index 890ca1a1e..000000000 --- a/src/test/mocks/BeaconChainOracleMock.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.12; - -import "../../contracts/interfaces/IBeaconChainOracle.sol"; - - - -contract BeaconChainOracleMock is IBeaconChainOracle { - - bytes32 public mockBeaconChainStateRoot; - - function getOracleBlockRootAtTimestamp() external view returns(bytes32) { - return mockBeaconChainStateRoot; - } - - function setOracleBlockRootAtTimestamp(bytes32 beaconChainStateRoot) external { - mockBeaconChainStateRoot = beaconChainStateRoot; - } - - function timestampToBlockRoot(uint256 /*blockNumber*/) external view returns(bytes32) { - return mockBeaconChainStateRoot; - } - - function isOracleSigner(address /*_oracleSigner*/) external pure returns(bool) { - return true; - } - - function hasVoted(uint64 /*blockNumber*/, address /*oracleSigner*/) external pure returns(bool) { - return true; - } - - function stateRootVotes(uint64 /*blockNumber*/, bytes32 /*stateRoot*/) external pure returns(uint256) { - return 0; - } - - function totalOracleSigners() external pure returns(uint256) { - return 0; - } - - function threshold() external pure returns(uint256) { - return 0; - } - - function setThreshold(uint256 /*_threshold*/) external pure {} - - function addOracleSigners(address[] memory /*_oracleSigners*/) external pure {} - - function removeOracleSigners(address[] memory /*_oracleSigners*/) external pure {} - - function voteForBeaconChainStateRoot(uint64 /*blockNumber*/, bytes32 /*stateRoot*/) external pure {} - - function latestConfirmedOracleBlockNumber() external pure returns(uint64) {} -} diff --git a/src/test/mocks/DelayedWithdrawalRouterMock.sol b/src/test/mocks/DelayedWithdrawalRouterMock.sol deleted file mode 100644 index 53077cd52..000000000 --- a/src/test/mocks/DelayedWithdrawalRouterMock.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import "../../contracts/interfaces/IDelayedWithdrawalRouter.sol"; - -contract DelayedWithdrawalRouterMock is IDelayedWithdrawalRouter { - /** - * @notice Creates an delayed withdrawal for `msg.value` to the `recipient`. - * @dev Only callable by the `podOwner`'s EigenPod contract. - */ - function createDelayedWithdrawal(address podOwner, address recipient) external payable{} - - /** - * @notice Called in order to withdraw delayed withdrawals made to the `recipient` that have passed the `withdrawalDelayBlocks` period. - * @param recipient The address to claim delayedWithdrawals for. - * @param maxNumberOfWithdrawalsToClaim Used to limit the maximum number of withdrawals to loop through claiming. - */ - function claimDelayedWithdrawals(address recipient, uint256 maxNumberOfWithdrawalsToClaim) external{} - - /** - * @notice Called in order to withdraw delayed withdrawals made to the caller that have passed the `withdrawalDelayBlocks` period. - * @param maxNumberOfWithdrawalsToClaim Used to limit the maximum number of withdrawals to loop through claiming. - */ - function claimDelayedWithdrawals(uint256 maxNumberOfWithdrawalsToClaim) external{} - - /// @notice Owner-only function for modifying the value of the `withdrawalDelayBlocks` variable. - function setWithdrawalDelayBlocks(uint256 newValue) external{} - - /// @notice Getter function for the mapping `_userWithdrawals` - function userWithdrawals(address user) external view returns (UserDelayedWithdrawals memory){} - - /// @notice Getter function to get all delayedWithdrawals of the `user` - function getUserDelayedWithdrawals(address user) external view returns (DelayedWithdrawal[] memory){} - - /// @notice Getter function to get all delayedWithdrawals that are currently claimable by the `user` - function getClaimableUserDelayedWithdrawals(address user) external view returns (DelayedWithdrawal[] memory){} - - /// @notice Getter function for fetching the delayedWithdrawal at the `index`th entry from the `_userWithdrawals[user].delayedWithdrawals` array - function userDelayedWithdrawalByIndex(address user, uint256 index) external view returns (DelayedWithdrawal memory){} - - /// @notice Getter function for fetching the length of the delayedWithdrawals array of a specific user - function userWithdrawalsLength(address user) external view returns (uint256){} - - /// @notice Convenience function for checking whether or not the delayedWithdrawal at the `index`th entry from the `_userWithdrawals[user].delayedWithdrawals` array is currently claimable - function canClaimDelayedWithdrawal(address user, uint256 index) external view returns (bool){} - - /** - * @notice Delay enforced by this contract for completing any delayedWithdrawal. 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 withdrawalDelayBlocks() external view returns (uint256){} -} diff --git a/src/test/mocks/EigenPodManagerMock.sol b/src/test/mocks/EigenPodManagerMock.sol index 96da69030..127fcc49a 100644 --- a/src/test/mocks/EigenPodManagerMock.sol +++ b/src/test/mocks/EigenPodManagerMock.sol @@ -3,14 +3,20 @@ pragma solidity ^0.8.9; import "forge-std/Test.sol"; import "../../contracts/interfaces/IEigenPodManager.sol"; +import "../../contracts/permissions/Pausable.sol"; -contract EigenPodManagerMock is IEigenPodManager, Test { + +contract EigenPodManagerMock is IEigenPodManager, Test, Pausable { IStrategy public constant beaconChainETHStrategy = IStrategy(0xbeaC0eeEeeeeEEeEeEEEEeeEEeEeeeEeeEEBEaC0); IBeacon public eigenPodBeacon; IETHPOSDeposit public ethPOS; mapping(address => int256) public podShares; + constructor(IPauserRegistry _pauserRegistry) { + _initializePauser(_pauserRegistry, 0); + } + function slasher() external view returns(ISlasher) {} function createPod() external returns(address) {} @@ -18,8 +24,6 @@ contract EigenPodManagerMock is IEigenPodManager, Test { function stake(bytes calldata /*pubkey*/, bytes calldata /*signature*/, bytes32 /*depositDataRoot*/) external payable {} function recordBeaconChainETHBalanceUpdate(address /*podOwner*/, int256 /*sharesDelta*/) external pure {} - - function updateBeaconChainOracle(IBeaconChainOracle /*newBeaconChainOracle*/) external pure {} function ownerToPod(address /*podOwner*/) external pure returns(IEigenPod) { return IEigenPod(address(0)); @@ -29,14 +33,6 @@ contract EigenPodManagerMock is IEigenPodManager, Test { return IEigenPod(podOwner); } - function beaconChainOracle() external pure returns(IBeaconChainOracle) { - return IBeaconChainOracle(address(0)); - } - - function getBlockRootAtTimestamp(uint64 /*timestamp*/) external pure returns(bytes32) { - return bytes32(0); - } - function strategyManager() external pure returns(IStrategyManager) { return IStrategyManager(address(0)); } @@ -45,26 +41,6 @@ contract EigenPodManagerMock is IEigenPodManager, Test { return false; } - function pause(uint256 /*newPausedStatus*/) external{} - - function pauseAll() external{} - - function paused() external pure returns (uint256) { - return 0; - } - - function paused(uint8 /*index*/) external pure returns (bool) { - return false; - } - - function setPauserRegistry(IPauserRegistry /*newPauserRegistry*/) external {} - - function pauserRegistry() external pure returns (IPauserRegistry) { - return IPauserRegistry(address(0)); - } - - function unpause(uint256 /*newPausedStatus*/) external{} - function podOwnerShares(address podOwner) external view returns (int256) { return podShares[podOwner]; } @@ -84,6 +60,8 @@ contract EigenPodManagerMock is IEigenPodManager, Test { function numPods() external view returns (uint256) {} + function updateStaleValidatorCount(address, int256) external {} + function denebForkTimestamp() external pure returns (uint64) { return type(uint64).max; } diff --git a/src/test/mocks/EigenPodMock.sol b/src/test/mocks/EigenPodMock.sol index 38b515018..d1e12199f 100644 --- a/src/test/mocks/EigenPodMock.sol +++ b/src/test/mocks/EigenPodMock.sol @@ -5,8 +5,6 @@ import "forge-std/Test.sol"; import "../../contracts/interfaces/IEigenPod.sol"; contract EigenPodMock is IEigenPod, Test { - /// @notice The max amount of eth, in gwei, that can be restaked per validator - function MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR() external view returns(uint64) {} function nonBeaconChainETHBalanceWei() external view returns(uint256) {} @@ -42,38 +40,42 @@ contract EigenPodMock is IEigenPod, Test { /// @notice Returns the validatorInfo struct for the provided pubkeyHash function validatorPubkeyHashToInfo(bytes32 validatorPubkeyHash) external view returns (ValidatorInfo memory) {} - - ///@notice mapping that tracks proven withdrawals - function provenWithdrawal(bytes32 validatorPubkeyHash, uint64 slot) external view returns (bool) {} - /// @notice This returns the status of a given validator function validatorStatus(bytes32 pubkeyHash) external view returns(VALIDATOR_STATUS) {} + /// @notice Number of validators with proven withdrawal credentials, who do not have proven full withdrawals + function activeValidatorCount() external view returns (uint256) {} - function verifyWithdrawalCredentials( - uint64 oracleTimestamp, - BeaconChainProofs.StateRootProof calldata stateRootProof, - uint40[] calldata validatorIndices, - bytes[] calldata withdrawalCredentialProofs, - bytes32[][] calldata validatorFields + /// @notice The timestamp of the last checkpoint finalized + function lastCheckpointTimestamp() external view returns (uint64) {} + + /// @notice The timestamp of the currently-active checkpoint. Will be 0 if there is not active checkpoint + function currentCheckpointTimestamp() external view returns (uint64) {} + + /// @notice Returns the currently-active checkpoint + function currentCheckpoint() external view returns (Checkpoint memory) {} + + function checkpointBalanceExitedGwei(uint64) external view returns (uint64) {} + + function startCheckpoint(bool revertIfNoBalance) external {} + + function verifyCheckpointProofs( + BeaconChainProofs.BalanceContainerProof calldata balanceContainerProof, + BeaconChainProofs.BalanceProof[] calldata proofs ) external {} - - function verifyBalanceUpdates( - uint64 oracleTimestamp, - uint40[] calldata validatorIndices, + function verifyStaleBalance( + uint64 beaconTimestamp, BeaconChainProofs.StateRootProof calldata stateRootProof, - bytes[] calldata validatorFieldsProofs, - bytes32[][] calldata validatorFields + BeaconChainProofs.ValidatorProof calldata proof ) external {} - function verifyAndProcessWithdrawals( + function verifyWithdrawalCredentials( uint64 oracleTimestamp, BeaconChainProofs.StateRootProof calldata stateRootProof, - BeaconChainProofs.WithdrawalProof[] calldata withdrawalProofs, - bytes[] calldata validatorFieldsProofs, - bytes32[][] calldata validatorFields, - bytes32[][] calldata withdrawalFields + uint40[] calldata validatorIndices, + bytes[] calldata withdrawalCredentialProofs, + bytes32[][] calldata validatorFields ) external {} /// @notice Called by the pod owner to withdraw the balance of the pod when `hasRestaked` is set to false @@ -88,6 +90,16 @@ contract EigenPodMock is IEigenPod, Test { /// @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 {} + function setProofSubmitter(address newProofSubmitter) external {} + + function proofSubmitter() external view returns (address) {} + function validatorStatus(bytes calldata pubkey) external view returns (VALIDATOR_STATUS){} function validatorPubkeyToInfo(bytes calldata validatorPubkey) external view returns (ValidatorInfo memory){} + + /// @notice Query the 4788 oracle to get the parent block root of the slot with the given `timestamp` + /// @param timestamp of the block for which the parent block root will be returned. MUST correspond + /// 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) {} } \ No newline at end of file diff --git a/src/test/mocks/IBeaconChainOracleMock.sol b/src/test/mocks/IBeaconChainOracleMock.sol deleted file mode 100644 index 7ef4cc680..000000000 --- a/src/test/mocks/IBeaconChainOracleMock.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.12; - -/** - * @title Interface for the BeaconStateOracle contract. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - */ -interface IBeaconChainOracleMock { - /// @notice Largest blockNumber that has been confirmed by the oracle. - function latestConfirmedOracleBlockNumber() external view returns(uint64); - /// @notice Mapping: Beacon Chain blockNumber => the Beacon Chain state root at the specified blockNumber. - /// @dev This will return `bytes32(0)` if the state root is not yet finalized at the blockNumber. - function beaconStateRootAtBlockNumber(uint64 blockNumber) external view returns(bytes32); - - /// @notice Mapping: address => whether or not the address is in the set of oracle signers. - function isOracleSigner(address _oracleSigner) external view returns(bool); - - /// @notice Mapping: Beacon Chain blockNumber => oracle signer address => whether or not the oracle signer has voted on the state root at the blockNumber. - function hasVoted(uint64 blockNumber, address oracleSigner) external view returns(bool); - - /// @notice Mapping: Beacon Chain blockNumber => state root => total number of oracle signer votes for the state root at the blockNumber. - function stateRootVotes(uint64 blockNumber, bytes32 stateRoot) external view returns(uint256); - - /// @notice Total number of members of the set of oracle signers. - function totalOracleSigners() external view returns(uint256); - - - function setOracleBlockRootAtTimestamp(bytes32 beaconChainStateRoot) external; - - - /** - * @notice Number of oracle signers that must vote for a state root in order for the state root to be confirmed. - * Adjustable by this contract's owner through use of the `setThreshold` function. - * @dev We note that there is an edge case -- when the threshold is adjusted downward, if a state root already has enough votes to meet the *new* threshold, - * the state root must still receive one additional vote from an oracle signer to be confirmed. This behavior is intended, to minimize unexpected root confirmations. - */ - function threshold() external view returns(uint256); - - /** - * @notice Owner-only function used to modify the value of the `threshold` variable. - * @param _threshold Desired new value for the `threshold` variable. Function will revert if this is set to zero. - */ - function setThreshold(uint256 _threshold) external; - - /** - * @notice Owner-only function used to add a signer to the set of oracle signers. - * @param _oracleSigners Array of address to be added to the set. - * @dev Function will have no effect on the i-th input address if `_oracleSigners[i]`is already in the set of oracle signers. - */ - function addOracleSigners(address[] memory _oracleSigners) external; - - /** - * @notice Owner-only function used to remove a signer from the set of oracle signers. - * @param _oracleSigners Array of address to be removed from the set. - * @dev Function will have no effect on the i-th input address if `_oracleSigners[i]`is already not in the set of oracle signers. - */ - function removeOracleSigners(address[] memory _oracleSigners) external; - - /** - * @notice Called by a member of the set of oracle signers to assert that the Beacon Chain state root is `stateRoot` at `blockNumber`. - * @dev The state root will be finalized once the total number of votes *for this exact state root at this exact blockNumber* meets the `threshold` value. - * @param blockNumber The Beacon Chain blockNumber of interest. - * @param stateRoot The Beacon Chain state root that the caller asserts was the correct root, at the specified `blockNumber`. - */ - function voteForBeaconChainStateRoot(uint64 blockNumber, bytes32 stateRoot) external; -} diff --git a/src/test/tree/EigenPodUnit.tree b/src/test/tree/EigenPodUnit.tree index 92a2c4e45..9e142df40 100644 --- a/src/test/tree/EigenPodUnit.tree +++ b/src/test/tree/EigenPodUnit.tree @@ -4,39 +4,6 @@ │ └── it should properly set storage ├── when initialize called again │ └── it should revert -├── // Balance Update Tree -├── when verifyBalanceUpdates is called *** -│ ├── given that balance updates are paused -│ │ └── it should revert -│ ├── given that the indices and proofs are different lengths -│ │ └── it should revert -│ ├── given that the oracle timestamp is stale -│ │ └── it should revert -│ ├── given that the beacon state root proof is invalid -│ │ └── it should revert -│ └── given that the above conditions are satisfied -│ ├── it should call _verifyBalanceUpdate for each balance update -│ └── it should record a beaconChainETH balance update in the EPM -├── when _verifyBalanceUpdate is called (internal function) -│ ├── given that the most recent balance update timestamp is greater than or equal to the oracle timestamp -│ │ └── it should revert -│ ├── given that the validator status is not active -│ │ └── it should revert -│ ├── given that the validator withdrawable epoch is less than or equal to the epoch of the oracle timestamp -│ │ └── given that the validator balance is equal to 0 -│ │ └── it should revert -│ ├── given that the validator fields proof is not valid -│ │ └── it should revert -│ ├── given that the validator balances proof is not valid -│ │ └── it should revert -│ └── given that the above conditions are satisfied -│ ├── given that the validator restaked balance is greater than the max restaked balance per validator -│ │ └── it should set the new restaked balance to the validator restaked balance -│ ├── given that the validator restaked balance is less than or equal to the max restaked balance per validator -│ │ └── it should set the new restaked balance to the validator restaked balance -│ ├── it should update the _validatorPubkeyHashToInfo mapping with the new restaked balance -│ └── given that the new restaked balance is not equal to the validator restaked balance -│ └── it should emit a validator balance updated event and return a non-zero sharesDeltaGwei ├── // EigenPodManager Caller Tree ├── when stake is called │ ├── given the caller is not the EigenPodManager @@ -73,99 +40,95 @@ │ ├── it should call _verifyWithdrawalCredentials for each validator │ └── it should record a beaconChainETH balance update in the EPM ├── when _verifyWithdrawalCredentials is called (internal function) -│ ├── given that the validators status is inactive +│ ├── given that the validators status is not INACTIVE +│ │ └── it should revert +│ ├── given that the validator is currently in the process of fully exiting │ │ └── it should revert │ ├── given that validator's withdrawal credentials does not correspond to the pod withdrawal credentials │ │ └── it should revert │ ├── given that the validator fields proof is not valid │ │ └── it should revert │ └── given that all the above conditions are satisfied -│ ├── given that the validator effective balance is greater than the max restaked balance -│ │ └── it should set the validator restaked balance to the max restaked balance -│ ├── given that the validator effective balance is less than or equal to the max restaked balance -│ │ └── it should set the validator restaked balance to the validator effective balance -│ ├── it should update the _validatorPubkeyHashToInfo mapping with an active validator and restaked balance +│ ├── it should set the validator's restaked balance to their effective balance +│ ├── it should update the _validatorPubkeyHashToInfo mapping with an active validator, restaked balance in gwei, and lastCheckpointedAt timestamp │ ├── it should emit ValidatorRestaked and ValidatorBalanceUpdated Events -│ └── It should return the validator's restakedBalance in wei -├── when withdrawNonBeaconChainETHBalanceWei is called -│ ├── given that the caller is not the eigen pod owner -│ │ └── it should revert -│ ├── given that the amount to withdraw is greater than the non-beacon chain eth balance -│ │ └── it should revert -│ └── given the above conditions pass -│ └── it should emit a non beacon chain eth withdrawn event and send eth to the delayed withdrawal router +│ └── it should return the validator's restakedBalance in wei ├── when recoverTokens is called │ ├── given that the caller is not the eigen pod owner │ │ └── it should revert +│ ├── given that non proof withdrawals are paused +│ │ └── it should revert │ ├── given that the tokens and amounts to withdraw are different lengths │ │ └── it should revert │ └── given that the above conditions pass │ └── it should transfer tokens to the recipient -├── when activate restaking is called -│ ├── given that the eigenpods verify credentials is not paused *** -│ │ └── it should revert +├── // Checkpointing Tree +├── when startCheckpoint is called │ ├── given that the caller is not the eigen pod owner │ │ └── it should revert -│ ├── given that hasRestaked is true +│ ├── given that start checkpoints is not paused │ │ └── it should revert -│ └── given that all the above conditions pass -│ └── it should set hasRestaked to true, process a withdrawal of ETH to the delayed withdrawal router, and emit a RestakingActivated event -├── when withdrawBeforeRestaking is called -│ ├── given that the caller is not the eigen pod owner +│ ├── it should call _startCheckpoint +│ └── given _startCheckpoint does not revert +│ └── given hasRestaked is false +│ └── it should set hasRestaked to true and emit RestakingActivated +├── when _startCheckpoint is called +│ ├── given a current checkpoint is in progress, currentCheckpointTimestamp != 0 │ │ └── it should revert -│ ├── given that has restaked is true +│ ├── given the last checkpoint occurred in the same block, lastCheckpointTimestamp == block.timestamp │ │ └── it should revert -│ └── given that the above conditions pass -│ └── it should process a withdrawal of eth to the delayed withdrawal router -├── // Withdrawal Tree -├── when verifyAndProcessWithdrawals is called *** -│ ├── given that verifying withdrawals are paused +│ ├── given revertIfNoBalance is true and the pod has no increase balance in gwei │ │ └── it should revert -│ ├── given that validatorFields, validatorProofs, withdrawalProofs, withdrawalFields, are different lengths -│ │ └── it should revert -│ ├── given that the beacon state root proof is invalid -│ │ └── it should revert -│ ├── given that the above conditions are satisfied -│ ├── it should call _verifyAndProcessWithdrawal -│ ├── given that the amount of ETH to withdraw immediately is greater than 0 -│ │ └── it should send the ETH to the delayed withdrawal router -│ └── given that the pod's shares have are not 0 -│ └── it should record a beacon chain balance update in the EPM -└── when _verifyAndProcessWithdrawal is called (internal function) - ├── given that the proof timestamp is stale +│ └── given that the above conditions pass +│ ├── it should set the currentCheckpointTimestamp to the current block timestamp +│ ├── it should set the currentCheckpoint with the parentBlockRoot at block.timestamp and with the current activeValidatorCount +│ └── it should emit CheckpointCreated +├── when verifyCheckpointProofs is called +│ ├── given that verify checkpoint proofs is paused +│ │ └── it should revert +│ ├── given there is no currently active checkpoint, currentCheckpointTimestamp == 0 +│ │ └── it should revert +│ ├── given the balanceContainerProof does not match with the current checkpoint beaconBlockRoot +│ │ └── it should revert +│ ├── for each balanceProof, it should process the respective validator accordingly +│ │ ├── given the validator is not active +│ │ │ └── it should continue to next validator proof +│ │ ├── given the validator last checkpointed timestamp is >= currentCheckpointTimestamp +│ │ │ └── it should continue to next validator proof +│ │ └── given _verifyCheckpointProof does not revert +│ │ └── it should decrement proofsRemaining, add to balanceDeltasGwei, add to exitedBalancesGwei +│ └── given that all above checkpoint proofs pass +│ └── it should update checkpointBalanceExitedGwei at the checkpoint timestamp and call _updateCheckpoint +├── when _verifyCheckpointProof is called +│ ├── given verifyValidatorBalance does not match with balanceContainerRoot +│ │ └── it should revert +│ └── it should return the balanceDeltaGwei and exitedBalanceGwei if the validator did a full exit +├── when _updateCheckpoint is called +│ ├── given there are still proofs remaining for the checkpoint +│ │ └── it should update the current checkpoint +│ └── given there are 0 proofs remaining for the checkpoint +│ ├── it should update the lastCheckpointTimestamp with currentCheckpointTimestamp +│ ├── it should delete currentCheckpointTimestamp resetting it to 0 +│ ├── it should delete the currentCheckpoint +│ ├── it should recordBeaconChainBalanceUpdate on the EPM with the total delta of shares in wei +│ └── it should emit CheckpointFinalized +├── when _getParentBlockRoot is called +│ ├── given the provided timestamp is out of range, HISTORY_BUFFER_LENGTH * 12seconds +│ │ └── it should revert +│ └── given the slot at the provided timestamp was skipped +│ └── it should revert +└── when verifyStaleBalance is called + ├── given that verify stale balance is paused + │ └── it should revert + ├── given that the validator last checkpointed timestamp is not stale enough (2 weeks) │ └── it should revert - ├── given that the status of the validator is inactive + ├── given that the validator status is not ACTIVE │ └── it should revert - ├── given that the withdrawalTimestamp has already been proven for the validator + ├── given that the validator has not been slashed │ └── it should revert - ├── given that the withdrawal proof is invalid + ├── given that the beacon state root proof does not match the beaconBlockRoot at the given beaconTimestamp │ └── it should revert - ├── given that the validator fields proof is invalid + ├── given the validator container proof does not match the beacon state root │ └── it should revert - └── given that the above conditions are satisfied - ├── it should set the withdrawal timestamp as proven for the validator pubKey - ├── given that the epoch of the proof is after the withdrawable epoch - │ ├── it should call _processFullWithdrawal - │ └── when _processFullWithdrawal is called (internal function) - │ ├── given that the withdrawalAmount is greater than the max restaked balance per validator - │ │ └── it should set the amount to queue to the max restaked balance per validator - │ ├── given that the withdrawalAmount is less than or equal to the max restaked balance per validator - │ │ └── it should set the amount to queue to the withdrawal amount - │ ├── it should set the amount of ETH to withdraw via the delayed withdrawal router as the difference between the withdrawalAmount and amount to queue - │ ├── it should increment withdrawableRestakedExecutionLayerGwei by the amount to queue - │ ├── it should update the sharesDelta of the withdrawal as the difference between the amount to queue and the previous restaked balance - │ ├── it should update the _validatorPubkeyHashToInfo mapping with a restaked balance of 0 and status as withdrawn - │ └── it should emit a FullWithdrawalRedeemed event and return the verified withdrawal struct - └── given that the epoch of the proof is before the withdrawable epoch - ├── it should call _processPartialWithdrawal - └── when _processPartialWithdrawal is called (internal function) - ├── it should emit a PartialWithdrawalRedeemed event - ├── it should increment the sumOfPartialWithdrawalsClaimedGwei variable - └── it should return the verified withdrawal struct - -// Tests in Integration -// Pausing Functionality -// verifyWithdrawalCredentials (external) -// verifyBalanceUpdates (external) -// verifyAndProcessWithdrawals(external) -// Withdraw restaked beacon chain ETH after withdrawing \ No newline at end of file + └── given that all the above conditions pass + └── it should call _startCheckpoint with revertIfNoBalance set to false \ No newline at end of file diff --git a/src/test/unit/AVSDirectoryUnit.t.sol b/src/test/unit/AVSDirectoryUnit.t.sol index 92fd7f875..6fd70891f 100644 --- a/src/test/unit/AVSDirectoryUnit.t.sol +++ b/src/test/unit/AVSDirectoryUnit.t.sol @@ -321,10 +321,6 @@ contract AVSDirectoryUnitTests_operatorAVSRegisterationStatus is AVSDirectoryUni assertFalse(delegationManager.isOperator(operator), "bad test setup"); _registerOperatorWithBaseDetails(operator); - uint256 expiry = type(uint256).max; - ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature = - _getOperatorSignature(delegationSignerPrivateKey, operator, defaultAVS, salt, expiry); - cheats.startPrank(operator); avsDirectory.cancelSalt(salt); diff --git a/src/test/unit/DelayedWithdrawalRouterUnit.t.sol b/src/test/unit/DelayedWithdrawalRouterUnit.t.sol deleted file mode 100644 index 848d1319e..000000000 --- a/src/test/unit/DelayedWithdrawalRouterUnit.t.sol +++ /dev/null @@ -1,474 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.12; - -import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import "@openzeppelin/contracts/utils/Address.sol"; - -import "../../contracts/pods/DelayedWithdrawalRouter.sol"; -import "../../contracts/permissions/PauserRegistry.sol"; - -import "../mocks/EigenPodManagerMock.sol"; -import "../mocks/Reenterer.sol"; - -import "forge-std/Test.sol"; - -contract DelayedWithdrawalRouterUnitTests is Test { - - Vm cheats = Vm(HEVM_ADDRESS); - - ProxyAdmin public proxyAdmin; - PauserRegistry public pauserRegistry; - - EigenPodManagerMock public eigenPodManagerMock; - - DelayedWithdrawalRouter public delayedWithdrawalRouterImplementation; - DelayedWithdrawalRouter public delayedWithdrawalRouter; - - Reenterer public reenterer; - - address public pauser = address(555); - address public unpauser = address(999); - - address initialOwner = address(this); - - uint224[] public delayedWithdrawalAmounts; - - uint256 internal _pseudorandomNumber; - - // index for flag that pauses withdrawals (i.e. 'delayedWithdrawal claims') when set - uint8 internal constant PAUSED_PAYMENT_CLAIMS = 0; - - mapping(address => bool) public addressIsExcludedFromFuzzedInputs; - - modifier filterFuzzedAddressInputs(address fuzzedAddress) { - cheats.assume(!addressIsExcludedFromFuzzedInputs[fuzzedAddress]); - _; - } - - /// @notice Emitted when the `withdrawalDelayBlocks` variable is modified from `previousValue` to `newValue`. - event WithdrawalDelayBlocksSet(uint256 previousValue, uint256 newValue); - - /// @notice event for delayedWithdrawal creation - event DelayedWithdrawalCreated(address podOwner, address recipient, uint256 amount, uint256 index); - - /// @notice event for the claiming of delayedWithdrawals - event DelayedWithdrawalsClaimed(address recipient, uint256 amountClaimed, uint256 delayedWithdrawalsCompleted); - - function setUp() external { - proxyAdmin = new ProxyAdmin(); - - address[] memory pausers = new address[](1); - pausers[0] = pauser; - pauserRegistry = new PauserRegistry(pausers, unpauser); - - eigenPodManagerMock = new EigenPodManagerMock(); - - delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManagerMock); - - uint256 initPausedStatus = 0; - uint256 withdrawalDelayBlocks = delayedWithdrawalRouterImplementation.MAX_WITHDRAWAL_DELAY_BLOCKS(); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - address( - new TransparentUpgradeableProxy( - address(delayedWithdrawalRouterImplementation), - address(proxyAdmin), - abi.encodeWithSelector(DelayedWithdrawalRouter.initialize.selector, initialOwner, pauserRegistry, initPausedStatus, withdrawalDelayBlocks) - ) - ) - ); - - reenterer = new Reenterer(); - - // exclude the zero address, the proxyAdmin, and this contract from fuzzed inputs - addressIsExcludedFromFuzzedInputs[address(0)] = true; - addressIsExcludedFromFuzzedInputs[address(proxyAdmin)] = true; - addressIsExcludedFromFuzzedInputs[address(this)] = true; - } - - function testCannotReinitialize() external { - uint256 initPausedStatus = 0; - uint256 withdrawalDelayBlocks = delayedWithdrawalRouter.MAX_WITHDRAWAL_DELAY_BLOCKS(); - cheats.expectRevert(bytes("Initializable: contract is already initialized")); - delayedWithdrawalRouter.initialize(initialOwner, pauserRegistry, initPausedStatus, withdrawalDelayBlocks); - } - - function testCreateDelayedWithdrawalNonzeroAmount(uint224 delayedWithdrawalAmount, address podOwner, address recipient) public filterFuzzedAddressInputs(podOwner) { - cheats.assume(delayedWithdrawalAmount != 0); - cheats.assume(recipient != address(0)); - - IDelayedWithdrawalRouter.UserDelayedWithdrawals memory userWithdrawalsBefore = delayedWithdrawalRouter.userWithdrawals(recipient); - - address podAddress = address(eigenPodManagerMock.getPod(podOwner)); - cheats.deal(podAddress, delayedWithdrawalAmount); - cheats.startPrank(podAddress); - uint256 userWithdrawalsLength = delayedWithdrawalRouter.userWithdrawalsLength(recipient); - cheats.expectEmit(true, true, true, true, address(delayedWithdrawalRouter)); - emit DelayedWithdrawalCreated(podOwner, recipient, delayedWithdrawalAmount, userWithdrawalsLength); - delayedWithdrawalRouter.createDelayedWithdrawal{value: delayedWithdrawalAmount}(podOwner, recipient); - cheats.stopPrank(); - - IDelayedWithdrawalRouter.UserDelayedWithdrawals memory userWithdrawalsAfter = delayedWithdrawalRouter.userWithdrawals(recipient); - - require(userWithdrawalsAfter.delayedWithdrawals.length == userWithdrawalsBefore.delayedWithdrawals.length + 1, - "userWithdrawalsAfter.delayedWithdrawals.length != userWithdrawalsBefore.delayedWithdrawals.length + 1"); - - IDelayedWithdrawalRouter.DelayedWithdrawal memory delayedWithdrawal = userWithdrawalsAfter.delayedWithdrawals[userWithdrawalsAfter.delayedWithdrawals.length - 1]; - require(delayedWithdrawal.amount == delayedWithdrawalAmount, "delayedWithdrawal.amount != delayedWithdrawalAmount"); - require(delayedWithdrawal.blockCreated == block.number, "delayedWithdrawal.blockCreated != block.number"); - } - - - function testCreateDelayedWithdrawalZeroAmount(address podOwner, address recipient) public filterFuzzedAddressInputs(podOwner) { - cheats.assume(recipient != address(0)); - IDelayedWithdrawalRouter.UserDelayedWithdrawals memory userWithdrawalsBefore = delayedWithdrawalRouter.userWithdrawals(recipient); - uint224 delayedWithdrawalAmount = 0; - cheats.assume(recipient != address(0)); - address podAddress = address(eigenPodManagerMock.getPod(podOwner)); - cheats.deal(podAddress, delayedWithdrawalAmount); - cheats.startPrank(podAddress); - delayedWithdrawalRouter.createDelayedWithdrawal{value: delayedWithdrawalAmount}(podOwner, recipient); - cheats.stopPrank(); - - IDelayedWithdrawalRouter.UserDelayedWithdrawals memory userWithdrawalsAfter = delayedWithdrawalRouter.userWithdrawals(recipient); - - // verify that no new 'delayedWithdrawal' was created - require(userWithdrawalsAfter.delayedWithdrawals.length == userWithdrawalsBefore.delayedWithdrawals.length, - "userWithdrawalsAfter.delayedWithdrawals.length != userWithdrawalsBefore.delayedWithdrawals.length"); - } - - function testCreateDelayedWithdrawalZeroAddress(address podOwner) external filterFuzzedAddressInputs(podOwner) { - uint224 delayedWithdrawalAmount = 0; - address podAddress = address(eigenPodManagerMock.getPod(podOwner)); - cheats.assume(podAddress != address(proxyAdmin)); - cheats.startPrank(podAddress); - cheats.expectRevert(bytes("DelayedWithdrawalRouter.createDelayedWithdrawal: recipient cannot be zero address")); - delayedWithdrawalRouter.createDelayedWithdrawal{value: delayedWithdrawalAmount}(podOwner, address(0)); - } - - function testCreateDelayedWithdrawalFromNonPodAddress(address podOwner, address nonPodAddress) external filterFuzzedAddressInputs(podOwner) filterFuzzedAddressInputs(nonPodAddress) { - uint224 delayedWithdrawalAmount = 0; - address podAddress = address(eigenPodManagerMock.getPod(podOwner)); - cheats.assume(nonPodAddress != podAddress); - cheats.assume(nonPodAddress != address(proxyAdmin)); - - cheats.startPrank(nonPodAddress); - cheats.expectRevert(bytes("DelayedWithdrawalRouter.onlyEigenPod: not podOwner's EigenPod")); - delayedWithdrawalRouter.createDelayedWithdrawal{value: delayedWithdrawalAmount}(podOwner, address(0)); - } - - function testClaimDelayedWithdrawals( - uint8 delayedWithdrawalsToCreate, - uint8 maxNumberOfDelayedWithdrawalsToClaim, - uint256 pseudorandomNumber_, - address recipient, - bool useOverloadedFunction - ) - public filterFuzzedAddressInputs(recipient) - { - // filter contracts out of fuzzed recipient input, since most don't implement a payable fallback function - cheats.assume(!Address.isContract(recipient)); - // filter out precompile addresses (they won't accept delayedWithdrawal either) - cheats.assume(uint160(recipient) > 256); - // filter fuzzed inputs to avoid running out of gas & excessive test run-time - cheats.assume(delayedWithdrawalsToCreate <= 32); - - address podOwner = address(88888); - - // create the delayedWithdrawals - _pseudorandomNumber = pseudorandomNumber_; - uint8 delayedWithdrawalsCreated; - for (uint256 i = 0; i < delayedWithdrawalsToCreate; ++i) { - uint224 delayedWithdrawalAmount = uint224(_getPseudorandomNumber()); - if (delayedWithdrawalAmount != 0) { - testCreateDelayedWithdrawalNonzeroAmount(delayedWithdrawalAmount, podOwner, recipient); - delayedWithdrawalAmounts.push(delayedWithdrawalAmount); - delayedWithdrawalsCreated += 1; - } - } - - IDelayedWithdrawalRouter.UserDelayedWithdrawals memory userWithdrawalsBefore = delayedWithdrawalRouter.userWithdrawals(recipient); - uint256 userBalanceBefore = recipient.balance; - - // pre-condition check - require(userWithdrawalsBefore.delayedWithdrawals.length == delayedWithdrawalsCreated, "userWithdrawalsBefore.delayedWithdrawals.length != delayedWithdrawalsCreated"); - - // roll forward the block number enough to make the delayedWithdrawals claimable - cheats.roll(block.number + delayedWithdrawalRouter.withdrawalDelayBlocks()); - - // find the expected number of completed withdrawals and the expected total withdrawal amount - uint256 numberOfDelayedWithdrawalsThatShouldBeCompleted = - (maxNumberOfDelayedWithdrawalsToClaim > delayedWithdrawalsCreated) ? delayedWithdrawalsCreated : maxNumberOfDelayedWithdrawalsToClaim; - uint256 totalDelayedWithdrawalAmount = 0; - for (uint256 i = 0; i < numberOfDelayedWithdrawalsThatShouldBeCompleted; ++i) { - totalDelayedWithdrawalAmount += delayedWithdrawalAmounts[i]; - } - - // claim the delayedWithdrawals - if (delayedWithdrawalsCreated != 0) { - if (useOverloadedFunction) { - cheats.expectEmit(true, true, true, true, address(delayedWithdrawalRouter)); - emit DelayedWithdrawalsClaimed(recipient, totalDelayedWithdrawalAmount, numberOfDelayedWithdrawalsThatShouldBeCompleted); - delayedWithdrawalRouter.claimDelayedWithdrawals(recipient, maxNumberOfDelayedWithdrawalsToClaim); - } else { - cheats.startPrank(recipient); - cheats.expectEmit(true, true, true, true, address(delayedWithdrawalRouter)); - emit DelayedWithdrawalsClaimed(recipient, totalDelayedWithdrawalAmount, numberOfDelayedWithdrawalsThatShouldBeCompleted); - delayedWithdrawalRouter.claimDelayedWithdrawals(maxNumberOfDelayedWithdrawalsToClaim); - cheats.stopPrank(); - } - } - - IDelayedWithdrawalRouter.UserDelayedWithdrawals memory userWithdrawalsAfter = delayedWithdrawalRouter.userWithdrawals(recipient); - uint256 userBalanceAfter = recipient.balance; - - // post-conditions - require(userWithdrawalsAfter.delayedWithdrawalsCompleted == userWithdrawalsBefore.delayedWithdrawalsCompleted + numberOfDelayedWithdrawalsThatShouldBeCompleted, - "userWithdrawalsAfter.delayedWithdrawalsCompleted != userWithdrawalsBefore.delayedWithdrawalsCompleted + numberOfDelayedWithdrawalsThatShouldBeCompleted"); - require(userBalanceAfter == userBalanceBefore + totalDelayedWithdrawalAmount, - "userBalanceAfter != userBalanceBefore + totalDelayedWithdrawalAmount"); - } - - /// @notice This function is used to test the getter function 'getClaimableDelayedWithdrawals' - function testDelayedWithdrawalsGetterFunctions(uint8 delayedWithdrawalsToCreate, uint224 delayedWithdrawalAmount, address recipient) - public filterFuzzedAddressInputs(recipient) - { - cheats.assume(delayedWithdrawalAmount != 0); - cheats.assume(delayedWithdrawalsToCreate > 5); - // filter contracts out of fuzzed recipient input, since most don't implement a payable fallback function - cheats.assume(!Address.isContract(recipient)); - // filter out precompile addresses (they won't accept delayedWithdrawal either) - cheats.assume(uint160(recipient) > 256); - // filter fuzzed inputs to avoid running out of gas & excessive test run-time - cheats.assume(delayedWithdrawalsToCreate <= 32); - - address podOwner = address(88888); - - // create the delayedWithdrawals - uint8 delayedWithdrawalsCreated; - for (uint256 i = 0; i < delayedWithdrawalsToCreate; ++i) { - testCreateDelayedWithdrawalNonzeroAmount(delayedWithdrawalAmount, podOwner, recipient); - delayedWithdrawalAmounts.push(delayedWithdrawalAmount); - delayedWithdrawalsCreated += 1; - cheats.roll(block.number + 1); // make sure each delayedWithdrawal has a unique block number - } - - require(delayedWithdrawalRouter.getUserDelayedWithdrawals(recipient).length == delayedWithdrawalsCreated, "Incorrect number delayed withdrawals"); - - cheats.roll(block.number + delayedWithdrawalRouter.withdrawalDelayBlocks() - delayedWithdrawalsToCreate); - for (uint256 i = 1; i <= delayedWithdrawalsToCreate; ++i) { - uint256 length = delayedWithdrawalRouter.getClaimableUserDelayedWithdrawals(recipient).length; - require(length == i, "Incorrect number of claimable delayed withdrawals"); - cheats.roll(block.number + 1); - } - require(delayedWithdrawalRouter.getClaimableUserDelayedWithdrawals(recipient).length == delayedWithdrawalsCreated, - "Incorrect number of claimable delayed withdrawals"); - } - - - /** - * @notice Creates a set of delayedWithdrawals of length (2 * `delayedWithdrawalsToCreate`), - * where only the first half is claimable, claims using `maxNumberOfDelayedWithdrawalsToClaim` input, - * and checks that only appropriate delayedWithdrawals were claimed. - */ - function testClaimDelayedWithdrawalsSomeUnclaimable(uint8 delayedWithdrawalsToCreate, uint8 maxNumberOfDelayedWithdrawalsToClaim, bool useOverloadedFunction) - external - { - // filter fuzzed inputs to avoid running out of gas & excessive test run-time - cheats.assume(delayedWithdrawalsToCreate <= 32); - - address podOwner = address(88888); - address recipient = address(22222); - - // create the first set of delayedWithdrawals - _pseudorandomNumber = 1554; - uint256 delayedWithdrawalsCreated_1; - for (uint256 i = 0; i < delayedWithdrawalsToCreate; ++i) { - uint224 delayedWithdrawalAmount = uint224(_getPseudorandomNumber()); - if (delayedWithdrawalAmount != 0) { - testCreateDelayedWithdrawalNonzeroAmount(delayedWithdrawalAmount, podOwner, recipient); - delayedWithdrawalAmounts.push(delayedWithdrawalAmount); - delayedWithdrawalsCreated_1 += 1; - } - } - - // roll forward the block number half of the delay window - cheats.roll(block.number + delayedWithdrawalRouter.withdrawalDelayBlocks() / 2); - - // create the second set of delayedWithdrawals - uint256 delayedWithdrawalsCreated_2; - for (uint256 i = 0; i < delayedWithdrawalsToCreate; ++i) { - uint224 delayedWithdrawalAmount = uint224(_getPseudorandomNumber()); - if (delayedWithdrawalAmount != 0) { - testCreateDelayedWithdrawalNonzeroAmount(delayedWithdrawalAmount, podOwner, recipient); - delayedWithdrawalAmounts.push(delayedWithdrawalAmount); - delayedWithdrawalsCreated_2 += 1; - } - } - - // roll forward the block number half of the delay window -- the first set of delayedWithdrawals should now be claimable, while the second shouldn't be! - cheats.roll(block.number + delayedWithdrawalRouter.withdrawalDelayBlocks() / 2); - - IDelayedWithdrawalRouter.UserDelayedWithdrawals memory userWithdrawalsBefore = delayedWithdrawalRouter.userWithdrawals(recipient); - uint256 userBalanceBefore = recipient.balance; - - // pre-condition check - require(userWithdrawalsBefore.delayedWithdrawals.length == delayedWithdrawalsCreated_1 + delayedWithdrawalsCreated_2, - "userWithdrawalsBefore.delayedWithdrawals.length != delayedWithdrawalsCreated_1 + delayedWithdrawalsCreated_2"); - - // find the expected number of completed withdrawals and the expected total withdrawal amount - uint256 numberOfDelayedWithdrawalsThatShouldBeCompleted = - (maxNumberOfDelayedWithdrawalsToClaim > delayedWithdrawalsCreated_1) ? delayedWithdrawalsCreated_1 : maxNumberOfDelayedWithdrawalsToClaim; - uint256 totalDelayedWithdrawalAmount = 0; - for (uint256 i = 0; i < numberOfDelayedWithdrawalsThatShouldBeCompleted; ++i) { - totalDelayedWithdrawalAmount += delayedWithdrawalAmounts[i]; - } - - // claim the delayedWithdrawals - if (delayedWithdrawalsCreated_1 + delayedWithdrawalsCreated_2 != 0) { - if (useOverloadedFunction) { - cheats.expectEmit(true, true, true, true, address(delayedWithdrawalRouter)); - emit DelayedWithdrawalsClaimed(recipient, totalDelayedWithdrawalAmount, numberOfDelayedWithdrawalsThatShouldBeCompleted); - delayedWithdrawalRouter.claimDelayedWithdrawals(recipient, maxNumberOfDelayedWithdrawalsToClaim); - } else { - cheats.startPrank(recipient); - cheats.expectEmit(true, true, true, true, address(delayedWithdrawalRouter)); - emit DelayedWithdrawalsClaimed(recipient, totalDelayedWithdrawalAmount, numberOfDelayedWithdrawalsThatShouldBeCompleted); - delayedWithdrawalRouter.claimDelayedWithdrawals(maxNumberOfDelayedWithdrawalsToClaim); - cheats.stopPrank(); - } - } - - IDelayedWithdrawalRouter.UserDelayedWithdrawals memory userWithdrawalsAfter = delayedWithdrawalRouter.userWithdrawals(recipient); - uint256 userBalanceAfter = recipient.balance; - - // post-conditions - require(userWithdrawalsAfter.delayedWithdrawalsCompleted == userWithdrawalsBefore.delayedWithdrawalsCompleted + numberOfDelayedWithdrawalsThatShouldBeCompleted, - "userWithdrawalsAfter.delayedWithdrawalsCompleted != userWithdrawalsBefore.delayedWithdrawalsCompleted + numberOfDelayedWithdrawalsThatShouldBeCompleted"); - require(userBalanceAfter == userBalanceBefore + totalDelayedWithdrawalAmount, - "userBalanceAfter != userBalanceBefore + totalDelayedWithdrawalAmount"); - } - - function testClaimDelayedWithdrawals_NoneToClaim_AttemptToClaimZero(uint256 pseudorandomNumber_, bool useOverloadedFunction) external { - uint8 delayedWithdrawalsToCreate = 0; - uint8 maxNumberOfDelayedWithdrawalsToClaim = 0; - address recipient = address(22222); - testClaimDelayedWithdrawals(delayedWithdrawalsToCreate, maxNumberOfDelayedWithdrawalsToClaim, pseudorandomNumber_, recipient, useOverloadedFunction); - } - - function testClaimDelayedWithdrawals_NoneToClaim_AttemptToClaimNonzero(uint256 pseudorandomNumber_, bool useOverloadedFunction) external { - uint8 delayedWithdrawalsToCreate = 0; - uint8 maxNumberOfDelayedWithdrawalsToClaim = 2; - address recipient = address(22222); - testClaimDelayedWithdrawals(delayedWithdrawalsToCreate, maxNumberOfDelayedWithdrawalsToClaim, pseudorandomNumber_, recipient, useOverloadedFunction); - } - - function testClaimDelayedWithdrawals_NonzeroToClaim_AttemptToClaimZero(uint256 pseudorandomNumber_, bool useOverloadedFunction) external { - uint8 delayedWithdrawalsToCreate = 2; - uint8 maxNumberOfDelayedWithdrawalsToClaim = 0; - address recipient = address(22222); - testClaimDelayedWithdrawals(delayedWithdrawalsToCreate, maxNumberOfDelayedWithdrawalsToClaim, pseudorandomNumber_, recipient, useOverloadedFunction); - } - - function testClaimDelayedWithdrawals_NonzeroToClaim_AttemptToClaimNonzero( - uint8 maxNumberOfDelayedWithdrawalsToClaim, uint256 pseudorandomNumber_, bool useOverloadedFunction - )external { - uint8 delayedWithdrawalsToCreate = 2; - address recipient = address(22222); - testClaimDelayedWithdrawals(delayedWithdrawalsToCreate, maxNumberOfDelayedWithdrawalsToClaim, pseudorandomNumber_, recipient, useOverloadedFunction); - } - - function testClaimDelayedWithdrawals_RevertsOnAttemptingReentrancy(bool useOverloadedFunction) external { - uint8 maxNumberOfDelayedWithdrawalsToClaim = 1; - address recipient = address(reenterer); - address podOwner = address(reenterer); - - // create the delayedWithdrawal - uint224 delayedWithdrawalAmount = 123; - testCreateDelayedWithdrawalNonzeroAmount(delayedWithdrawalAmount, podOwner, recipient); - - // roll forward the block number enough to make the delayedWithdrawal claimable - cheats.roll(block.number + delayedWithdrawalRouter.withdrawalDelayBlocks()); - - // prepare the Reenterer contract - address targetToUse = address(delayedWithdrawalRouter); - uint256 msgValueToUse = 0; - bytes memory expectedRevertDataToUse = bytes("ReentrancyGuard: reentrant call"); - bytes memory callDataToUse; - if (useOverloadedFunction) { - callDataToUse = abi.encodeWithSignature( - "claimDelayedWithdrawals(address,uint256)", address(22222), maxNumberOfDelayedWithdrawalsToClaim); - } else { - callDataToUse = abi.encodeWithSignature( - "claimDelayedWithdrawals(uint256)", maxNumberOfDelayedWithdrawalsToClaim); - } - reenterer.prepare(targetToUse, msgValueToUse, callDataToUse, expectedRevertDataToUse); - - if (useOverloadedFunction) { - delayedWithdrawalRouter.claimDelayedWithdrawals(recipient, maxNumberOfDelayedWithdrawalsToClaim); - } else { - cheats.startPrank(recipient); - delayedWithdrawalRouter.claimDelayedWithdrawals(maxNumberOfDelayedWithdrawalsToClaim); - cheats.stopPrank(); - } - } - - function testClaimDelayedWithdrawals_RevertsWhenPaused(bool useOverloadedFunction) external { - uint8 maxNumberOfDelayedWithdrawalsToClaim = 1; - address recipient = address(22222); - - // pause delayedWithdrawal claims - cheats.startPrank(pauser); - delayedWithdrawalRouter.pause(2 ** PAUSED_PAYMENT_CLAIMS); - cheats.stopPrank(); - - cheats.expectRevert(bytes("Pausable: index is paused")); - if (useOverloadedFunction) { - delayedWithdrawalRouter.claimDelayedWithdrawals(recipient, maxNumberOfDelayedWithdrawalsToClaim); - } else { - cheats.startPrank(recipient); - delayedWithdrawalRouter.claimDelayedWithdrawals(maxNumberOfDelayedWithdrawalsToClaim); - cheats.stopPrank(); - } - } - - function testSetWithdrawalDelayBlocks(uint16 valueToSet) external { - // filter fuzzed inputs to allowed amounts - cheats.assume(valueToSet <= delayedWithdrawalRouter.MAX_WITHDRAWAL_DELAY_BLOCKS()); - - // set the `withdrawalDelayBlocks` variable - cheats.startPrank(delayedWithdrawalRouter.owner()); - uint256 previousValue = delayedWithdrawalRouter.withdrawalDelayBlocks(); - cheats.expectEmit(true, true, true, true, address(delayedWithdrawalRouter)); - emit WithdrawalDelayBlocksSet(previousValue, uint256(valueToSet)); - delayedWithdrawalRouter.setWithdrawalDelayBlocks(valueToSet); - cheats.stopPrank(); - require(delayedWithdrawalRouter.withdrawalDelayBlocks() == valueToSet, "delayedWithdrawalRouter.withdrawalDelayBlocks() != valueToSet"); - } - - function testSetWithdrawalDelayBlocksRevertsWhenCalledByNotOwner(address notOwner) filterFuzzedAddressInputs(notOwner) external { - cheats.assume(notOwner != delayedWithdrawalRouter.owner()); - - uint256 valueToSet = 1; - // set the `withdrawalDelayBlocks` variable - cheats.startPrank(notOwner); - cheats.expectRevert(bytes("Ownable: caller is not the owner")); - delayedWithdrawalRouter.setWithdrawalDelayBlocks(valueToSet); - cheats.stopPrank(); - } - - function testSetWithdrawalDelayBlocksRevertsWhenInputValueTooHigh(uint256 valueToSet) external { - // filter fuzzed inputs to disallowed amounts - cheats.assume(valueToSet > delayedWithdrawalRouter.MAX_WITHDRAWAL_DELAY_BLOCKS()); - - // attempt to set the `withdrawalDelayBlocks` variable - cheats.startPrank(delayedWithdrawalRouter.owner()); - cheats.expectRevert(bytes("DelayedWithdrawalRouter._setWithdrawalDelayBlocks: newValue too large")); - delayedWithdrawalRouter.setWithdrawalDelayBlocks(valueToSet); - } - - function _getPseudorandomNumber() internal returns (uint256) { - _pseudorandomNumber = uint256(keccak256(abi.encode(_pseudorandomNumber))); - return _pseudorandomNumber; - } -} diff --git a/src/test/unit/DelegationUnit.t.sol b/src/test/unit/DelegationUnit.t.sol index 1c71723fa..79bf46daf 100644 --- a/src/test/unit/DelegationUnit.t.sol +++ b/src/test/unit/DelegationUnit.t.sol @@ -3114,7 +3114,6 @@ contract DelegationManagerUnitTests_completeQueuedWithdrawal is DelegationManage */ function test_Revert_WhenWithdrawalDelayBlocksNotPassed( uint256[] memory depositAmounts, - uint256 randSalt, bool receiveAsTokens ) public { cheats.assume(depositAmounts.length > 0 && depositAmounts.length <= 32); @@ -3168,7 +3167,7 @@ contract DelegationManagerUnitTests_completeQueuedWithdrawal is DelegationManage ( IDelegationManager.Withdrawal memory withdrawal, IERC20[] memory tokens, - bytes32 withdrawalRoot + // bytes32 withdrawalRoot ) = _setUpCompleteQueuedWithdrawalBeaconStrat({ staker: defaultStaker, withdrawer: defaultStaker, diff --git a/src/test/unit/EigenPod-PodManagerUnit.t.sol b/src/test/unit/EigenPod-PodManagerUnit.t.sol deleted file mode 100644 index ca33ffde0..000000000 --- a/src/test/unit/EigenPod-PodManagerUnit.t.sol +++ /dev/null @@ -1,648 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.12; - -import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; - -import "src/contracts/pods/EigenPodManager.sol"; -import "src/contracts/pods/EigenPod.sol"; -import "src/contracts/pods/EigenPodPausingConstants.sol"; - -import "src/test/utils/EigenLayerUnitTestSetup.sol"; -import "src/test/utils/ProofParsing.sol"; -import "src/test/harnesses/EigenPodManagerWrapper.sol"; -import "src/test/mocks/EigenPodMock.sol"; -import "src/test/mocks/Dummy.sol"; -import "src/test/mocks/ETHDepositMock.sol"; -import "src/test/mocks/DelayedWithdrawalRouterMock.sol"; -import "src/test/mocks/BeaconChainOracleMock.sol"; -import "src/test/mocks/Reenterer.sol"; -import "src/test/events/IEigenPodEvents.sol"; -import "src/test/events/IEigenPodManagerEvents.sol"; - -contract EigenPod_PodManager_UnitTests is EigenLayerUnitTestSetup { - // Contracts Under Test: EigenPodManager & EigenPod - EigenPod public eigenPod; - EigenPod public podImplementation; - IBeacon public eigenPodBeacon; - EigenPodManager public eigenPodManager; - EigenPodManager public eigenPodManagerImplementation; - EigenPodManagerWrapper public eigenPodManagerWrapper; // Implementation contract - - // Mocks - IETHPOSDeposit public ethPOSMock; - IDelayedWithdrawalRouter public delayedWithdrawalRouterMock; - BeaconChainOracleMock beaconChainOracle; - - // Constants - uint64 public constant MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = 32e9; - uint64 public constant GOERLI_GENESIS_TIME = 1616508000; - address public initialOwner = address(this); - - // Owner for which proofs are generated; eigenPod above is owned by this address - bytes internal constant beaconProxyBytecode = - hex"608060405260405161090e38038061090e83398101604081905261002291610460565b61002e82826000610035565b505061058a565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610520565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610520565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108e7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe919061053b565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c65782516103bf576001600160a01b0385163b6103bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d0565b6103d083836103d8565b949350505050565b8151156103e85781518083602001fd5b8060405162461bcd60e51b81526004016101699190610557565b80516001600160a01b038116811461041957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044f578181015183820152602001610437565b838111156100f95750506000910152565b6000806040838503121561047357600080fd5b61047c83610402565b60208401519092506001600160401b038082111561049957600080fd5b818501915085601f8301126104ad57600080fd5b8151818111156104bf576104bf61041e565b604051601f8201601f19908116603f011681019083821181831017156104e7576104e761041e565b8160405282815288602084870101111561050057600080fd5b610511836020830160208801610434565b80955050505050509250929050565b60006020828403121561053257600080fd5b6102c882610402565b6000825161054d818460208701610434565b9190910192915050565b6020815260008251806020840152610576816040850160208701610434565b601f01601f19169190910160400192915050565b61034e806105996000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102f260279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb9190610249565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b03168560405161014191906102a2565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020d578251610206576001600160a01b0385163b6102065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610217565b610217838361021f565b949350505050565b81511561022f5781518083602001fd5b8060405162461bcd60e51b81526004016101fd91906102be565b60006020828403121561025b57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028d578181015183820152602001610275565b8381111561029c576000848401525b50505050565b600082516102b4818460208701610272565b9190910192915050565b60208152600082518060208401526102dd816040850160208701610272565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d51e81d3bc5ed20a26aeb05dce7e825c503b2061aa78628027300c8d65b9d89a64736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564"; - address public constant podOwner = address(42000094993494); - - address public constant podAddress = address(0x49c486E3f4303bc11C02F952Fe5b08D0AB22D443); - - function setUp() public override virtual { - // Setup - EigenLayerUnitTestSetup.setUp(); - - // Deploy Mocks - ethPOSMock = new ETHPOSDepositMock(); - delayedWithdrawalRouterMock = new DelayedWithdrawalRouterMock(); - beaconChainOracle = new BeaconChainOracleMock(); - - // Deploy proxy contract for EPM - EmptyContract emptyContract = new EmptyContract(); - eigenPodManager = EigenPodManager( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - - // Deploy EigenPod Implementation and beacon - podImplementation = new EigenPod( - ethPOSMock, - delayedWithdrawalRouterMock, - eigenPodManager, - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - GOERLI_GENESIS_TIME - ); - - eigenPodBeacon = new UpgradeableBeacon(address(podImplementation)); - - // Deploy EigenPodManager implementation - eigenPodManagerWrapper = new EigenPodManagerWrapper( - ethPOSMock, - eigenPodBeacon, - strategyManagerMock, - slasherMock, - delegationManagerMock - ); - - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(eigenPodManager))), - address(eigenPodManagerWrapper), - abi.encodeWithSelector( - EigenPodManager.initialize.selector, - beaconChainOracle, - initialOwner, - pauserRegistry, - 0 /*initialPausedStatus*/ - ) - ); - - // Below is a hack to get the eigenPod address that proofs prove against - - // Deploy Proxy same way as EigenPodManager does - eigenPod = EigenPod(payable( - Create2.deploy( - 0, - bytes32(uint256(uint160(address(podOwner)))), - // set the beacon address to the eigenPodBeacon - abi.encodePacked(beaconProxyBytecode, abi.encode(eigenPodBeacon, "")) - ))); - - // Etch the eigenPod code to the address for which proofs are generated - bytes memory code = address(eigenPod).code; - cheats.etch(podAddress, code); - eigenPod = EigenPod(payable(podAddress)); - - // Store the eigenPodBeacon address in the eigenPod beacon proxy - bytes32 beaconSlot = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; - cheats.store(address(eigenPod), beaconSlot, bytes32(uint256(uint160(address(eigenPodBeacon))))); - - // Initialize pod - eigenPod.initialize(address(podOwner)); - - // Set storage in EPM - EigenPodManagerWrapper(address(eigenPodManager)).setPodAddress(podOwner, eigenPod); - - eigenPodManager.setDenebForkTimestamp(type(uint64).max); - } -} - -contract EigenPod_PodManager_UnitTests_EigenPodPausing is EigenPod_PodManager_UnitTests { - /** - * 1. verifyBalanceUpdates revert when PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE set - * 2. verifyAndProcessWithdrawals revert when PAUSED_EIGENPODS_VERIFY_WITHDRAWAL set - * 3. verifyWithdrawalCredentials revert when PAUSED_EIGENPODS_VERIFY_CREDENTIALS set - * 4. activateRestaking revert when PAUSED_EIGENPODS_VERIFY_CREDENTIALS set - */ - - /// @notice Index for flag that pauses creation of new EigenPods when set. See EigenPodManager code for details. - uint8 internal constant PAUSED_NEW_EIGENPODS = 0; - /// @notice Index for flag that pauses all withdrawal-of-restaked ETH related functionality `function *of the EigenPodManager* when set. See EigenPodManager code for details. - uint8 internal constant PAUSED_WITHDRAW_RESTAKED_ETH = 1; - - /// @notice Index for flag that pauses the deposit related functions *of the EigenPods* when set. see EigenPod code for details. - uint8 internal constant PAUSED_EIGENPODS_VERIFY_CREDENTIALS = 2; - /// @notice Index for flag that pauses the `verifyBalanceUpdate` function *of the EigenPods* when set. see EigenPod code for details. - uint8 internal constant PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE = 3; - /// @notice Index for flag that pauses the `verifyBeaconChainFullWithdrawal` function *of the EigenPods* when set. see EigenPod code for details. - uint8 internal constant PAUSED_EIGENPODS_VERIFY_WITHDRAWAL = 4; - - function test_verifyBalanceUpdates_revert_pausedEigenVerifyBalanceUpdate() public { - BeaconChainProofs.StateRootProof memory stateRootProofStruct; - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - bytes[] memory proofsArray = new bytes[](1); - uint40[] memory validatorIndices = new uint40[](1); - - // pause the contract - cheats.prank(address(pauser)); - eigenPodManager.pause(2 ** PAUSED_EIGENPODS_VERIFY_BALANCE_UPDATE); - - cheats.prank(address(podOwner)); - cheats.expectRevert(bytes("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager")); - eigenPod.verifyBalanceUpdates(0, validatorIndices, stateRootProofStruct, proofsArray, validatorFieldsArray); - } - - function test_verifyAndProcessWithdrawals_revert_pausedEigenVerifyWithdrawal() public { - BeaconChainProofs.StateRootProof memory stateRootProofStruct; - BeaconChainProofs.WithdrawalProof[] memory withdrawalProofsArray; - - bytes[] memory validatorFieldsProofArray = new bytes[](1); - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - bytes32[][] memory withdrawalFieldsArray = new bytes32[][](1); - - // pause the contract - cheats.prank(address(pauser)); - eigenPodManager.pause(2 ** PAUSED_EIGENPODS_VERIFY_WITHDRAWAL); - - cheats.prank(address(podOwner)); - cheats.expectRevert(bytes("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager")); - eigenPod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofsArray, - validatorFieldsProofArray, - validatorFieldsArray, - withdrawalFieldsArray - ); - } - - function test_verifyWithdrawalCredentials_revert_pausedEigenVerifyCredentials() public { - BeaconChainProofs.StateRootProof memory stateRootProofStruct; - - bytes32[][] memory validatorFieldsArray = new bytes32[][](1); - bytes[] memory proofsArray = new bytes[](1); - uint40[] memory validatorIndices = new uint40[](1); - - // pause the contract - cheats.prank(address(pauser)); - eigenPodManager.pause(2 ** PAUSED_EIGENPODS_VERIFY_CREDENTIALS); - - cheats.prank(address(podOwner)); - cheats.expectRevert(bytes("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager")); - eigenPod.verifyWithdrawalCredentials( - 0, - stateRootProofStruct, - validatorIndices, - proofsArray, - validatorFieldsArray - ); - } - - function test_activateRestaking_revert_pausedEigenVerifyCredentials() public { - // pause the contract - cheats.prank(address(pauser)); - eigenPodManager.pause(2 ** PAUSED_EIGENPODS_VERIFY_CREDENTIALS); - - cheats.prank(address(podOwner)); - cheats.expectRevert(bytes("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager")); - eigenPod.activateRestaking(); - } -} - -contract EigenPod_PodManager_UnitTests_EigenPod is EigenPod_PodManager_UnitTests { - /** - * @notice Tests function calls from EPM to EigenPod - * 1. Stake works when pod is deployed - * 2. Stake when pod is not deployed -> check that ethPOS deposit contract is correct for this and above test - */ - - bytes public constant pubkey = hex"88347ed1c492eedc97fc8c506a35d44d81f27a0c7a1c661b35913cfd15256c0cccbd34a83341f505c7de2983292f2cab"; - - function test_stake_podAlreadyDeployed(bytes memory signature, bytes32 depositDataRoot) public { - uint256 stakeAmount = 32e18; - - uint256 numPods = eigenPodManager.numPods(); - emit log_named_uint("numPods", numPods); - - cheats.startPrank(podOwner); - cheats.deal(podOwner, stakeAmount); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - } - - function test_stake_podNotDeployed(bytes memory signature, bytes32 depositDataRoot) public { - address newPodOwner = address(69696969696); - - uint256 stakeAmount = 32e18; - - cheats.startPrank(newPodOwner); - cheats.deal(newPodOwner, stakeAmount); - eigenPodManager.stake{value: stakeAmount}(pubkey, signature, depositDataRoot); - cheats.stopPrank(); - } -} - -contract EigenPod_PodManager_UnitTests_EigenPodManager is EigenPod_PodManager_UnitTests, ProofParsing, IEigenPodEvents { - /** - * @notice Tests function calls from EigenPod to EigenPodManager - * 1. Verify withdrawal credentials and call `recordBeaconChainETHBalanceUpdate` -> assert shares are updated - * 2. Do a full withdrawal and call `recordBeaconChainETHBalanceUpdate` -> assert shares are updated - * 3. Do a partial withdrawal and call `recordBeaconChainETHBalanceUpdate` -> assert shares are updated - * 4. Verify balance updates and call `recordBeaconChainEThBalanceUpdate` -> assert shares are updated - * 5. Withdraw restaked beacon chain ETH - */ - - using BeaconChainProofs for *; - - // Params to verify withdrawal credentials - BeaconChainProofs.StateRootProof stateRootProofStruct; - uint40[] validatorIndices; - bytes[] validatorFieldsProofs; - bytes32[][] validatorFields; - // BeaconChainProofs.BalanceUpdateProof[] balanceUpdateProof; - BeaconChainProofs.WithdrawalProof[] withdrawalProofs; - bytes32[][] withdrawalFields; - - function test_verifyWithdrawalCredentials() public { - // Arrange: Set up conditions to verify withdrawal credentials - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _setWithdrawalCredentialParams(); - - // Set oracle block root and warp time - _setOracleBlockRoot(); - cheats.warp(GOERLI_GENESIS_TIME + 1 days); - uint64 oracleTimestamp = uint64(block.timestamp); - - // Save state for checks - int256 initialShares = eigenPodManager.podOwnerShares(podOwner); - - // Act: Verify withdrawal credentials and record the balance update - cheats.prank(podOwner); - eigenPod.verifyWithdrawalCredentials( - oracleTimestamp, - stateRootProofStruct, - validatorIndices, - validatorFieldsProofs, - validatorFields - ); - - // Assert: Check that the shares are updated correctly - int256 updatedShares = eigenPodManager.podOwnerShares(podOwner); - assertTrue(updatedShares != initialShares, "Shares should be updated after verifying withdrawal credentials"); - assertEq(updatedShares, 32e18, "Shares should be 32ETH in wei after verifying withdrawal credentials"); - } - - function test_balanceUpdate_negativeSharesDelta() public { - // Verify withdrawal credentials - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _verifyWithdrawalCredentials(); - - // Set JSON - setJSON("src/test/test-data/balanceUpdateProof_balance28ETH_302913.json"); - bytes32 validatorPubkeyHash = validatorFields[0].getPubkeyHash(); - - // Set proof params, oracle block root, and warp time - _setBalanceUpdateParams(); - _setOracleBlockRoot(); - cheats.warp(GOERLI_GENESIS_TIME); - uint64 oracleTimestamp = uint64(block.timestamp); - - // Save state for checks - int256 initialShares = eigenPodManager.podOwnerShares(podOwner); - uint64 newValidatorBalance = validatorFields[0].getEffectiveBalanceGwei(); - - // Verify balance update - eigenPod.verifyBalanceUpdates( - oracleTimestamp, - validatorIndices, - stateRootProofStruct, - validatorFieldsProofs, - validatorFields - ); - - // Checks - int256 updatedShares = eigenPodManager.podOwnerShares(podOwner); - IEigenPod.ValidatorInfo memory validatorInfo = eigenPod.validatorPubkeyHashToInfo(validatorPubkeyHash); - assertEq(validatorInfo.restakedBalanceGwei, newValidatorBalance, "Restaked balance gwei is incorrect"); - assertLt(updatedShares - initialShares, 0, "Shares delta should be negative"); - int256 expectedSharesDiff = (int256(uint256(newValidatorBalance)) - int256(uint256(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR))) * 1e9; - assertEq(updatedShares - initialShares, expectedSharesDiff, "Shares delta should be equal to restaked balance"); - } - - function test_balanceUpdate_positiveSharesDelta() public { - // Verify withdrawal credentials - setJSON("./src/test/test-data/withdrawal_credential_proof_302913_30ETHBalance.json"); - _verifyWithdrawalCredentials(); - - // Set JSON - setJSON("src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); - bytes32 validatorPubkeyHash = validatorFields[0].getPubkeyHash(); - - // Set proof params, oracle block root, and warp time - _setBalanceUpdateParams(); - _setOracleBlockRoot(); - cheats.warp(GOERLI_GENESIS_TIME); - uint64 oracleTimestamp = uint64(block.timestamp); - - // Save state for checks - int256 initialShares = eigenPodManager.podOwnerShares(podOwner); - uint64 newValidatorBalance = validatorFields[0].getEffectiveBalanceGwei(); - - // Verify balance update - eigenPod.verifyBalanceUpdates( - oracleTimestamp, - validatorIndices, - stateRootProofStruct, - validatorFieldsProofs, - validatorFields - ); - - // Checks - int256 updatedShares = eigenPodManager.podOwnerShares(podOwner); - IEigenPod.ValidatorInfo memory validatorInfo = eigenPod.validatorPubkeyHashToInfo(validatorPubkeyHash); - assertEq(validatorInfo.restakedBalanceGwei, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Restaked balance gwei should be max"); - assertGt(updatedShares - initialShares, 0, "Shares delta should be positive"); - assertEq(updatedShares, 32e18, "Shares should be 32ETH"); - assertEq(newValidatorBalance, 32e9, "validator balance should be 32e9 Gwei"); - } - - function test_fullWithdrawal_excess32ETH() public { - // Verify withdrawal credentials - setJSON("./src/test/test-data/withdrawal_credential_proof_302913_30ETHBalance.json"); - _verifyWithdrawalCredentials(); - - // Set JSON - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - bytes32 validatorPubkeyHash = validatorFields[0].getPubkeyHash(); - - // Set proof params, block root - _setWithdrawalProofParams(); - _setOracleBlockRoot(); - - // Save state for checks; deal EigenPod withdrawal router balance - uint64 withdrawalAmountGwei = Endian.fromLittleEndianUint64( - withdrawalFields[0][BeaconChainProofs.WITHDRAWAL_VALIDATOR_AMOUNT_INDEX] - ); - uint64 leftOverBalanceWEI = uint64(withdrawalAmountGwei - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) * 1e9; - cheats.deal(address(eigenPod), leftOverBalanceWEI); - int256 initialShares = eigenPodManager.podOwnerShares(podOwner); - - // Withdraw - eigenPod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofs, - validatorFieldsProofs, - validatorFields, - withdrawalFields - ); - - // Checks - int256 updatedShares = eigenPodManager.podOwnerShares(podOwner); - IEigenPod.ValidatorInfo memory validatorInfo = eigenPod.validatorPubkeyHashToInfo(validatorPubkeyHash); - assertEq(validatorInfo.restakedBalanceGwei, 0, "Restaked balance gwei should be 0"); - assertGt(updatedShares - initialShares, 0, "Shares diff should be positive"); - int256 expectedSharesDiff = (int256(uint256(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR))*1e9) - initialShares; - assertEq(updatedShares - initialShares, expectedSharesDiff, "Shares delta incorrect"); - assertEq(updatedShares, 32e18, "Shares should be 32e18"); - assertEq(address(delayedWithdrawalRouterMock).balance, leftOverBalanceWEI, "Incorrect amount sent to delayed withdrawal router"); - } - - function test_withdrawRestakedBeaconChainETH() public { - test_fullWithdrawal_excess32ETH(); - - // Deal eigenPod balance - max restaked balance - cheats.deal(address(eigenPod), 32 ether); - - cheats.startPrank(address(delegationManagerMock)); - vm.expectEmit(true, true, true, true); - emit RestakedBeaconChainETHWithdrawn(podOwner, 32 ether); - eigenPodManager.withdrawSharesAsTokens( - podOwner, - podOwner, - uint256(eigenPodManager.podOwnerShares(podOwner)) - ); - cheats.stopPrank(); - - // Checks - assertEq(address(podOwner).balance, 32 ether, "EigenPod balance should be 0"); - assertEq(address(eigenPod).balance, 0, "EigenPod balance should be 0"); - assertEq(eigenPod.withdrawableRestakedExecutionLayerGwei(), 0, "Restaked execution layer gwei should be 0"); - } - - function test_fullWithdrawal_less32ETH() public { - // Verify withdrawal credentials - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _verifyWithdrawalCredentials(); - - // Set JSON - setJSON("src/test/test-data/fullWithdrawalProof_Latest_28ETH.json"); - bytes32 validatorPubkeyHash = validatorFields[0].getPubkeyHash(); - - // Set proof params, block root - _setWithdrawalProofParams(); - _setOracleBlockRoot(); - - // Save State - uint64 withdrawalAmountGwei = Endian.fromLittleEndianUint64( - withdrawalFields[0][BeaconChainProofs.WITHDRAWAL_VALIDATOR_AMOUNT_INDEX] - ); - int256 initialShares = eigenPodManager.podOwnerShares(podOwner); - - // Withdraw - eigenPod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofs, - validatorFieldsProofs, - validatorFields, - withdrawalFields - ); - - // Checks - int256 updatedShares = eigenPodManager.podOwnerShares(podOwner); - IEigenPod.ValidatorInfo memory validatorInfo = eigenPod.validatorPubkeyHashToInfo(validatorPubkeyHash); - assertEq(validatorInfo.restakedBalanceGwei, 0, "Restaked balance gwei is incorrect"); - assertLt(updatedShares - initialShares, 0, "Shares delta should be negative"); - int256 expectedSharesDiff = (int256(uint256(withdrawalAmountGwei)) - int256(uint256(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR))) * 1e9; - assertEq(updatedShares - initialShares, expectedSharesDiff, "Shares delta incorrect"); - } - - function test_partialWithdrawal() public { - // Set JSON & params - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _verifyWithdrawalCredentials(); - - // Set JSON - setJSON("./src/test/test-data/partialWithdrawalProof_Latest.json"); - bytes32 validatorPubkeyHash = validatorFields[0].getPubkeyHash(); - - // Set proof params, block root - _setWithdrawalProofParams(); - _setOracleBlockRoot(); - - // Assert that partial withdrawal code path will be tested - assertLt(withdrawalProofs[0].getWithdrawalEpoch(), validatorFields[0].getWithdrawableEpoch(), "Withdrawal epoch should be less than the withdrawable epoch"); - - // Save state for checks; deal EigenPod withdrawal router balance - uint64 withdrawalAmountGwei = Endian.fromLittleEndianUint64( - withdrawalFields[0][BeaconChainProofs.WITHDRAWAL_VALIDATOR_AMOUNT_INDEX] - ); - cheats.deal(address(eigenPod), withdrawalAmountGwei * 1e9); // deal full withdrawal amount since it's a partial withdrawal - uint64 initialRestakedBalance = (eigenPod.validatorPubkeyHashToInfo(validatorPubkeyHash)).restakedBalanceGwei; - int256 initialShares = eigenPodManager.podOwnerShares(podOwner); - - // Withdraw - eigenPod.verifyAndProcessWithdrawals( - 0, - stateRootProofStruct, - withdrawalProofs, - validatorFieldsProofs, - validatorFields, - withdrawalFields - ); - - // Checks - int256 updatedShares = eigenPodManager.podOwnerShares(podOwner); - IEigenPod.ValidatorInfo memory validatorInfo = eigenPod.validatorPubkeyHashToInfo(validatorPubkeyHash); - assertEq(validatorInfo.restakedBalanceGwei, initialRestakedBalance, "Restaked balance gwei should be unchanged"); - assertEq(updatedShares - initialShares, 0, "Shares diff should be 0"); - assertEq(address(delayedWithdrawalRouterMock).balance, withdrawalAmountGwei * 1e9, "Incorrect amount sent to delayed withdrawal router"); - } - - // Helper Functions - function _getStateRootProof() internal returns (BeaconChainProofs.StateRootProof memory) { - return BeaconChainProofs.StateRootProof(getBeaconStateRoot(), abi.encodePacked(getStateRootProof())); - } - - function _setOracleBlockRoot() internal { - bytes32 latestBlockRoot = getLatestBlockRoot(); - //set beaconStateRoot - beaconChainOracle.setOracleBlockRootAtTimestamp(latestBlockRoot); - } - - function _verifyWithdrawalCredentials() internal { - _setWithdrawalCredentialParams(); - - // Set oracle block root and warp time - uint64 oracleTimestamp = 0; - _setOracleBlockRoot(); - cheats.warp(oracleTimestamp+=1); - - // Act: Verify withdrawal credentials and record the balance update - cheats.prank(podOwner); - eigenPod.verifyWithdrawalCredentials( - oracleTimestamp, - stateRootProofStruct, - validatorIndices, - validatorFieldsProofs, - validatorFields - ); - } - - function _setWithdrawalCredentialParams() internal { - // Reset arrays - delete validatorIndices; - delete validatorFields; - delete validatorFieldsProofs; - - // Set state proof struct - stateRootProofStruct = _getStateRootProof(); - - // Set validator indices - uint40 validatorIndex = uint40(getValidatorIndex()); - validatorIndices.push(validatorIndex); - - // Set validatorFieldsArray - validatorFields.push(getValidatorFields()); - - // Set validator fields proof - validatorFieldsProofs.push(abi.encodePacked(getWithdrawalCredentialProof())); // Validator fields are proven here - } - - function _setBalanceUpdateParams() internal { - // Reset arrays - delete validatorIndices; - delete validatorFields; - delete validatorFieldsProofs; - - // Set state proof struct - stateRootProofStruct = _getStateRootProof(); - - // Set validator indices - uint40 validatorIndex = uint40(getValidatorIndex()); - validatorIndices.push(validatorIndex); - - // Set validatorFieldsArray - validatorFields.push(getValidatorFields()); - - // Set validator fields proof - validatorFieldsProofs.push(abi.encodePacked(getBalanceUpdateProof())); // Validator fields are proven here - } - - function _setWithdrawalProofParams() internal { - // Reset arrays - delete validatorFields; - delete validatorFieldsProofs; - delete withdrawalFields; - delete withdrawalProofs; - - // Set state proof struct - stateRootProofStruct = _getStateRootProof(); - - // Set validatorFields - validatorFields.push(getValidatorFields()); - - // Set validator fields proof - validatorFieldsProofs.push(abi.encodePacked(getValidatorProof())); - - // Set withdrawal fields - withdrawalFields.push(getWithdrawalFields()); - - // Set withdrawal proofs - withdrawalProofs.push(_getWithdrawalProof()); - } - - // function _getBalanceUpdateProof() internal returns (BeaconChainProofs.BalanceUpdateProof memory) { - // bytes32 balanceRoot = getBalanceRoot(); - // BeaconChainProofs.BalanceUpdateProof memory proofs = BeaconChainProofs.BalanceUpdateProof( - // abi.encodePacked(getValidatorBalanceProof()), - // abi.encodePacked(getWithdrawalCredentialProof()), //technically this is to verify validator pubkey in the validator fields, but the WC proof is effectively the same so we use it here again. - // balanceRoot - // ); - // return proofs; - // } - - /// @notice this function just generates a valid proof so that we can test other functionalities of the withdrawal flow - function _getWithdrawalProof() internal returns (BeaconChainProofs.WithdrawalProof memory) { - { - bytes32 blockRoot = getBlockRoot(); - bytes32 slotRoot = getSlotRoot(); - bytes32 timestampRoot = getTimestampRoot(); - bytes32 executionPayloadRoot = getExecutionPayloadRoot(); - - return - BeaconChainProofs.WithdrawalProof( - abi.encodePacked(getWithdrawalProofCapella()), - abi.encodePacked(getSlotProof()), - abi.encodePacked(getExecutionPayloadProof()), - abi.encodePacked(getTimestampProofCapella()), - abi.encodePacked(getHistoricalSummaryProof()), - uint64(getBlockRootIndex()), - uint64(getHistoricalSummaryIndex()), - uint64(getWithdrawalIndex()), - blockRoot, - slotRoot, - timestampRoot, - executionPayloadRoot - ); - } - } -} - diff --git a/src/test/unit/EigenPodManagerUnit.t.sol b/src/test/unit/EigenPodManagerUnit.t.sol index bc553243c..b31d1d404 100644 --- a/src/test/unit/EigenPodManagerUnit.t.sol +++ b/src/test/unit/EigenPodManagerUnit.t.sol @@ -53,7 +53,6 @@ contract EigenPodManagerUnitTests is EigenLayerUnitTestSetup { address(eigenLayerProxyAdmin), abi.encodeWithSelector( EigenPodManager.initialize.selector, - IBeaconChainOracle(address(0)) /*beaconChainOracle*/, initialOwner, pauserRegistry, 0 /*initialPausedStatus*/ @@ -110,7 +109,6 @@ contract EigenPodManagerUnitTests_Initialization_Setters is EigenPodManagerUnitT function test_initialization() public { // Check max pods, beacon chain, owner, and pauser - assertEq(address(eigenPodManager.beaconChainOracle()), address(IBeaconChainOracle(address(0))), "Initialization: beacon chain oracle incorrect"); assertEq(eigenPodManager.owner(), initialOwner, "Initialization: owner incorrect"); assertEq(address(eigenPodManager.pauserRegistry()), address(pauserRegistry), "Initialization: pauser registry incorrect"); assertEq(eigenPodManager.paused(), 0, "Initialization: paused value not 0"); @@ -126,57 +124,10 @@ contract EigenPodManagerUnitTests_Initialization_Setters is EigenPodManagerUnitT function test_initialize_revert_alreadyInitialized() public { cheats.expectRevert("Initializable: contract is already initialized"); eigenPodManager.initialize( - IBeaconChainOracle(address(0)) /*beaconChainOracle*/, initialOwner, pauserRegistry, 0 /*initialPausedStatus*/); } - - /******************************************************************************* - Setters - *******************************************************************************/ - - function testFuzz_updateBeaconChainOracle_revert_notOwner(address notOwner) public filterFuzzedAddressInputs(notOwner) { - cheats.assume(notOwner != initialOwner); - cheats.prank(notOwner); - cheats.expectRevert("Ownable: caller is not the owner"); - eigenPodManager.updateBeaconChainOracle(IBeaconChainOracle(address(1))); - } - - function test_updateBeaconChainOracle() public { - // Set new beacon chain oracle - IBeaconChainOracle newBeaconChainOracle = IBeaconChainOracle(address(1)); - cheats.prank(initialOwner); - cheats.expectEmit(true, true, true, true); - emit BeaconOracleUpdated(address(newBeaconChainOracle)); - eigenPodManager.updateBeaconChainOracle(newBeaconChainOracle); - - // Check storage update - assertEq(address(eigenPodManager.beaconChainOracle()), address(newBeaconChainOracle), "Beacon chain oracle not updated"); - } - - function test_setDenebForkTimestamp(uint64 denebForkTimestamp) public { - cheats.assume(denebForkTimestamp != 0); - cheats.assume(denebForkTimestamp != type(uint64).max); - cheats.prank(initialOwner); - - cheats.expectEmit(true, true, true, true); - emit DenebForkTimestampUpdated(denebForkTimestamp); - eigenPodManager.setDenebForkTimestamp(denebForkTimestamp); - assertEq(eigenPodManager.denebForkTimestamp(), denebForkTimestamp, "fork timestamp not set correctly"); - } - - function test_setDenebForkTimestamp_Twice(uint64 timestamp1, uint64 timestamp2) public { - cheats.assume(timestamp1 != 0); - cheats.assume(timestamp2 != 0); - cheats.assume(timestamp1 != type(uint64).max); - cheats.assume(timestamp2 != type(uint64).max); - cheats.prank(initialOwner); - - eigenPodManager.setDenebForkTimestamp(timestamp1); - cheats.expectRevert(bytes("EigenPodManager.setDenebForkTimestamp: cannot set denebForkTimestamp more than once")); - eigenPodManager.setDenebForkTimestamp(timestamp2); - } } contract EigenPodManagerUnitTests_CreationTests is EigenPodManagerUnitTests, IEigenPodManagerEvents { @@ -477,6 +428,8 @@ contract EigenPodManagerUnitTests_BeaconChainETHBalanceUpdateTests is EigenPodMa // Update balance cheats.expectEmit(true, true, true, true); emit PodSharesUpdated(defaultStaker, scaledSharesDelta); + cheats.expectEmit(true, true, true, true); + emit NewTotalShares(defaultStaker, scaledSharesBefore + scaledSharesDelta); cheats.prank(address(defaultPod)); eigenPodManager.recordBeaconChainETHBalanceUpdate(defaultStaker, scaledSharesDelta); diff --git a/src/test/unit/EigenPodUnit.t.sol b/src/test/unit/EigenPodUnit.t.sol index 6af23d1bd..6314a107c 100644 --- a/src/test/unit/EigenPodUnit.t.sol +++ b/src/test/unit/EigenPodUnit.t.sol @@ -5,57 +5,65 @@ import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import "@openzeppelin/contracts/utils/Create2.sol"; import "src/contracts/pods/EigenPod.sol"; +import "src/contracts/pods/EigenPodPausingConstants.sol"; import "src/test/mocks/ETHDepositMock.sol"; -import "src/test/mocks/DelayedWithdrawalRouterMock.sol"; import "src/test/mocks/ERC20Mock.sol"; import "src/test/harnesses/EigenPodHarness.sol"; import "src/test/utils/ProofParsing.sol"; import "src/test/utils/EigenLayerUnitTestSetup.sol"; import "src/test/events/IEigenPodEvents.sol"; -contract EigenPodUnitTests is EigenLayerUnitTestSetup { +import "src/test/integration/mocks/BeaconChainMock.t.sol"; +import "src/test/integration/mocks/EIP_4788_Oracle_Mock.t.sol"; +import "src/test/utils/EigenPodUser.t.sol"; +import "src/test/events/IEigenPodEvents.sol"; + + +contract EigenPodUnitTests is EigenLayerUnitTestSetup, EigenPodPausingConstants, IEigenPodEvents { + using Strings for *; + using BytesLib for bytes; + using BeaconChainProofs for *; + // Contract Under Test: EigenPod EigenPod public eigenPod; EigenPod public podImplementation; IBeacon public eigenPodBeacon; - // Mocks - IETHPOSDeposit public ethPOSDepositMock; - IDelayedWithdrawalRouter public delayedWithdrawalRouterMock; + // BeaconChain Mock Setup + TimeMachine public timeMachine; + ETHPOSDepositMock ethPOSDepositMock; + BeaconChainMock public beaconChain; + EIP_4788_Oracle_Mock constant EIP_4788_ORACLE = EIP_4788_Oracle_Mock(0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02); - // Address of pod for which proofs were generated - address podAddress = address(0x49c486E3f4303bc11C02F952Fe5b08D0AB22D443); + uint256 public numStakers; + address defaultProofSubmitter = cheats.addr(uint256(0xDEADBEEF)); + + // Beacon chain genesis time when running locally + // Multiple of 12 for sanity's sake + uint64 constant GENESIS_TIME_LOCAL = 1 hours * 12; + uint256 constant TIME_TILL_STALE_BALANCE = 2 weeks; - bool IS_DENEB = false; - - // Constants - // uint32 public constant WITHDRAWAL_DELAY_BLOCKS = 7 days / 12 seconds; - uint64 public constant MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = 32e9; - // uint64 public constant RESTAKED_BALANCE_OFFSET_GWEI = 75e7; - uint64 public constant GOERLI_GENESIS_TIME = 1616508000; - // uint64 public constant SECONDS_PER_SLOT = 12; - bytes internal constant beaconProxyBytecode = hex"608060405260405161090e38038061090e83398101604081905261002291610460565b61002e82826000610035565b505061058a565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610520565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610520565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108e7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe919061053b565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c65782516103bf576001600160a01b0385163b6103bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d0565b6103d083836103d8565b949350505050565b8151156103e85781518083602001fd5b8060405162461bcd60e51b81526004016101699190610557565b80516001600160a01b038116811461041957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044f578181015183820152602001610437565b838111156100f95750506000910152565b6000806040838503121561047357600080fd5b61047c83610402565b60208401519092506001600160401b038082111561049957600080fd5b818501915085601f8301126104ad57600080fd5b8151818111156104bf576104bf61041e565b604051601f8201601f19908116603f011681019083821181831017156104e7576104e761041e565b8160405282815288602084870101111561050057600080fd5b610511836020830160208801610434565b80955050505050509250929050565b60006020828403121561053257600080fd5b6102c882610402565b6000825161054d818460208701610434565b9190910192915050565b6020815260008251806020840152610576816040850160208701610434565b601f01601f19169190910160400192915050565b61034e806105996000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102f260279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb9190610249565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b03168560405161014191906102a2565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020d578251610206576001600160a01b0385163b6102065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610217565b610217838361021f565b949350505050565b81511561022f5781518083602001fd5b8060405162461bcd60e51b81526004016101fd91906102be565b60006020828403121561025b57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028d578181015183820152602001610275565b8381111561029c576000848401525b50505050565b600082516102b4818460208701610272565b9190910192915050565b60208152600082518060208401526102dd816040850160208701610272565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d51e81d3bc5ed20a26aeb05dce7e825c503b2061aa78628027300c8d65b9d89a64736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564"; - address public podOwner = address(this); function setUp() public override virtual { // Setup EigenLayerUnitTestSetup.setUp(); - // Deploy mocks + // Create time machine and beacon chain. Set block time to beacon chain genesis time + // beaconChainMock will also etch 4788 precompile ethPOSDepositMock = new ETHPOSDepositMock(); - delayedWithdrawalRouterMock = new DelayedWithdrawalRouterMock(); + cheats.warp(GENESIS_TIME_LOCAL); + timeMachine = new TimeMachine(); + beaconChain = new BeaconChainMock(EigenPodManager(address(eigenPodManagerMock)), GENESIS_TIME_LOCAL); // Deploy EigenPod podImplementation = new EigenPod( ethPOSDepositMock, - delayedWithdrawalRouterMock, eigenPodManagerMock, - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - GOERLI_GENESIS_TIME + GENESIS_TIME_LOCAL ); // Deploy Beacon @@ -70,10 +78,8 @@ contract EigenPodUnitTests is EigenLayerUnitTestSetup { abi.encodePacked(beaconProxyBytecode, abi.encode(eigenPodBeacon, "")) ))); - // Etch the eigenPod code to the address for which proofs are generated - bytes memory code = address(eigenPod).code; - cheats.etch(podAddress, code); - eigenPod = EigenPod(payable(podAddress)); + // Etch 4788 precompile + cheats.etch(address(EIP_4788_ORACLE), type(EIP_4788_Oracle_Mock).runtimeCode); // Store the eigenPodBeacon address in the eigenPod beacon proxy bytes32 beaconSlot = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; @@ -81,59 +87,313 @@ contract EigenPodUnitTests is EigenLayerUnitTestSetup { // Initialize pod eigenPod.initialize(address(this)); + + // Set a proof submitter + eigenPod.setProofSubmitter(defaultProofSubmitter); } + /******************************************************************************* + EIGENPOD Helpers + *******************************************************************************/ - /// @notice Post-M2, all new deployed eigen pods will have restaked set to true - modifier hasNotRestaked() { - // Write hasRestaked as false. hasRestaked in slot 52 - bytes32 slot = bytes32(uint256(52)); - bytes32 value = bytes32(0); // 0 == false - cheats.store(address(eigenPod), slot, value); + modifier timewarp() { + uint curState = timeMachine.warpToLast(); _; + timeMachine.warpToPresent(curState); + } + + function _seedPodWithETH(uint256 ethAmount) internal { + cheats.deal(address(this), ethAmount); + bool result; + bytes memory data; + (result, data) = address(eigenPod).call{value: ethAmount}(""); + } + + function _newEigenPodStaker(uint256 rand) internal returns (EigenPodUser, uint256) { + string memory stakerName; + + EigenPodUser staker; + + stakerName = string.concat("Staker", numStakers.toString()); + staker = new EigenPodUser(stakerName); + + uint256 amount = bound(rand, 1 ether, 640 ether); + cheats.deal(address(staker), amount); + + numStakers++; + return (staker, amount); + } + + /// @dev Opposite of Endian.fromLittleEndianUint64 + function _toLittleEndianUint64(uint64 num) internal pure returns (bytes32) { + uint256 lenum; + + // Rearrange the bytes from big-endian to little-endian format + lenum |= uint256((num & 0xFF) << 56); + lenum |= uint256((num & 0xFF00) << 40); + lenum |= uint256((num & 0xFF0000) << 24); + lenum |= uint256((num & 0xFF000000) << 8); + lenum |= uint256((num & 0xFF00000000) >> 8); + lenum |= uint256((num & 0xFF0000000000) >> 24); + lenum |= uint256((num & 0xFF000000000000) >> 40); + lenum |= uint256((num & 0xFF00000000000000) >> 56); + + // Shift the little-endian bytes to the end of the bytes32 value + return bytes32(lenum << 192); + } + + /******************************************************************************* + verifyWithdrawalCredentials Assertions + *******************************************************************************/ + + function assert_Snap_Added_ActiveValidatorCount( + EigenPodUser staker, + uint addedValidators, + string memory err + ) internal { + uint curActiveValidatorCount = _getActiveValidatorCount(staker); + uint prevActiveValidatorCount = _getPrevActiveValidatorCount(staker); + + assertEq(prevActiveValidatorCount + addedValidators, curActiveValidatorCount, err); + } + + function assert_Snap_Removed_ActiveValidatorCount( + EigenPodUser staker, + uint removedValidators, + string memory err + ) internal { + uint curActiveValidatorCount = _getActiveValidatorCount(staker); + uint prevActiveValidatorCount = _getPrevActiveValidatorCount(staker); + + assertEq(curActiveValidatorCount + removedValidators, prevActiveValidatorCount, err); + } + + function assert_Snap_Unchanged_ActiveValidatorCount( + EigenPodUser staker, + string memory err + ) internal { + uint curActiveValidatorCount = _getActiveValidatorCount(staker); + uint prevActiveValidatorCount = _getPrevActiveValidatorCount(staker); + + assertEq(curActiveValidatorCount, prevActiveValidatorCount, err); + } + + function _getActiveValidatorCount(EigenPodUser staker) internal view returns (uint) { + EigenPod pod = staker.pod(); + return pod.activeValidatorCount(); + } + + function _getPrevActiveValidatorCount(EigenPodUser staker) internal timewarp() returns (uint) { + return _getActiveValidatorCount(staker); + } + + function assert_Snap_Added_ActiveValidators( + EigenPodUser staker, + uint40[] memory addedValidators, + string memory err + ) internal { + bytes32[] memory pubkeyHashes = beaconChain.getPubkeyHashes(addedValidators); + + IEigenPod.VALIDATOR_STATUS[] memory curStatuses = _getValidatorStatuses(staker, pubkeyHashes); + IEigenPod.VALIDATOR_STATUS[] memory prevStatuses = _getPrevValidatorStatuses(staker, pubkeyHashes); + + for (uint i = 0; i < curStatuses.length; i++) { + assertTrue(prevStatuses[i] == IEigenPod.VALIDATOR_STATUS.INACTIVE, err); + assertTrue(curStatuses[i] == IEigenPod.VALIDATOR_STATUS.ACTIVE, err); + } + } + + function assert_Snap_Removed_ActiveValidators( + EigenPodUser staker, + uint40[] memory removedValidators, + string memory err + ) internal { + bytes32[] memory pubkeyHashes = beaconChain.getPubkeyHashes(removedValidators); + + IEigenPod.VALIDATOR_STATUS[] memory curStatuses = _getValidatorStatuses(staker, pubkeyHashes); + IEigenPod.VALIDATOR_STATUS[] memory prevStatuses = _getPrevValidatorStatuses(staker, pubkeyHashes); + + for (uint i = 0; i < curStatuses.length; i++) { + assertTrue(prevStatuses[i] == IEigenPod.VALIDATOR_STATUS.ACTIVE, err); + assertTrue(curStatuses[i] == IEigenPod.VALIDATOR_STATUS.WITHDRAWN, err); + } + } + + function _getValidatorStatuses(EigenPodUser staker, bytes32[] memory pubkeyHashes) internal view returns (IEigenPod.VALIDATOR_STATUS[] memory) { + EigenPod pod = staker.pod(); + IEigenPod.VALIDATOR_STATUS[] memory statuses = new IEigenPod.VALIDATOR_STATUS[](pubkeyHashes.length); + + for (uint i = 0; i < statuses.length; i++) { + statuses[i] = pod.validatorStatus(pubkeyHashes[i]); + } + + return statuses; + } + + function _getPrevValidatorStatuses(EigenPodUser staker, bytes32[] memory pubkeyHashes) internal timewarp() returns (IEigenPod.VALIDATOR_STATUS[] memory) { + return _getValidatorStatuses(staker, pubkeyHashes); + } + + /******************************************************************************* + startCheckpoint Assertions + *******************************************************************************/ + + function check_StartCheckpoint_State( + EigenPodUser staker + ) internal { + assert_ProofsRemainingEqualsActive(staker, "checkpoint proofs remaining should equal active validator count"); + assert_Snap_Created_Checkpoint(staker, "staker should have created a new checkpoint"); + } + + function assert_ProofsRemainingEqualsActive( + EigenPodUser staker, + string memory err + ) internal { + EigenPod pod = staker.pod(); + assertEq(pod.currentCheckpoint().proofsRemaining, pod.activeValidatorCount(), err); + } + + function assert_Snap_Created_Checkpoint( + EigenPodUser staker, + string memory err + ) internal { + uint64 curCheckpointTimestamp = _getCheckpointTimestamp(staker); + uint64 prevCheckpointTimestamp = _getPrevCheckpointTimestamp(staker); + + assertEq(prevCheckpointTimestamp, 0, err); + assertTrue(curCheckpointTimestamp != 0, err); + } + + function _getCheckpointTimestamp(EigenPodUser staker) internal view returns (uint64) { + EigenPod pod = staker.pod(); + return pod.currentCheckpointTimestamp(); + } + + function _getPrevCheckpointTimestamp(EigenPodUser staker) internal timewarp() returns (uint64) { + return _getCheckpointTimestamp(staker); + } + + /******************************************************************************* + verifyCheckpointProofs + *******************************************************************************/ + + /// @notice assumes positive rewards and that the checkpoint will be finalized + function _expectEventsVerifyCheckpointProofs( + EigenPodUser staker, + uint40[] memory validators, + BeaconChainProofs.BalanceProof[] memory proofs + ) internal { + EigenPod pod = staker.pod(); + int256 totalBalanceDeltaGWei = 0; + uint64 checkpointTimestamp = pod.currentCheckpointTimestamp(); + for (uint i = 0; i < validators.length; i++) { + IEigenPod.ValidatorInfo memory info = pod.validatorPubkeyHashToInfo(proofs[i].pubkeyHash); + uint64 prevBalanceGwei = info.restakedBalanceGwei; + uint64 newBalanceGwei = BeaconChainProofs.getBalanceAtIndex(proofs[i].balanceRoot, validators[i]); + int128 balanceDeltaGwei = _calcBalanceDelta({ + newAmountGwei: newBalanceGwei, + previousAmountGwei: prevBalanceGwei + }); + if (newBalanceGwei != prevBalanceGwei) { + cheats.expectEmit(true, true, true, true, address(pod)); + emit ValidatorBalanceUpdated( + validators[i], + checkpointTimestamp, + newBalanceGwei + ); + } + + if (newBalanceGwei == 0 ) { + cheats.expectEmit(true, true, true, true, address(pod)); + emit ValidatorWithdrawn(checkpointTimestamp, validators[i]); + } + + cheats.expectEmit(true, true, true, true, address(pod)); + emit ValidatorCheckpointed(checkpointTimestamp, validators[i]); + + totalBalanceDeltaGWei += balanceDeltaGwei; + } + int256 totalShareDeltaWei = (int128(uint128(pod.currentCheckpoint().podBalanceGwei)) + totalBalanceDeltaGWei) * int256(1 gwei); + cheats.expectEmit(true, true, true, true, address(pod)); + emit CheckpointFinalized(checkpointTimestamp, totalShareDeltaWei); + } + + /// @dev Calculates the delta between two Gwei amounts and returns as an int256 + function _calcBalanceDelta(uint64 newAmountGwei, uint64 previousAmountGwei) internal pure returns (int128) { + return + int128(uint128(newAmountGwei)) - int128(uint128(previousAmountGwei)); } } -contract EigenPodUnitTests_Initialization is EigenPodUnitTests, IEigenPodEvents { +contract EigenPodUnitTests_Initialization is EigenPodUnitTests { + + function test_constructor() public { + EigenPod pod = new EigenPod(ethPOSDepositMock, eigenPodManagerMock, GENESIS_TIME_LOCAL); + + assertTrue(pod.ethPOS() == ethPOSDepositMock, "should have set ethPOS correctly"); + assertTrue(pod.eigenPodManager() == eigenPodManagerMock, "should have set eigenpodmanager correctly"); + assertTrue(pod.GENESIS_TIME() == GENESIS_TIME_LOCAL, "should have set genesis time correctly"); + } function test_initialization() public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + // Check podOwner and restaked - assertEq(eigenPod.podOwner(), podOwner, "Pod owner incorrectly set"); - assertTrue(eigenPod.hasRestaked(), "hasRestaked incorrectly set"); + assertEq(pod.podOwner(), address(staker), "Pod owner incorrectly set"); // Check immutable storage - assertEq(address(eigenPod.ethPOS()), address(ethPOSDepositMock), "EthPOS incorrectly set"); - assertEq(address(eigenPod.delayedWithdrawalRouter()), address(delayedWithdrawalRouterMock), "DelayedWithdrawalRouter incorrectly set"); - assertEq(address(eigenPod.eigenPodManager()), address(eigenPodManagerMock), "EigenPodManager incorrectly set"); - assertEq(eigenPod.MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR(), MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Max restaked balance incorrectly set"); - assertEq(eigenPod.GENESIS_TIME(), GOERLI_GENESIS_TIME, "Goerli genesis time incorrectly set"); + assertEq(address(pod.ethPOS()), address(ethPOSDepositMock), "EthPOS incorrectly set"); + assertEq(address(pod.eigenPodManager()), address(eigenPodManagerMock), "EigenPodManager incorrectly set"); + assertEq(pod.GENESIS_TIME(), GENESIS_TIME_LOCAL, "LOCAL genesis time incorrectly set"); } function test_initialize_revert_alreadyInitialized() public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + cheats.expectRevert("Initializable: contract is already initialized"); - eigenPod.initialize(podOwner); + pod.initialize(address(this)); } - function test_initialize_eventEmitted() public { - address newPodOwner = address(0x123); + function test_initialize_revert_emptyPodOwner() public { + EigenPod pod = new EigenPod(ethPOSDepositMock, eigenPodManagerMock, GENESIS_TIME_LOCAL); + // un-initialize pod + cheats.store(address(pod), 0, 0); - // Deploy new pod - EigenPod newEigenPod = EigenPod(payable( - Create2.deploy( - 0, - bytes32(uint256(uint160(newPodOwner))), - // set the beacon address to the eigenPodBeacon - abi.encodePacked(beaconProxyBytecode, abi.encode(eigenPodBeacon, "")) - ))); + cheats.expectRevert("EigenPod.initialize: podOwner cannot be zero address"); + pod.initialize(address(0)); + } - // Expect emit and Initialize new pod - vm.expectEmit(true, true, true, true); - emit RestakingActivated(newPodOwner); - newEigenPod.initialize(newPodOwner); + function test_setProofSubmitter_revert_notPodOwner(address invalidCaller) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + + cheats.assume(invalidCaller != address(staker)); + cheats.prank(invalidCaller); + cheats.expectRevert("EigenPod.onlyEigenPodOwner: not podOwner"); + pod.setProofSubmitter(invalidCaller); + } + + function test_setProofSubmitter(address newProofSubmitter) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + address prevProofSubmitter = pod.proofSubmitter(); + + cheats.prank(address(staker)); + cheats.expectEmit(true, true, true, true, address(pod)); + emit ProofSubmitterUpdated(prevProofSubmitter, newProofSubmitter); + pod.setProofSubmitter(newProofSubmitter); + + assertEq(pod.proofSubmitter(), newProofSubmitter, "did not update proof submitter"); } } -contract EigenPodUnitTests_Stake is EigenPodUnitTests, IEigenPodEvents { +contract EigenPodUnitTests_EPMFunctions is EigenPodUnitTests { + /******************************************************************************* + stake() tests + *******************************************************************************/ + // Beacon chain staking constnats bytes public constant pubkey = hex"88347ed1c492eedc97fc8c506a35d44d81f27a0c7a1c661b35913cfd15256c0cccbd34a83341f505c7de2983292f2cab"; @@ -173,51 +433,123 @@ contract EigenPodUnitTests_Stake is EigenPodUnitTests, IEigenPodEvents { // Check eth transferred assertEq(address(ethPOSDepositMock).balance, 32 ether, "Incorrect amount transferred"); } -} -contract EigenPodUnitTests_PodOwnerFunctions is EigenPodUnitTests, IEigenPodEvents { - /******************************************************************************* - Withdraw Non Beacon Chain ETH Tests + withdrawRestakedBeaconChainETH() tests *******************************************************************************/ - function testFuzz_withdrawNonBeaconChainETH_revert_notPodOwner(address invalidCaller) public { - cheats.assume(invalidCaller != podOwner); + function testFuzz_withdrawRestakedBeaconChainETH_revert_notEigenPodManager( + address invalidCaller, + address recipient, + uint256 randAmount + ) public filterFuzzedAddressInputs(invalidCaller) { + // Setup EigenPod Staker + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + // ensure invalid caller causing revert + cheats.assume(invalidCaller != address(eigenPodManagerMock)); cheats.prank(invalidCaller); - cheats.expectRevert("EigenPod.onlyEigenPodOwner: not podOwner"); - eigenPod.withdrawNonBeaconChainETHBalanceWei(invalidCaller, 1 ether); + cheats.expectRevert("EigenPod.onlyEigenPodManager: not eigenPodManager"); + pod.withdrawRestakedBeaconChainETH(recipient, randAmount); } - function test_withdrawNonBeaconChainETH_revert_tooMuchWithdrawn() public { - // Send EigenPod 0.9 ether - _seedPodWithETH(0.9 ether); - - // Withdraw 1 ether - cheats.expectRevert("EigenPod.withdrawnonBeaconChainETHBalanceWei: amountToWithdraw is greater than nonBeaconChainETHBalanceWei"); - eigenPod.withdrawNonBeaconChainETHBalanceWei(podOwner, 1 ether); + function testFuzz_withdrawRestakedBeaconChainETH_revert_notFullGweiAmount( + address recipient, + uint256 randAmount + ) public { + // Setup EigenPod Staker + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + beaconChain.advanceEpoch(); + staker.startCheckpoint(); + staker.completeCheckpoint(); + + // ensure amount is not a full gwei + randAmount = (randAmount % 1 gwei) + bound(randAmount, 1, 1 gwei - 1); + cheats.expectRevert("EigenPod.withdrawRestakedBeaconChainETH: amountWei must be a whole Gwei amount"); + cheats.prank(address(eigenPodManagerMock)); + pod.withdrawRestakedBeaconChainETH(recipient, randAmount); } - function testFuzz_withdrawNonBeaconChainETH(uint256 ethAmount) public { - _seedPodWithETH(ethAmount); - assertEq(eigenPod.nonBeaconChainETHBalanceWei(), ethAmount, "Incorrect amount incremented in receive function"); + function testFuzz_withdrawRestakedBeaconChainETH_revert_withdrawAmountTooLarge( + uint256 rand, + address recipient, + uint256 randAmountWei + ) public { + // Setup EigenPod Staker + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + beaconChain.advanceEpoch(); + staker.startCheckpoint(); + staker.completeCheckpoint(); + + // ensure amount is too large + uint64 withdrawableRestakedExecutionLayerGwei = pod.withdrawableRestakedExecutionLayerGwei(); + randAmountWei = randAmountWei - (randAmountWei % 1 gwei); + cheats.assume((randAmountWei / 1 gwei) > withdrawableRestakedExecutionLayerGwei); + cheats.expectRevert( + "EigenPod.withdrawRestakedBeaconChainETH: amountGwei exceeds withdrawableRestakedExecutionLayerGwei" + ); + cheats.prank(address(eigenPodManagerMock)); + pod.withdrawRestakedBeaconChainETH(recipient, randAmountWei); + } - cheats.expectEmit(true, true, true, true); - emit NonBeaconChainETHWithdrawn(podOwner, ethAmount); - eigenPod.withdrawNonBeaconChainETHBalanceWei(podOwner, ethAmount); + function testFuzz_withdrawRestakedBeaconChainETH( + uint256 rand, + uint256 randAmountWei + ) public { + // Setup EigenPod Staker + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + beaconChain.advanceEpoch(); + staker.startCheckpoint(); + staker.completeCheckpoint(); + + // ensure valid fuzzed wei amounts + uint64 withdrawableRestakedExecutionLayerGwei = pod.withdrawableRestakedExecutionLayerGwei(); + randAmountWei = randAmountWei - (randAmountWei % 1 gwei); + cheats.assume((randAmountWei / 1 gwei) <= withdrawableRestakedExecutionLayerGwei); + + address recipient = cheats.addr(uint256(123_456_789)); - // Checks - assertEq(address(eigenPod).balance, 0, "Incorrect amount withdrawn from eigenPod"); - assertEq(address(delayedWithdrawalRouterMock).balance, ethAmount, "Incorrect amount set to delayed withdrawal router"); + cheats.prank(address(eigenPodManagerMock)); + cheats.expectEmit(true, true, true, true, address(pod)); + emit RestakedBeaconChainETHWithdrawn(recipient, randAmountWei); + pod.withdrawRestakedBeaconChainETH(recipient, randAmountWei); + + assertEq(address(recipient).balance, randAmountWei, "recipient should have received withdrawn balance"); + assertEq( + address(pod).balance, + uint(withdrawableRestakedExecutionLayerGwei * 1 gwei) - randAmountWei, + "pod balance should have decreased by withdrawn eth" + ); + assertEq( + pod.withdrawableRestakedExecutionLayerGwei(), + withdrawableRestakedExecutionLayerGwei - uint64(randAmountWei / 1 gwei), + "withdrawableRestakedExecutionLayerGwei should have decreased by amount withdrawn" + ); } +} +contract EigenPodUnitTests_recoverTokens is EigenPodUnitTests { + /******************************************************************************* - Recover Tokens Tests + recoverTokens() tests *******************************************************************************/ function testFuzz_recoverTokens_revert_notPodOwner(address invalidCaller) public { - cheats.assume(invalidCaller != podOwner); + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + address podOwner = pod.podOwner(); + cheats.assume(invalidCaller != podOwner); IERC20[] memory tokens = new IERC20[](1); tokens[0] = IERC20(address(0x123)); uint256[] memory amounts = new uint256[](1); @@ -225,24 +557,53 @@ contract EigenPodUnitTests_PodOwnerFunctions is EigenPodUnitTests, IEigenPodEven cheats.prank(invalidCaller); cheats.expectRevert("EigenPod.onlyEigenPodOwner: not podOwner"); - eigenPod.recoverTokens(tokens, amounts, podOwner); + pod.recoverTokens(tokens, amounts, podOwner); + } + + function test_recoverTokens_revert_whenPaused() public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + address podOwner = pod.podOwner(); + + IERC20[] memory tokens = new IERC20[](1); + tokens[0] = IERC20(address(0x123)); + uint256[] memory amounts = new uint256[](1); + amounts[0] = 1; + + // pause recoverTokens + cheats.prank(pauser); + eigenPodManagerMock.pause(1 << PAUSED_NON_PROOF_WITHDRAWALS); + + cheats.prank(podOwner); + cheats.expectRevert("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager"); + pod.recoverTokens(tokens, amounts, podOwner); } function test_recoverTokens_revert_invalidLengths() public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + address podOwner = pod.podOwner(); + IERC20[] memory tokens = new IERC20[](1); tokens[0] = IERC20(address(0x123)); uint256[] memory amounts = new uint256[](2); amounts[0] = 1; amounts[1] = 1; + cheats.startPrank(podOwner); cheats.expectRevert("EigenPod.recoverTokens: tokenList and amountsToWithdraw must be same length"); - eigenPod.recoverTokens(tokens, amounts, podOwner); + pod.recoverTokens(tokens, amounts, podOwner); + cheats.stopPrank(); } function test_recoverTokens() public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + EigenPod pod = staker.pod(); + address podOwner = pod.podOwner(); + // Deploy dummy token IERC20 dummyToken = new ERC20Mock(); - dummyToken.transfer(address(eigenPod), 1e18); + dummyToken.transfer(address(pod), 1e18); // Recover tokens address recipient = address(0x123); @@ -251,821 +612,1162 @@ contract EigenPodUnitTests_PodOwnerFunctions is EigenPodUnitTests, IEigenPodEven uint256[] memory amounts = new uint256[](1); amounts[0] = 1e18; - eigenPod.recoverTokens(tokens, amounts, recipient); + cheats.prank(podOwner); + pod.recoverTokens(tokens, amounts, recipient); // Checks assertEq(dummyToken.balanceOf(recipient), 1e18, "Incorrect amount recovered"); } +} + +contract EigenPodUnitTests_verifyWithdrawalCredentials is EigenPodUnitTests, ProofParsing { /******************************************************************************* - Activate Restaking Tests + verifyWithdrawalCredentials() tests *******************************************************************************/ - function testFuzz_activateRestaking_revert_notPodOwner(address invalidCaller) public { - cheats.assume(invalidCaller != podOwner); + /// @notice revert when verify wc is not called by pod owner + function testFuzz_revert_callerIsNotPodOwnerOrProofSubmitter(address invalidCaller) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + + (uint40[] memory validators,) = staker.startValidators(); + EigenPod pod = staker.pod(); + address podOwner = pod.podOwner(); + address proofSubmitter = pod.proofSubmitter(); + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); + cheats.assume(invalidCaller != podOwner && invalidCaller != proofSubmitter); cheats.prank(invalidCaller); - cheats.expectRevert("EigenPod.onlyEigenPodOwner: not podOwner"); - eigenPod.activateRestaking(); - } + cheats.expectRevert( + "EigenPod.onlyOwnerOrProofSubmitter: caller is not pod owner or proof submitter" + ); - function test_activateRestaking_revert_alreadyRestaked() public { - cheats.expectRevert("EigenPod.hasNeverRestaked: restaking is enabled"); - eigenPod.activateRestaking(); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); } - function testFuzz_activateRestaking(uint256 ethAmount) public hasNotRestaked { - // Seed some ETH - _seedPodWithETH(ethAmount); + /// @notice test verify wc reverts when paused + function test_revert_verifyWithdrawalCredentialsPaused() public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: 0 }); + (uint40[] memory validators,) = staker.startValidators(); - // Activate restaking - vm.expectEmit(true, true, true, true); - emit RestakingActivated(podOwner); - eigenPod.activateRestaking(); + cheats.prank(pauser); + eigenPodManagerMock.pause(2 ** PAUSED_EIGENPODS_VERIFY_CREDENTIALS); - // Checks - assertTrue(eigenPod.hasRestaked(), "hasRestaked incorrectly set"); - _assertWithdrawalProcessed(ethAmount); + cheats.expectRevert("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager"); + staker.verifyWithdrawalCredentials(validators); } - /** - * This is a regression test for a bug (EIG-14) found by Hexens. Lets say podOwner sends 32 ETH to the EigenPod, - * the nonBeaconChainETHBalanceWei increases by 32 ETH. podOwner calls withdrawBeforeRestaking, which - * will simply send the entire ETH balance (32 ETH) to the owner. The owner activates restaking, - * creates a validator and verifies the withdrawal credentials, receiving 32 ETH in shares. - * They can exit the validator, the pod gets the 32ETH and they can call withdrawNonBeaconChainETHBalanceWei - * And simply withdraw the 32ETH because nonBeaconChainETHBalanceWei is 32ETH. This was an issue because - * nonBeaconChainETHBalanceWei was never zeroed out in _processWithdrawalBeforeRestaking - */ - function test_regression_validatorBalance_cannotBeRemoved_viaNonBeaconChainETHBalanceWei() external hasNotRestaked { - // Assert that the pod has not restaked - assertFalse(eigenPod.hasRestaked(), "hasRestaked should be false"); + /// @notice beaconTimestamp must be after the current checkpoint + function testFuzz_revert_beaconTimestampInvalid(uint256 rand) public { + cheats.warp(10 days); + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + // Ensure we have more than one validator (_newEigenPodStaker allocates a nonzero amt of eth) + cheats.deal(address(staker), address(staker).balance + 32 ether); + (uint40[] memory validators,) = staker.startValidators(); - // Simulate podOwner sending 32 ETH to eigenPod - _seedPodWithETH(32 ether); - assertEq(eigenPod.nonBeaconChainETHBalanceWei(), 32 ether, "nonBeaconChainETHBalanceWei should be 32 ETH"); + uint40[] memory firstValidator = new uint40[](1); + firstValidator[0] = validators[0]; + staker.verifyWithdrawalCredentials(firstValidator); - // Pod owner calls withdrawBeforeRestaking, sending 32 ETH to owner - eigenPod.withdrawBeforeRestaking(); - assertEq(address(eigenPod).balance, 0, "eigenPod balance should be 0"); - assertEq(address(delayedWithdrawalRouterMock).balance, 32 ether, "withdrawal router balance should be 32 ETH"); + // Start a checkpoint so `currentCheckpointTimestamp` is nonzero + staker.startCheckpoint(); - // Upgrade from m1 to m2 - - // Activate restaking on the pod - eigenPod.activateRestaking(); - - // Simulate a withdrawal by increasing eth balance without code execution - cheats.deal(address(eigenPod), 32 ether); - - // Try calling withdrawNonBeaconChainETHBalanceWei, should fail since `nonBeaconChainETHBalanceWei` - // was set to 0 when calling `_processWithdrawalBeforeRestaking` from `activateRestaking` - cheats.expectRevert("EigenPod.withdrawnonBeaconChainETHBalanceWei: amountToWithdraw is greater than nonBeaconChainETHBalanceWei"); - eigenPod.withdrawNonBeaconChainETHBalanceWei(podOwner, 32 ether); + // Try to verify withdrawal credentials at the current block + cheats.expectRevert("EigenPod.verifyWithdrawalCredentials: specified timestamp is too far in past"); + staker.verifyWithdrawalCredentials(validators); } - - /******************************************************************************* - Withdraw Before Restaking Tests - *******************************************************************************/ - function testFuzz_withdrawBeforeRestaking_revert_notPodOwner(address invalidCaller) public filterFuzzedAddressInputs(invalidCaller) { - cheats.assume(invalidCaller != podOwner); + /// @notice Check for revert on input array mismatch lengths + function testFuzz_revert_inputArrayLengthsMismatch(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + (uint40[] memory validators,) = staker.startValidators(); + EigenPod pod = staker.pod(); + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); + + uint40[] memory invalidValidatorIndices = new uint40[](validators.length + 1); + bytes[] memory invalidValidatorFieldsProofs = new bytes[](proofs.validatorFieldsProofs.length + 1); + bytes32[][] memory invalidValidatorFields = new bytes32[][](proofs.validatorFields.length + 1); + + cheats.startPrank(address(staker)); + cheats.expectRevert("EigenPod.verifyWithdrawalCredentials: validatorIndices and proofs must be same length"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: invalidValidatorIndices, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); - cheats.prank(invalidCaller); - cheats.expectRevert("EigenPod.onlyEigenPodOwner: not podOwner"); - eigenPod.withdrawBeforeRestaking(); - } + cheats.expectRevert("EigenPod.verifyWithdrawalCredentials: validatorIndices and proofs must be same length"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: invalidValidatorFieldsProofs, + validatorFields: proofs.validatorFields + }); - function test_withdrawBeforeRestaking_revert_alreadyRestaked() public { - cheats.expectRevert("EigenPod.hasNeverRestaked: restaking is enabled"); - eigenPod.withdrawBeforeRestaking(); - } + cheats.expectRevert("EigenPod.verifyWithdrawalCredentials: validatorIndices and proofs must be same length"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: invalidValidatorFields + }); - function testFuzz_withdrawBeforeRestaking(uint256 ethAmount) public hasNotRestaked { - // Seed some ETH - _seedPodWithETH(ethAmount); + cheats.stopPrank(); + } - // Withdraw - eigenPod.withdrawBeforeRestaking(); + /// @notice Check beaconStateRootProof reverts on invalid length or invalid proof + function testFuzz_revert_beaconStateRootProofInvalid(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + (uint40[] memory validators,) = staker.startValidators(); + EigenPod pod = staker.pod(); + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); + + bytes memory proofWithInvalidLength = new bytes(proofs.stateRootProof.proof.length + 1); + BeaconChainProofs.StateRootProof memory invalidStateRootProof = BeaconChainProofs.StateRootProof({ + beaconStateRoot: proofs.stateRootProof.beaconStateRoot, + proof: proofWithInvalidLength + }); - // Checks - _assertWithdrawalProcessed(ethAmount); - } - // Helpers - function _assertWithdrawalProcessed(uint256 amount) internal { - assertEq(eigenPod.mostRecentWithdrawalTimestamp(), uint32(block.timestamp), "Incorrect mostRecentWithdrawalTimestamp"); - assertEq(eigenPod.nonBeaconChainETHBalanceWei(), 0, "Incorrect nonBeaconChainETHBalanceWei"); - assertEq(address(delayedWithdrawalRouterMock).balance, amount, "Incorrect amount sent to delayed withdrawal router"); - } + cheats.startPrank(address(staker)); + cheats.expectRevert("BeaconChainProofs.verifyStateRoot: Proof has incorrect length"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: invalidStateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); - function _seedPodWithETH(uint256 ethAmount) internal { - cheats.deal(address(this), ethAmount); - bool result; - bytes memory data; - (result, data) = address(eigenPod).call{value: ethAmount}(""); + // Change the proof to have an invalid value + bytes1 randValue = bytes1(keccak256(abi.encodePacked(proofs.stateRootProof.proof[0]))); + uint256 proofLength = proofs.stateRootProof.proof.length; + uint256 randIndex = bound(rand, 0, proofLength - 1); + proofs.stateRootProof.proof[randIndex] = randValue; + cheats.expectRevert("BeaconChainProofs.verifyStateRoot: Invalid state root merkle proof"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); + cheats.stopPrank(); } -} - -contract EigenPodHarnessSetup is EigenPodUnitTests { - // Harness that exposes internal functions for test - EPInternalFunctions public eigenPodHarnessImplementation; - EPInternalFunctions public eigenPodHarness; - function setUp() public virtual override { - EigenPodUnitTests.setUp(); + /// @notice attempt to verify validator credentials in both ACTIVE and WITHDRAWN states + /// check reverts + function testFuzz_revert_validatorsWithdrawn(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); - // Deploy EP Harness - eigenPodHarnessImplementation = new EPInternalFunctions( - ethPOSDepositMock, - delayedWithdrawalRouterMock, - eigenPodManagerMock, - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, - GOERLI_GENESIS_TIME + // now that validators are ACTIVE, ensure we can't verify them again + cheats.expectRevert( + "EigenPod._verifyWithdrawalCredentials: validator must be inactive to prove withdrawal credentials" ); + staker.verifyWithdrawalCredentials(validators); - // Upgrade eigenPod to harness - UpgradeableBeacon(address(eigenPodBeacon)).upgradeTo(address(eigenPodHarnessImplementation)); - eigenPodHarness = EPInternalFunctions(payable(eigenPod)); - } -} + staker.exitValidators(validators); + beaconChain.advanceEpoch_NoRewards(); -contract EigenPodUnitTests_VerifyWithdrawalCredentialsTests is EigenPodHarnessSetup, ProofParsing, IEigenPodEvents { - using BytesLib for bytes; - using BeaconChainProofs for *; + staker.startCheckpoint(); + staker.completeCheckpoint(); + beaconChain.advanceEpoch_NoRewards(); - // Params to _verifyWithdrawalCredentials, can be set in test or helper function - uint64 oracleTimestamp; - bytes32 beaconStateRoot; - uint40 validatorIndex; - bytes validatorFieldsProof; - bytes32[] validatorFields; - - function test_revert_validatorActive() public { - // Set JSON & params - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _setWithdrawalCredentialParams(); - - // Set validator status to active - eigenPodHarness.setValidatorStatus(validatorFields[0], IEigenPod.VALIDATOR_STATUS.ACTIVE); - - // Expect revert + // now that validators are WITHDRAWN, ensure we can't verify them again cheats.expectRevert( - "EigenPod.verifyCorrectWithdrawalCredentials: Validator must be inactive to prove withdrawal credentials" - ); - eigenPodHarness.verifyWithdrawalCredentials( - oracleTimestamp, - beaconStateRoot, - validatorIndex, - validatorFieldsProof, - validatorFields + "EigenPod._verifyWithdrawalCredentials: validator must be inactive to prove withdrawal credentials" ); + staker.verifyWithdrawalCredentials(validators); } - function testFuzz_revert_invalidValidatorFields(address wrongWithdrawalAddress) public { - cheats.assume(wrongWithdrawalAddress != address(eigenPodHarness)); - // Set JSON and params - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _setWithdrawalCredentialParams(); - - // Change the withdrawal credentials in validatorFields, which is at index 1 - validatorFields[1] = abi.encodePacked(bytes1(uint8(1)), bytes11(0), wrongWithdrawalAddress).toBytes32(0); + /// @notice attempt to verify validator credentials after they have exited + /// check reverts + function testFuzz_revert_validatorsExited(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + (uint40[] memory validators,) = staker.startValidators(); + + // Exit validators from beacon chain and withdraw to pod + staker.exitValidators(validators); + beaconChain.advanceEpoch(); - // Expect revert + // now that validators are exited, ensure we can't verify them cheats.expectRevert( - "EigenPod.verifyCorrectWithdrawalCredentials: Proof is not for this EigenPod" - ); - eigenPodHarness.verifyWithdrawalCredentials( - oracleTimestamp, - beaconStateRoot, - validatorIndex, - validatorFieldsProof, - validatorFields + "EigenPod._verifyWithdrawalCredentials: validator must not be exiting" ); + staker.verifyWithdrawalCredentials(validators); } - function test_effectiveBalanceGreaterThan32ETH() public { - // Set JSON and params - setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); - _setWithdrawalCredentialParams(); - - // Check that restaked balance greater than 32 ETH - uint64 effectiveBalanceGwei = validatorFields.getEffectiveBalanceGwei(); - assertGt(effectiveBalanceGwei, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Proof file has an effective balance less than 32 ETH"); - - uint activeValidatorCountBefore = eigenPodHarness.getActiveValidatorCount(); - - // Verify withdrawal credentials - vm.expectEmit(true, true, true, true); - emit ValidatorRestaked(validatorIndex); - vm.expectEmit(true, true, true, true); - emit ValidatorBalanceUpdated(validatorIndex, oracleTimestamp, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR); - uint256 restakedBalanceWei = eigenPodHarness.verifyWithdrawalCredentials( - oracleTimestamp, - beaconStateRoot, - validatorIndex, - validatorFieldsProof, - validatorFields - ); + /// @notice modify withdrawal credentials to cause a revert + function testFuzz_revert_invalidWithdrawalAddress(uint256 rand, bytes32 invalidWithdrawalCredentials) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + (uint40[] memory validators, ) = staker.startValidators(); + EigenPod pod = staker.pod(); + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); + + // Set invalid withdrawal credentials in validatorFields + uint256 VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX = 1; + proofs.validatorFields[0][VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX] = invalidWithdrawalCredentials; + + cheats.startPrank(address(staker)); + cheats.expectRevert("EigenPod._verifyWithdrawalCredentials: proof is not for this EigenPod"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); + cheats.stopPrank(); + } - // Checks - uint activeValidatorCountAfter = eigenPodHarness.getActiveValidatorCount(); - assertEq(activeValidatorCountAfter, activeValidatorCountBefore + 1, "active validator count should increase when proving withdrawal credentials"); - assertEq(restakedBalanceWei, uint256(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) * uint256(1e9), "Returned restaked balance gwei should be max"); - _assertWithdrawalCredentialsSet(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR); + /// @notice modify validator field length to cause a revert + function testFuzz_revert_invalidValidatorFields(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + (uint40[] memory validators, ) = staker.startValidators(); + EigenPod pod = staker.pod(); + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); + + // change validator field length to invalid value + bytes32[] memory invalidValidatorFields = new bytes32[](BeaconChainProofs.VALIDATOR_FIELDS_LENGTH + 1); + for (uint i = 0; i < BeaconChainProofs.VALIDATOR_FIELDS_LENGTH; i++) { + invalidValidatorFields[i] = proofs.validatorFields[0][i]; + } + proofs.validatorFields[0] = invalidValidatorFields; + + cheats.startPrank(address(staker)); + cheats.expectRevert("BeaconChainProofs.verifyValidatorFields: Validator fields has incorrect length"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); + cheats.stopPrank(); } - function test_effectiveBalanceLessThan32ETH() public { - // Set JSON and params - setJSON("./src/test/test-data/withdrawal_credential_proof_302913_30ETHBalance.json"); - _setWithdrawalCredentialParams(); + /// @notice modify validator activation epoch to cause a revert + function testFuzz_revert_activationEpochNotSet(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + (uint40[] memory validators, ) = staker.startValidators(); + EigenPod pod = staker.pod(); + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); - // Check that restaked balance less than 32 ETH - uint64 effectiveBalanceGwei = validatorFields.getEffectiveBalanceGwei(); - assertLt(effectiveBalanceGwei, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Proof file has an effective balance greater than 32 ETH"); - - uint activeValidatorCountBefore = eigenPodHarness.getActiveValidatorCount(); - - // Verify withdrawal credentials - vm.expectEmit(true, true, true, true); - emit ValidatorRestaked(validatorIndex); - vm.expectEmit(true, true, true, true); - emit ValidatorBalanceUpdated(validatorIndex, oracleTimestamp, effectiveBalanceGwei); - uint256 restakedBalanceWei = eigenPodHarness.verifyWithdrawalCredentials( - oracleTimestamp, - beaconStateRoot, - validatorIndex, - validatorFieldsProof, - validatorFields - ); - - // Checks - uint activeValidatorCountAfter = eigenPodHarness.getActiveValidatorCount(); - assertEq(activeValidatorCountAfter, activeValidatorCountBefore + 1, "active validator count should increase when proving withdrawal credentials"); - assertEq(restakedBalanceWei, uint256(effectiveBalanceGwei) * uint256(1e9), "Returned restaked balance gwei incorrect"); - _assertWithdrawalCredentialsSet(effectiveBalanceGwei); + proofs.validatorFields[0][BeaconChainProofs.VALIDATOR_ACTIVATION_EPOCH_INDEX] + = _toLittleEndianUint64(BeaconChainProofs.FAR_FUTURE_EPOCH); + + cheats.startPrank(address(staker)); + cheats.expectRevert("EigenPod._verifyWithdrawalCredentials: validator must be in the process of activating"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); + cheats.stopPrank(); } - function _assertWithdrawalCredentialsSet(uint256 restakedBalanceGwei) internal { - IEigenPod.ValidatorInfo memory validatorInfo = eigenPodHarness.validatorPubkeyHashToInfo(validatorFields[0]); - assertEq(uint8(validatorInfo.status), uint8(IEigenPod.VALIDATOR_STATUS.ACTIVE), "Validator status should be active"); - assertEq(validatorInfo.validatorIndex, validatorIndex, "Validator index incorrectly set"); - assertEq(validatorInfo.mostRecentBalanceUpdateTimestamp, oracleTimestamp, "Most recent balance update timestamp incorrectly set"); - assertEq(validatorInfo.restakedBalanceGwei, restakedBalanceGwei, "Restaked balance gwei not set correctly"); + /// @notice modify validator proof length to cause a revert + function testFuzz_revert_invalidValidatorProofLength(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + (uint40[] memory validators, ) = staker.startValidators(); + EigenPod pod = staker.pod(); + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); + + // add an element to the proof + proofs.validatorFieldsProofs[0] = new bytes(proofs.validatorFieldsProofs[0].length + 32); + + cheats.startPrank(address(staker)); + cheats.expectRevert("BeaconChainProofs.verifyValidatorFields: Proof has incorrect length"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); + cheats.stopPrank(); } + /// @notice modify validator pubkey to cause a revert + function testFuzz_revert_invalidValidatorProof(uint256 rand, bytes32 randPubkey) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + (uint40[] memory validators, ) = staker.startValidators(); + EigenPod pod = staker.pod(); + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); + + // change validator pubkey to an invalid value causing a revert + uint256 VALIDATOR_PUBKEY_INDEX = 0; + proofs.validatorFields[0][VALIDATOR_PUBKEY_INDEX] = randPubkey; + + cheats.startPrank(address(staker)); + cheats.expectRevert("BeaconChainProofs.verifyValidatorFields: Invalid merkle proof"); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); + cheats.stopPrank(); + } - function _setWithdrawalCredentialParams() public { - // Set beacon state root, validatorIndex - beaconStateRoot = getBeaconStateRoot(); - validatorIndex = uint40(getValidatorIndex()); - validatorFieldsProof = abi.encodePacked(getWithdrawalCredentialProof()); // Validator fields are proven here - validatorFields = getValidatorFields(); - - // Get an oracle timestamp - cheats.warp(GOERLI_GENESIS_TIME + 1 days); - oracleTimestamp = uint64(block.timestamp); + /// @notice fuzz test a eigenPod with multiple validators. Using timemachine to assert values over time + function testFuzz_verifyWithdrawalCredentials(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators, ) = staker.startValidators(); + // Complete a quick empty checkpoint so we have a nonzero value for `lastCheckpointedAt` + staker.startCheckpoint(); + beaconChain.advanceEpoch_NoRewards(); + + CredentialProofs memory proofs = beaconChain.getCredentialProofs(validators); + + for (uint256 i; i < validators.length; i++) { + cheats.expectEmit(true, true, true, true, address(pod)); + emit ValidatorRestaked(validators[i]); + cheats.expectEmit(true, true, true, true, address(pod)); + emit ValidatorBalanceUpdated( + validators[i], + pod.lastCheckpointTimestamp(), + beaconChain.effectiveBalance(validators[i]) + ); + } + // staker.verifyWithdrawalCredentials(validators); + // Prank either the staker or proof submitter + cheats.prank(rand % 2 == 1 ? address(staker) : pod.proofSubmitter()); + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); + assert_Snap_Added_ActiveValidatorCount(staker, validators.length, "staker should have increased active validator count"); + assert_Snap_Added_ActiveValidators(staker, validators, "validators should each be active"); + // Check ValidatorInfo values for each validator + for (uint i = 0; i < validators.length; i++) { + bytes32 pubkeyHash = beaconChain.pubkeyHash(validators[i]); + bytes memory pubkey = beaconChain.pubkey(validators[i]); + + IEigenPod.ValidatorInfo memory info = pod.validatorPubkeyHashToInfo(pubkeyHash); + IEigenPod.ValidatorInfo memory pkInfo = pod.validatorPubkeyToInfo(pubkey); + assertTrue(pod.validatorStatus(pubkey) == IEigenPod.VALIDATOR_STATUS.ACTIVE, "validator status should be active"); + assertEq(keccak256(abi.encode(info)), keccak256(abi.encode(pkInfo)), "validator info should be identical"); + assertEq(info.validatorIndex, validators[i], "should have assigned correct validator index"); + assertEq(info.restakedBalanceGwei, beaconChain.effectiveBalance(validators[i]), "should have restaked full effective balance"); + assertEq(info.lastCheckpointedAt, pod.lastCheckpointTimestamp(), "should have recorded correct update time"); + } } } -/// @notice In practice, this function should be called after a validator has verified their withdrawal credentials -contract EigenPodUnitTests_VerifyBalanceUpdateTests is EigenPodHarnessSetup, ProofParsing, IEigenPodEvents { - using BeaconChainProofs for *; +contract EigenPodUnitTests_startCheckpoint is EigenPodUnitTests { - // Params to verifyBalanceUpdate, can be set in test or helper function - uint64 oracleTimestamp; - uint40 validatorIndex; - bytes32 beaconStateRoot; - bytes validatorFieldsProof; - bytes32[] validatorFields; + /******************************************************************************* + startCheckpoint() tests + *******************************************************************************/ - function testFuzz_revert_oracleTimestampStale(uint64 oracleFuzzTimestamp, uint64 mostRecentBalanceUpdateTimestamp) public { - // Constain inputs and set proof file - cheats.assume(oracleFuzzTimestamp < mostRecentBalanceUpdateTimestamp); - setJSON("src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); - - // Get validator fields and balance update root - validatorFields = getValidatorFields(); - validatorFieldsProof = abi.encodePacked(getBalanceUpdateProof()); + /// @notice revert when startCheckpoint is not called by pod owner + function testFuzz_revert_callerIsNotPodOwnerOrProofSubmitter(uint256 rand, address invalidCaller) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + EigenPod pod = staker.pod(); + address podOwner = pod.podOwner(); + address proofSubmitter = pod.proofSubmitter(); - // Balance update reversion + cheats.assume(invalidCaller != podOwner && invalidCaller != proofSubmitter); + cheats.prank(invalidCaller); cheats.expectRevert( - "EigenPod.verifyBalanceUpdate: Validators balance has already been updated for this timestamp" - ); - eigenPodHarness.verifyBalanceUpdate( - oracleFuzzTimestamp, - 0, - bytes32(0), - validatorFieldsProof, - validatorFields, - mostRecentBalanceUpdateTimestamp + "EigenPod.onlyOwnerOrProofSubmitter: caller is not pod owner or proof submitter" ); + pod.startCheckpoint({ revertIfNoBalance: false }); } - function test_revert_validatorInactive() public { - // Set proof file - setJSON("src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); + /// @notice test startCheckpoint reverts when paused + function testFuzz_revert_startCheckpointPaused(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); - // Set proof params - _setBalanceUpdateParams(); + staker.startValidators(); - // Set validator status to inactive - eigenPodHarness.setValidatorStatus(validatorFields[0], IEigenPod.VALIDATOR_STATUS.INACTIVE); + cheats.prank(pauser); + eigenPodManagerMock.pause(2 ** PAUSED_START_CHECKPOINT); - // Balance update reversion - cheats.expectRevert( - "EigenPod.verifyBalanceUpdate: Validator not active" - ); - eigenPodHarness.verifyBalanceUpdate( - oracleTimestamp, - validatorIndex, - beaconStateRoot, - validatorFieldsProof, - validatorFields, - 0 // Most recent balance update timestamp set to 0 - ); + cheats.expectRevert("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager"); + staker.startCheckpoint(); } - /** - * Regression test for a bug that allowed balance updates to be made for withdrawn validators. Thus - * the validator's balance could be maliciously proven to be 0 before the validator themselves are - * able to prove their withdrawal. - */ - function test_revert_balanceUpdateAfterWithdrawableEpoch() external { - // Set Json proof - setJSON("src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); - - // Set proof params - _setBalanceUpdateParams(); - - // Set effective balance and withdrawable epoch - validatorFields[2] = bytes32(uint256(0)); // per consensus spec, slot 2 is effective balance - validatorFields[7] = bytes32(uint256(0)); // per consensus spec, slot 7 is withdrawable epoch == 0 - - console.log("withdrawable epoch: ", validatorFields.getWithdrawableEpoch()); - // Expect revert on balance update - cheats.expectRevert(bytes("EigenPod.verifyBalanceUpdate: validator is withdrawable but has not withdrawn")); - eigenPodHarness.verifyBalanceUpdate(oracleTimestamp, validatorIndex, beaconStateRoot, validatorFieldsProof, validatorFields, 0); + /// @notice startCheckpoint should revert if another checkpoint already in progress + function testFuzz_revert_checkpointAlreadyStarted(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + staker.startCheckpoint(); + cheats.expectRevert("EigenPod._startCheckpoint: must finish previous checkpoint before starting another"); + staker.startCheckpoint(); } - /// @notice Rest of tests assume beacon chain proofs are correct; Now we update the validator's balance + /// @notice startCheckpoint should revert if a checkpoint has already been completed this block + function testFuzz_revert_checkpointTwicePerBlock(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); - ///@notice Balance of validator is >= 32e9 - function test_positiveSharesDelta() public { - // Set JSON - setJSON("src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + staker.startCheckpoint(); + staker.completeCheckpoint(); - // Set proof params - _setBalanceUpdateParams(); + cheats.expectRevert("EigenPod._startCheckpoint: cannot checkpoint twice in one block"); + staker.startCheckpoint(); + } - // Verify balance update - vm.expectEmit(true, true, true, true); - emit ValidatorBalanceUpdated(validatorIndex, oracleTimestamp, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR); - int256 sharesDeltaGwei = eigenPodHarness.verifyBalanceUpdate( - oracleTimestamp, - validatorIndex, - beaconStateRoot, - validatorFieldsProof, - validatorFields, - 0 // Most recent balance update timestamp set to 0 - ); + /// @notice if no rewards and revertIfNoBalance is set, startCheckpoint should revert + function testFuzz_revert_revertIfNoBalanceIsSet(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); - // Checks - IEigenPod.ValidatorInfo memory validatorInfo = eigenPodHarness.validatorPubkeyHashToInfo(validatorFields[0]); - assertEq(validatorInfo.restakedBalanceGwei, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Restaked balance gwei should be max"); - assertGt(sharesDeltaGwei, 0, "Shares delta should be positive"); - assertEq(sharesDeltaGwei, int256(uint256(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR)), "Shares delta should be equal to restaked balance"); - } - - function test_negativeSharesDelta() public { - // Set JSON - setJSON("src/test/test-data/balanceUpdateProof_balance28ETH_302913.json"); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + EigenPod pod = staker.pod(); + beaconChain.advanceEpoch_NoRewards(); - // Set proof params - _setBalanceUpdateParams(); - uint64 newValidatorBalance = validatorFields.getEffectiveBalanceGwei(); + cheats.prank(pod.podOwner()); + cheats.expectRevert("EigenPod._startCheckpoint: no balance available to checkpoint"); + pod.startCheckpoint({ revertIfNoBalance: true }); + } - // Set balance of validator to max ETH - eigenPodHarness.setValidatorRestakedBalance(validatorFields[0], MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR); + /// @notice fuzz test an eigenpod with multiple validators and starting a checkpoint + function testFuzz_startCheckpoint(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); - // Verify balance update - int256 sharesDeltaGwei = eigenPodHarness.verifyBalanceUpdate( - oracleTimestamp, - validatorIndex, - beaconStateRoot, - validatorFieldsProof, - validatorFields, - 0 // Most recent balance update timestamp set to 0 - ); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); - // Checks - IEigenPod.ValidatorInfo memory validatorInfo = eigenPodHarness.validatorPubkeyHashToInfo(validatorFields[0]); - assertEq(validatorInfo.restakedBalanceGwei, newValidatorBalance, "Restaked balance gwei should be max"); - assertLt(sharesDeltaGwei, 0, "Shares delta should be negative"); - int256 expectedSharesDiff = int256(uint256(newValidatorBalance)) - int256(uint256(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR)); - assertEq(sharesDeltaGwei, expectedSharesDiff, "Shares delta should be equal to restaked balance"); + cheats.expectEmit(true, true, true, true, address(staker.pod())); + emit CheckpointCreated(uint64(block.timestamp), EIP_4788_ORACLE.timestampToBlockRoot(block.timestamp), validators.length); + staker.startCheckpoint(); + check_StartCheckpoint_State(staker); + assertEq(pod.currentCheckpoint().proofsRemaining, uint24(validators.length), "should have one proof remaining pre verified validator"); } - function test_zeroSharesDelta() public { - // Set JSON - setJSON("src/test/test-data/balanceUpdateProof_notOverCommitted_302913.json"); + /// @notice fuzz test an eigenpod with multiple validators and starting a checkpoint + function testFuzz_startCheckpoint_AsProofSubmitter(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); - // Set proof params - _setBalanceUpdateParams(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); - // Set previous restaked balance to max restaked balance - eigenPodHarness.setValidatorRestakedBalance(validatorFields[0], MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR); + cheats.expectEmit(true, true, true, true, address(staker.pod())); + emit CheckpointCreated(uint64(block.timestamp), EIP_4788_ORACLE.timestampToBlockRoot(block.timestamp), validators.length); + cheats.prank(pod.proofSubmitter()); + pod.startCheckpoint(false); + check_StartCheckpoint_State(staker); + assertEq(pod.currentCheckpoint().proofsRemaining, uint24(validators.length), "should have one proof remaining pre verified validator"); + } +} - // Verify balance update - int256 sharesDeltaGwei = eigenPodHarness.verifyBalanceUpdate( - oracleTimestamp, - validatorIndex, - beaconStateRoot, - validatorFieldsProof, - validatorFields, - 0 // Most recent balance update timestamp set to 0 +contract EigenPodUnitTests_verifyCheckpointProofs is EigenPodUnitTests { + + /******************************************************************************* + verifyCheckpointProofs() tests + *******************************************************************************/ + + /// @notice test verifyCheckpointProofs reverts when paused + function testFuzz_revert_verifyCheckpointProofsPaused(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() ); - // Checks - assertEq(sharesDeltaGwei, 0, "Shares delta should be 0"); + cheats.prank(pauser); + eigenPodManagerMock.pause(2 ** PAUSED_EIGENPODS_VERIFY_CHECKPOINT_PROOFS); + cheats.expectRevert("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager"); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); } - function _setBalanceUpdateParams() internal { - // Set validator index, beacon state root, balance update proof, and validator fields - validatorIndex = uint40(getValidatorIndex()); - beaconStateRoot = getBeaconStateRoot(); - validatorFieldsProof = abi.encodePacked(getBalanceUpdateProof()); - validatorFields = getValidatorFields(); + /// @notice verifyCheckpointProofs should revert if checkpoint not in progress + function testFuzz_revert_checkpointNotStarted(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); - // Get an oracle timestamp - cheats.warp(GOERLI_GENESIS_TIME + 1 days); - oracleTimestamp = uint64(block.timestamp); - - // Set validator status to active - eigenPodHarness.setValidatorStatus(validatorFields[0], IEigenPod.VALIDATOR_STATUS.ACTIVE); + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() + ); + cheats.expectRevert( + "EigenPod.verifyCheckpointProofs: must have active checkpoint to perform checkpoint proof" + ); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); } -} -contract EigenPodUnitTests_WithdrawalTests is EigenPodHarnessSetup, ProofParsing, IEigenPodEvents { - using BeaconChainProofs for *; + /// @notice invalid proof length should revert + function testFuzz_revert_verifyBalanceContainerInvalidLengths(uint256 rand) public { + // Setup verifyCheckpointProofs + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + beaconChain.advanceEpoch(); + staker.startCheckpoint(); + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() + ); - // Params to process withdrawal - bytes32 beaconStateRoot; - BeaconChainProofs.WithdrawalProof withdrawalToProve; - bytes validatorFieldsProof; - bytes32[] validatorFields; - bytes32[] withdrawalFields; + // change the length of balanceContainerProof to cause a revert + proofs.balanceContainerProof.proof = new bytes(proofs.balanceContainerProof.proof.length + 1); - // Most recent withdrawal timestamp incremented when withdrawal processed before restaking OR when staking activated - function test_verifyAndProcessWithdrawal_revert_staleProof() public hasNotRestaked { - // Set JSON & params - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - _setWithdrawalProofParams(); + cheats.expectRevert("BeaconChainProofs.verifyBalanceContainer: Proof has incorrect length"); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); + } - // Set timestamp to after withdrawal timestamp - uint64 timestampOfWithdrawal = Endian.fromLittleEndianUint64(withdrawalToProve.timestampRoot); - uint256 newTimestamp = timestampOfWithdrawal + 2500; - cheats.warp(newTimestamp); + /// @notice change one of the bytes in the balanceContainer proof to cause a revert + function testFuzz_revert_verifyBalanceContainerInvalidProof(uint256 rand) public { + // Setup verifyCheckpointProofs + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + beaconChain.advanceEpoch(); + staker.startCheckpoint(); - // Activate restaking, setting `mostRecentWithdrawalTimestamp` - eigenPodHarness.activateRestaking(); - // Expect revert - cheats.expectRevert("EigenPod.proofIsForValidTimestamp: beacon chain proof must be at or after mostRecentWithdrawalTimestamp"); - eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() ); + // randomly change one of the bytes in the proof to make the proof invalid + bytes1 randValue = bytes1(keccak256(abi.encodePacked(proofs.balanceContainerProof.proof[0]))); + proofs.balanceContainerProof.proof[0] = randValue; + + cheats.expectRevert("BeaconChainProofs.verifyBalanceContainer: invalid balance container proof"); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); } - function test_verifyAndProcessWithdrawal_revert_statusInactive() public { - // Set JSON & params - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - _setWithdrawalProofParams(); + /// @notice invalid balance proof length should revert + function testFuzz_revert_verifyValidatorBalanceInvalidLength(uint256 rand) public { + // Setup verifyCheckpointProofs + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + beaconChain.advanceEpoch(); + staker.startCheckpoint(); + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() + ); - // Set status to inactive - eigenPodHarness.setValidatorStatus(validatorFields[0], IEigenPod.VALIDATOR_STATUS.INACTIVE); + // change the length of balance proof to cause a revert + proofs.balanceProofs[0].proof = new bytes(proofs.balanceProofs[0].proof.length + 1); - // Expect revert - cheats.expectRevert("EigenPod._verifyAndProcessWithdrawal: Validator never proven to have withdrawal credentials pointed to this contract"); - eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields + cheats.expectRevert("BeaconChainProofs.verifyValidatorBalance: Proof has incorrect length"); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); + } + + /// @notice change one of the bytes in one of the balance proofs to cause a revert + function testFuzz_revert_verifyValidatorBalanceInvalidProof(uint256 rand) public { + // Setup verifyCheckpointProofs + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + beaconChain.advanceEpoch(); + staker.startCheckpoint(); + + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() ); + // randomly change one of the bytes in the first proof to make the proof invalid + bytes1 randValue = bytes1(keccak256(abi.encodePacked(proofs.balanceProofs[0].proof[0]))); + proofs.balanceProofs[0].proof[0] = randValue; + + cheats.expectRevert("BeaconChainProofs.verifyValidatorBalance: Invalid merkle proof"); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); } - function test_verifyAndProcessWithdrawal_withdrawalAlreadyProcessed() public setWithdrawalCredentialsExcess { - // Set JSON & params - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - _setWithdrawalProofParams(); + /// @notice test that verifyCheckpointProofs skips proofs submitted for non-ACTIVE validators + function testFuzz_verifyCheckpointProofs_skipIfNotActive(uint256 rand) public { + // Setup verifyCheckpointProofs + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + // Ensure we have more than one validator (_newEigenPodStaker allocates a nonzero amt of eth) + cheats.deal(address(staker), address(staker).balance + 32 ether); + EigenPod pod = staker.pod(); - // Process withdrawal - eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields - ); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); - // Attempt to process again - cheats.expectRevert("EigenPod._verifyAndProcessWithdrawal: withdrawal has already been proven for this timestamp"); - eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields - ); - } + // Exit a validator and advance epoch so the exit is picked up next checkpoint + uint40[] memory exitedValidator = new uint40[](1); + exitedValidator[0] = validators[0]; + uint64 exitedBalanceGwei = staker.exitValidators(exitedValidator); + beaconChain.advanceEpoch_NoRewards(); - function test_verifyAndProcessWithdrawal_excess() public setWithdrawalCredentialsExcess { - // Set JSON & params - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - _setWithdrawalProofParams(); + staker.startCheckpoint(); - // Process withdrawal - eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + exitedValidator, + pod.currentCheckpointTimestamp() ); - // Verify storage - bytes32 validatorPubKeyHash = validatorFields.getPubkeyHash(); - uint64 withdrawalTimestamp = withdrawalToProve.getWithdrawalTimestamp(); - assertTrue(eigenPodHarness.provenWithdrawal(validatorPubKeyHash, withdrawalTimestamp), "Withdrawal not set to proven"); - } - - // regression test for off-by-one error - function test_verifyAndProcessWithdrawal_atLatestWithdrawalTimestamp() public setWithdrawalCredentialsExcess { - // Set JSON & params - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - _setWithdrawalProofParams(); + // verify checkpoint proof for one exited validator + // manually create a snapshot here for Snap checks + timeMachine.createSnapshot(); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); + assertEq(0, pod.withdrawableRestakedExecutionLayerGwei(), "should not have updated withdrawable balance"); + assertEq(pod.currentCheckpoint().proofsRemaining, validators.length - 1, "should have decreased proofs remaining by 1"); + assert_Snap_Removed_ActiveValidatorCount(staker, 1, "should have removed one validator from active set"); + assert_Snap_Removed_ActiveValidators(staker, exitedValidator, "should have set validator status to WITHDRAWN"); + + // attempt to submit the same proof and ensure that checkpoint did not progress + // the call should succeed, but nothing should happen + // manually create a snapshot here for Snap checks + timeMachine.createSnapshot(); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); - uint64 withdrawalTimestamp = withdrawalToProve.getWithdrawalTimestamp(); - // set the `mostRecentWithdrawalTimestamp` to be equal to the withdrawal timestamp - eigenPodHarness.setMostRecentWithdrawalTimestamp(withdrawalTimestamp); + assertEq(0, pod.withdrawableRestakedExecutionLayerGwei(), "should not have updated withdrawable balance"); + assertEq(pod.currentCheckpoint().proofsRemaining, validators.length - 1, "should not have decreased proofs remaining"); + assert_Snap_Unchanged_ActiveValidatorCount(staker, "should have the same active validator count"); - // Process withdrawal - eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields + // finally, finish the checkpoint by submitting all proofs + proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() ); + // manually create a snapshot here for Snap checks + timeMachine.createSnapshot(); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); - // Verify storage - bytes32 validatorPubKeyHash = validatorFields.getPubkeyHash(); - assertTrue(eigenPodHarness.provenWithdrawal(validatorPubKeyHash, withdrawalTimestamp), "Withdrawal not set to proven"); + assert_Snap_Unchanged_ActiveValidatorCount(staker, "should have the same active validator count after completing checkpoint"); + assertEq(exitedBalanceGwei, pod.withdrawableRestakedExecutionLayerGwei(), "exited balance should now be withdrawable"); + assertEq( + pod.currentCheckpointTimestamp(), + 0, + "checkpoint should be complete" + ); } - function test_revert_verifyAndProcessWithdrawal_beforeLatestWithdrawalTimestamp() public setWithdrawalCredentialsExcess { - // Set JSON & params - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - _setWithdrawalProofParams(); + /// @notice test that verifyCheckpointProofs skips duplicate checkpoint proofs + function testFuzz_verifyCheckpointProofs_skipIfAlreadyProven(uint256 rand) public { + // Setup verifyCheckpointProofs + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + // Ensure we have more than one validator (_newEigenPodStaker allocates a nonzero amt of eth) + cheats.deal(address(staker), address(staker).balance + 32 ether); + EigenPod pod = staker.pod(); - uint64 withdrawalTimestamp = withdrawalToProve.getWithdrawalTimestamp(); - // set the `mostRecentWithdrawalTimestamp` to just after the withdrawal timestamp - eigenPodHarness.setMostRecentWithdrawalTimestamp(withdrawalTimestamp + 1); + (uint40[] memory validators,) = staker.startValidators(); + beaconChain.advanceEpoch_NoWithdraw(); // generate rewards on the beacon chain + staker.verifyWithdrawalCredentials(validators); - // Process withdrawal, expect revert - cheats.expectRevert("EigenPod.proofIsForValidTimestamp: beacon chain proof must be at or after mostRecentWithdrawalTimestamp"); - eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields + // select a single validator to submit multiple times + uint40[] memory singleValidator = new uint40[](1); + singleValidator[0] = validators[0]; + + staker.startCheckpoint(); + + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + singleValidator, + pod.currentCheckpointTimestamp() ); - } - /// @notice Tests processing a full withdrawal > MAX_RESTAKED_GWEI_PER_VALIDATOR - function test_processFullWithdrawal_excess32ETH() public setWithdrawalCredentialsExcess { - // Set JSON & params - setJSON("./src/test/test-data/fullWithdrawalProof_Latest.json"); - _setWithdrawalProofParams(); + // verify checkpoint proof for one validator + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); + assertEq(pod.currentCheckpoint().proofsRemaining, validators.length - 1, "should have decreased proofs remaining by 1"); - // Get params to check against - uint64 withdrawalTimestamp = withdrawalToProve.getWithdrawalTimestamp(); - uint40 validatorIndex = uint40(getValidatorIndex()); - uint64 withdrawalAmountGwei = withdrawalFields.getWithdrawalAmountGwei(); - assertGt(withdrawalAmountGwei, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Withdrawal amount should be greater than max restaked balance for this test"); + // attempt to submit the same proof and ensure that checkpoint did not progress + // the call should succeed, but nothing should happen + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); + assertEq(pod.currentCheckpoint().proofsRemaining, validators.length - 1, "should not have decreased proofs remaining"); - // Process full withdrawal - vm.expectEmit(true, true, true, true); - emit FullWithdrawalRedeemed(validatorIndex, withdrawalTimestamp, podOwner, withdrawalAmountGwei); - IEigenPod.VerifiedWithdrawal memory vw = eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields + // finally, finish the checkpoint by submitting all proofs + proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() ); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); - // Storage checks in _verifyAndProcessWithdrawal - bytes32 validatorPubKeyHash = validatorFields.getPubkeyHash(); - assertTrue(eigenPodHarness.provenWithdrawal(validatorPubKeyHash, withdrawalTimestamp), "Withdrawal not set to proven"); + assertEq( + pod.currentCheckpointTimestamp(), + 0, + "checkpoint should be complete" + ); + // Check ValidatorInfo values for each validator + for (uint i = 0; i < validators.length; i++) { + bytes32 pubkeyHash = beaconChain.pubkeyHash(validators[i]); - // Checks from _processFullWithdrawal - assertEq(eigenPod.withdrawableRestakedExecutionLayerGwei(), MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Incorrect withdrawable restaked execution layer gwei"); - // Excess withdrawal amount is diff between restaked balance and total withdrawal amount - uint64 excessWithdrawalAmount = withdrawalAmountGwei - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; - assertEq(vw.amountToSendGwei, excessWithdrawalAmount, "Amount to send via router is not correct"); - assertEq(vw.sharesDeltaGwei, 0, "Shares delta not correct"); // Shares delta is 0 since restaked balance and amount to withdraw were max - - // ValidatorInfo storage update checks - IEigenPod.ValidatorInfo memory validatorInfo = eigenPodHarness.validatorPubkeyHashToInfo(validatorFields[0]); - assertEq(uint8(validatorInfo.status), uint8(IEigenPod.VALIDATOR_STATUS.WITHDRAWN), "Validator status should be withdrawn"); - assertEq(validatorInfo.restakedBalanceGwei, 0, "Restaked balance gwei should be 0"); + IEigenPod.ValidatorInfo memory info = pod.validatorPubkeyHashToInfo(pubkeyHash); + assertEq(info.restakedBalanceGwei, beaconChain.currentBalance(validators[i]), "should have restaked full current balance"); + assertEq(info.lastCheckpointedAt, pod.lastCheckpointTimestamp(), "should have recorded correct update time"); + } } - function test_processFullWithdrawal_lessThan32ETH() public setWithdrawalCredentialsExcess { - // Set JSON & params - setJSON("src/test/test-data/fullWithdrawalProof_Latest_28ETH.json"); - _setWithdrawalProofParams(); + /// @notice test that verifyCheckpointProofs sets validators to WITHDRAWN if they are exited + function testFuzz_verifyCheckpointProofs_validatorExits(uint256 rand) public { + // Setup verifyCheckpointProofs + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); - // Get params to check against - uint64 withdrawalTimestamp = withdrawalToProve.getWithdrawalTimestamp(); - uint64 withdrawalAmountGwei = withdrawalFields.getWithdrawalAmountGwei(); - assertLt(withdrawalAmountGwei, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Withdrawal amount should be greater than max restaked balance for this test"); + // Exit validators and advance epoch so exits are picked up in next checkpoint + uint64 exitedBalanceGwei = staker.exitValidators(validators); + beaconChain.advanceEpoch_NoRewards(); - // Process full withdrawal - IEigenPod.VerifiedWithdrawal memory vw = eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields + staker.startCheckpoint(); + + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() ); - // Storage checks in _verifyAndProcessWithdrawal - bytes32 validatorPubKeyHash = validatorFields.getPubkeyHash(); - assertTrue(eigenPodHarness.provenWithdrawal(validatorPubKeyHash, withdrawalTimestamp), "Withdrawal not set to proven"); + // Verify checkpoint proofs emit the expected values + _expectEventsVerifyCheckpointProofs(staker, validators, proofs.balanceProofs); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); + assertEq( + pod.currentCheckpointTimestamp(), + 0, + "checkpoint should be complete" + ); - // Checks from _processFullWithdrawal - assertEq(eigenPod.withdrawableRestakedExecutionLayerGwei(), withdrawalAmountGwei, "Incorrect withdrawable restaked execution layer gwei"); - // Excess withdrawal amount should be 0 since balance is < MAX - assertEq(vw.amountToSendGwei, 0, "Amount to send via router is not correct"); - int256 expectedSharesDiff = int256(uint256(withdrawalAmountGwei)) - int256(uint256(MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR)); - assertEq(vw.sharesDeltaGwei, expectedSharesDiff, "Shares delta not correct"); // Shares delta is 0 since restaked balance and amount to withdraw were max - - // ValidatorInfo storage update checks - IEigenPod.ValidatorInfo memory validatorInfo = eigenPodHarness.validatorPubkeyHashToInfo(validatorFields[0]); - assertEq(uint8(validatorInfo.status), uint8(IEigenPod.VALIDATOR_STATUS.WITHDRAWN), "Validator status should be withdrawn"); - assertEq(validatorInfo.restakedBalanceGwei, 0, "Restaked balance gwei should be 0"); + assertEq(pod.withdrawableRestakedExecutionLayerGwei(), exitedBalanceGwei, "exited balance should be withdrawable"); + + // Check ValidatorInfo values for each validator + for (uint i = 0; i < validators.length; i++) { + bytes32 pubkeyHash = beaconChain.pubkeyHash(validators[i]); + + IEigenPod.ValidatorInfo memory info = pod.validatorPubkeyHashToInfo(pubkeyHash); + assertEq(info.restakedBalanceGwei, 0, "should have 0 restaked balance"); + assertEq(info.lastCheckpointedAt, pod.lastCheckpointTimestamp(), "should have recorded correct update time"); + assertTrue(info.status == IEigenPod.VALIDATOR_STATUS.WITHDRAWN, "should have recorded correct update time"); + } } - function test_processPartialWithdrawal() public setWithdrawalCredentialsExcess { - // Set JSON & params - setJSON("./src/test/test-data/partialWithdrawalProof_Latest.json"); - _setWithdrawalProofParams(); + /// @notice fuzz test an eigenPod with multiple validators and verifyCheckpointProofs + function testFuzz_verifyCheckpointProofs(uint256 rand, bool epochRewards) public { + // Setup verifyCheckpointProofs + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + staker.verifyWithdrawalCredentials(validators); + if (epochRewards) { + beaconChain.advanceEpoch(); + } else { + beaconChain.advanceEpoch_NoRewards(); + } + staker.startCheckpoint(); - // Get params to check against - uint64 withdrawalTimestamp = withdrawalToProve.getWithdrawalTimestamp(); - uint40 validatorIndex = uint40(getValidatorIndex()); - uint64 withdrawalAmountGwei = withdrawalFields.getWithdrawalAmountGwei(); - - // Assert that partial withdrawal code path will be tested - assertLt(withdrawalToProve.getWithdrawalEpoch(), validatorFields.getWithdrawableEpoch(), "Withdrawal epoch should be less than the withdrawable epoch"); + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs( + validators, + pod.currentCheckpointTimestamp() + ); - // Process partial withdrawal - vm.expectEmit(true, true, true, true); - emit PartialWithdrawalRedeemed(validatorIndex, withdrawalTimestamp, podOwner, withdrawalAmountGwei); - IEigenPod.VerifiedWithdrawal memory vw = eigenPodHarness.verifyAndProcessWithdrawal( - beaconStateRoot, - withdrawalToProve, - validatorFieldsProof, - validatorFields, - withdrawalFields + // Verify checkpoint proofs emit the expected values + _expectEventsVerifyCheckpointProofs(staker, validators, proofs.balanceProofs); + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); + assertEq( + pod.currentCheckpointTimestamp(), + 0, + "checkpoint should be complete" ); + } +} + +/// @notice TODO +contract EigenPodUnitTests_verifyStaleBalance is EigenPodUnitTests { + /// @notice test verifyStaleBalance reverts when paused + function testFuzz_revert_verifyStaleBalancePaused(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validators[0]); + + cheats.prank(pauser); + eigenPodManagerMock.pause(2 ** PAUSED_VERIFY_STALE_BALANCE); + cheats.expectRevert("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager"); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof + }); + } - // Storage checks in _verifyAndProcessWithdrawal - bytes32 validatorPubKeyHash = validatorFields.getPubkeyHash(); - assertTrue(eigenPodHarness.provenWithdrawal(validatorPubKeyHash, withdrawalTimestamp), "Withdrawal not set to proven"); + /// @notice test verifyStaleBalance reverts when paused via the PAUSED_START_CHECKPOINT flag + function testFuzz_revert_verifyStaleBalancePausedViaStartCheckpoint(uint256 rand) public { + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validators[0]); + + cheats.prank(pauser); + eigenPodManagerMock.pause(2 ** PAUSED_START_CHECKPOINT); + cheats.expectRevert("EigenPod.onlyWhenNotPaused: index is paused in EigenPodManager"); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof + }); + } - // Checks from _processPartialWithdrawal - assertEq(eigenPod.sumOfPartialWithdrawalsClaimedGwei(), withdrawalAmountGwei, "Incorrect partial withdrawal amount"); - assertEq(vw.amountToSendGwei, withdrawalAmountGwei, "Amount to send via router is not correct"); - assertEq(vw.sharesDeltaGwei, 0, "Shares delta should be 0"); + /// @notice verifyStaleBalance should revert if validator balance too stale + function testFuzz_revert_validatorBalanceNotStale(uint256 rand) public { + // setup eigenpod staker and validators + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + uint40 validator = validators[0]; + beaconChain.advanceEpoch(); + staker.verifyWithdrawalCredentials(validators); + + staker.startCheckpoint(); + staker.completeCheckpoint(); + + uint64 lastCheckpointTimestamp = pod.lastCheckpointTimestamp(); + // proof for given beaconTimestamp is not yet stale, this should revert + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validator); + cheats.expectRevert("EigenPod.verifyStaleBalance: proof is older than last checkpoint"); + pod.verifyStaleBalance({ + beaconTimestamp: lastCheckpointTimestamp, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof + }); + } - // Assert validator still has same restaked balance and status - IEigenPod.ValidatorInfo memory validatorInfo = eigenPodHarness.validatorPubkeyHashToInfo(validatorFields[0]); - assertEq(uint8(validatorInfo.status), uint8(IEigenPod.VALIDATOR_STATUS.ACTIVE), "Validator status should be active"); - assertEq(validatorInfo.restakedBalanceGwei, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, "Restaked balance gwei should be max"); + /// @notice checks staleness condition when a pod has never completed a checkpoint before + /// The only value that will result in a revert here is `beaconTimestamp == 0` + function testFuzz_revert_validatorBalanceNotStale_NeverCheckpointed(uint256 rand) public { + // setup eigenpod staker and validators + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + uint40 validator = validators[0]; + beaconChain.advanceEpoch(); + staker.verifyWithdrawalCredentials(validators); + + // proof for given beaconTimestamp is not yet stale, this should revert + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validator); + cheats.expectRevert("EigenPod.verifyStaleBalance: proof is older than last checkpoint"); + pod.verifyStaleBalance({ + beaconTimestamp: 0, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof + }); } - function testFuzz_processFullWithdrawal(bytes32 pubkeyHash, uint64 restakedAmount, uint64 withdrawalAmount) public { - // Format validatorInfo struct - IEigenPod.ValidatorInfo memory validatorInfo = IEigenPod.ValidatorInfo({ - validatorIndex: 0, - restakedBalanceGwei: restakedAmount, - mostRecentBalanceUpdateTimestamp: 0, - status: IEigenPod.VALIDATOR_STATUS.ACTIVE + /// @notice verifyStaleBalance should revert if validator status is not ACTIVE + function testFuzz_revert_validatorStatusNotActive(uint256 rand) public { + // setup eigenpod staker and validators + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + uint40 validator = validators[0]; + + // Advance epoch and use stale balance proof without verifyingWithdrawalCredentials + // validator should be INACTIVE and cause a revert + beaconChain.advanceEpoch(); + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validator); + + cheats.expectRevert("EigenPod.verifyStaleBalance: validator is not active"); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof }); + } - // Since we're withdrawing using an ACTIVE validator, ensure we have - // a validator count to decrement - uint activeValidatorCountBefore = 1 + eigenPodHarness.getActiveValidatorCount(); - eigenPodHarness.setActiveValidatorCount(activeValidatorCountBefore); - - // Process full withdrawal. - IEigenPod.VerifiedWithdrawal memory vw = eigenPodHarness.processFullWithdrawal(0, pubkeyHash, 0, podOwner, withdrawalAmount, validatorInfo); - - // Validate that our activeValidatorCount decreased - uint activeValidatorCountAfter = eigenPodHarness.getActiveValidatorCount(); - assertEq(activeValidatorCountAfter, activeValidatorCountBefore - 1, "active validator count should decrease when withdrawing active validator"); - - // Get expected amounts based on withdrawalAmount - uint64 amountETHToQueue; - uint64 amountETHToSend; - if (withdrawalAmount > MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR){ - amountETHToQueue = MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; - amountETHToSend = withdrawalAmount - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR; - } else { - amountETHToQueue = withdrawalAmount; - amountETHToSend = 0; - } + /// @notice verifyStaleBalance should revert if validator is not slashed + function testFuzz_revert_validatorNotSlashed(uint256 rand) public { + // setup eigenpod staker and validators + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + uint40 validator = validators[0]; + staker.verifyWithdrawalCredentials(validators); + + // Advance epoch and use stale balance proof where the validator has not been slashed + // this should cause a revert + beaconChain.advanceEpoch(); + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validator); + + cheats.expectRevert("EigenPod.verifyStaleBalance: validator must be slashed to be marked stale"); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof + }); + } + + /// @notice verifyStaleBalance should revert with invalid beaconStateRoot proof length + function testFuzz_revert_beaconStateRootProofInvalidLength(uint256 rand) public { + // setup eigenpod staker and validators + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + uint40 validator = validators[0]; + staker.verifyWithdrawalCredentials(validators); + + // Slash validators and advance epoch + beaconChain.slashValidators(validators); + beaconChain.advanceEpoch(); + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validator); + + // change the proof to have an invalid length + bytes memory proofWithInvalidLength = new bytes(proofs.stateRootProof.proof.length + 1); + BeaconChainProofs.StateRootProof memory invalidStateRootProof = BeaconChainProofs.StateRootProof({ + beaconStateRoot: proofs.stateRootProof.beaconStateRoot, + proof: proofWithInvalidLength + }); + + cheats.expectRevert("BeaconChainProofs.verifyStateRoot: Proof has incorrect length"); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: invalidStateRootProof, + proof: proofs.validatorProof + }); + } - // Check invariant-> amountToQueue + amountToSend = withdrawalAmount - assertEq(vw.amountToSendGwei + eigenPod.withdrawableRestakedExecutionLayerGwei(), withdrawalAmount, "Amount to queue and send must add up to total withdrawal amount"); + /// @notice verifyStaleBalance should revert with invalid beaconStateRoot proof + function testFuzz_revert_beaconStateRootProofInvalid(uint256 rand) public { + // setup eigenpod staker and validators + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + uint40 validator = validators[0]; + staker.verifyWithdrawalCredentials(validators); + + // Slash validators and advance epoch + beaconChain.slashValidators(validators); + beaconChain.advanceEpoch(); + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validator); + + // change the proof to have an invalid value + bytes1 randValue = bytes1(keccak256(abi.encodePacked(proofs.stateRootProof.proof[0]))); + uint256 proofLength = proofs.stateRootProof.proof.length; + uint256 randIndex = bound(rand, 0, proofLength - 1); + proofs.stateRootProof.proof[randIndex] = randValue; + + cheats.expectRevert("BeaconChainProofs.verifyStateRoot: Invalid state root merkle proof"); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof + }); + } - // Check amount to queue and send - assertEq(vw.amountToSendGwei, amountETHToSend, "Amount to queue is not correct"); - assertEq(eigenPod.withdrawableRestakedExecutionLayerGwei(), amountETHToQueue, "Incorrect withdrawable restaked execution layer gwei"); + /// @notice verifyStaleBalance should revert with invalid validatorFields and validator proof length + function testFuzz_revert_validatorContainerProofInvalidLength( + uint256 rand + ) public { + // setup eigenpod staker and validators + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + uint40 validator = validators[0]; + staker.verifyWithdrawalCredentials(validators); + + // Slash validators and advance epoch + beaconChain.slashValidators(validators); + beaconChain.advanceEpoch(); + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validator); + + // change the proof to have an invalid length + uint256 proofLength = proofs.validatorProof.proof.length; + bytes memory invalidProof = new bytes(proofLength + 1); + BeaconChainProofs.ValidatorProof memory invalidValidatorProof = BeaconChainProofs.ValidatorProof({ + validatorFields: proofs.validatorProof.validatorFields, + proof: invalidProof + }); + cheats.expectRevert("BeaconChainProofs.verifyValidatorFields: Proof has incorrect length"); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + proof: invalidValidatorProof + }); - // Check shares delta - int256 expectedSharesDelta = int256(uint256(amountETHToQueue)) - int256(uint256(restakedAmount)); - assertEq(vw.sharesDeltaGwei, expectedSharesDelta, "Shares delta not correct"); + // Change the validator fields to have an invalid length + bytes32[] memory validatorFieldsInvalidLength = new bytes32[](proofs.validatorProof.validatorFields.length + 1); + for (uint256 i = 0; i < proofs.validatorProof.validatorFields.length; i++) { + validatorFieldsInvalidLength[i] = proofs.validatorProof.validatorFields[i]; + } + proofs.validatorProof.validatorFields = validatorFieldsInvalidLength; - // Storage checks - IEigenPod.ValidatorInfo memory validatorInfoAfter = eigenPodHarness.validatorPubkeyHashToInfo(pubkeyHash); - assertEq(uint8(validatorInfoAfter.status), uint8(IEigenPod.VALIDATOR_STATUS.WITHDRAWN), "Validator status should be withdrawn"); - assertEq(validatorInfoAfter.restakedBalanceGwei, 0, "Restaked balance gwei should be 0"); + cheats.expectRevert("BeaconChainProofs.verifyValidatorFields: Validator fields has incorrect length"); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof + }); } - function testFuzz_processFullWithdrawal_lessMaxRestakedBalance(bytes32 pubkeyHash, uint64 restakedAmount, uint64 withdrawalAmount) public { - withdrawalAmount = uint64(bound(withdrawalAmount, 0, MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR)); - testFuzz_processFullWithdrawal(pubkeyHash, restakedAmount, withdrawalAmount); + /// @notice verifyStaleBalance should revert with invalid validatorContainer proof + function testFuzz_revert_validatorContainerProofInvalid( + uint256 rand, + bytes32 randWithdrawalCredentials + ) public { + // setup eigenpod staker and validators + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + uint40 validator = validators[0]; + staker.verifyWithdrawalCredentials(validators); + + // Slash validators and advance epoch + beaconChain.slashValidators(validators); + beaconChain.advanceEpoch(); + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validator); + + // change validator withdrawal creds to an invalid value causing a revert + uint256 VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX = 1; + proofs.validatorProof.validatorFields[VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX] = randWithdrawalCredentials; + + cheats.expectRevert("BeaconChainProofs.verifyValidatorFields: Invalid merkle proof"); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof + }); } - - function testFuzz_processPartialWithdrawal( - uint40 validatorIndex, - uint64 withdrawalTimestamp, - address recipient, - uint64 partialWithdrawalAmountGwei + + function testFuzz_verifyStaleBalance( + uint256 rand ) public { - IEigenPod.VerifiedWithdrawal memory vw = eigenPodHarness.processPartialWithdrawal(validatorIndex, withdrawalTimestamp, recipient, partialWithdrawalAmountGwei); + // setup eigenpod staker and validators + (EigenPodUser staker,) = _newEigenPodStaker({ rand: rand }); + EigenPod pod = staker.pod(); + (uint40[] memory validators,) = staker.startValidators(); + uint40 validator = validators[0]; + staker.verifyWithdrawalCredentials(validators); + + // Slash validators and advance epoch + beaconChain.slashValidators(validators); + beaconChain.advanceEpoch(); + StaleBalanceProofs memory proofs = beaconChain.getStaleBalanceProofs(validator); + + cheats.expectEmit(true, true, true, true, address(staker.pod())); + emit CheckpointCreated(uint64(block.timestamp), EIP_4788_ORACLE.timestampToBlockRoot(block.timestamp), validators.length); + pod.verifyStaleBalance({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + proof: proofs.validatorProof + }); + check_StartCheckpoint_State(staker); + } +} - // Checks - assertEq(eigenPod.sumOfPartialWithdrawalsClaimedGwei(), partialWithdrawalAmountGwei, "Incorrect partial withdrawal amount"); - assertEq(vw.amountToSendGwei, partialWithdrawalAmountGwei, "Amount to send via router is not correct"); - assertEq(vw.sharesDeltaGwei, 0, "Shares delta should be 0"); +contract EigenPodHarnessSetup is EigenPodUnitTests { + // Harness that exposes internal functions for test + EigenPodHarness public eigenPodHarnessImplementation; + EigenPodHarness public eigenPodHarness; + + function setUp() public virtual override { + EigenPodUnitTests.setUp(); + + // Deploy EP Harness + eigenPodHarnessImplementation = new EigenPodHarness( + ethPOSDepositMock, + eigenPodManagerMock, + GENESIS_TIME_LOCAL + ); + + // Upgrade eigenPod to harness + UpgradeableBeacon(address(eigenPodBeacon)).upgradeTo(address(eigenPodHarnessImplementation)); + eigenPodHarness = EigenPodHarness(payable(eigenPod)); + } +} + +/// @notice No unit tests as of now but would be good to add specific unit tests using proofs from our proofGen library +/// for a EigenPod on Holesky +contract EigenPodUnitTests_proofParsingTests is EigenPodHarnessSetup, ProofParsing { + using BytesLib for bytes; + using BeaconChainProofs for *; + + // Params to _verifyWithdrawalCredentials, can be set in test or helper function + uint64 oracleTimestamp; + bytes32 beaconStateRoot; + uint40 validatorIndex; + bytes validatorFieldsProof; + bytes32[] validatorFields; + + function _assertWithdrawalCredentialsSet(uint256 restakedBalanceGwei) internal { + IEigenPod.ValidatorInfo memory validatorInfo = eigenPodHarness.validatorPubkeyHashToInfo(validatorFields[0]); + assertEq(uint8(validatorInfo.status), uint8(IEigenPod.VALIDATOR_STATUS.ACTIVE), "Validator status should be active"); + assertEq(validatorInfo.validatorIndex, validatorIndex, "Validator index incorrectly set"); + assertEq(validatorInfo.lastCheckpointedAt, oracleTimestamp, "Last checkpointed at timestamp incorrectly set"); + assertEq(validatorInfo.restakedBalanceGwei, restakedBalanceGwei, "Restaked balance gwei not set correctly"); } - function _setWithdrawalProofParams() internal { - // Set validator index, beacon state root, balance update proof, and validator fields + function _setWithdrawalCredentialParams() public { + // Set beacon state root, validatorIndex beaconStateRoot = getBeaconStateRoot(); + validatorIndex = uint40(getValidatorIndex()); + validatorFieldsProof = getWithdrawalCredentialProof(); // Validator fields are proven here validatorFields = getValidatorFields(); - validatorFieldsProof = abi.encodePacked(getValidatorProof()); - withdrawalToProve = _getWithdrawalProof(); - withdrawalFields = getWithdrawalFields(); - } - - /// @notice this function just generates a valid proof so that we can test other functionalities of the withdrawal flow - function _getWithdrawalProof() internal returns (BeaconChainProofs.WithdrawalProof memory) { - { - bytes32 blockRoot = getBlockRoot(); - bytes32 slotRoot = getSlotRoot(); - bytes32 timestampRoot = getTimestampRoot(); - bytes32 executionPayloadRoot = getExecutionPayloadRoot(); - bytes memory withdrawalProof = IS_DENEB ? abi.encodePacked(getWithdrawalProofDeneb()) : abi.encodePacked(getWithdrawalProofCapella()); - bytes memory timestampProof = IS_DENEB ? abi.encodePacked(getTimestampProofDeneb()) : abi.encodePacked(getTimestampProofCapella()); - return - BeaconChainProofs.WithdrawalProof( - abi.encodePacked(withdrawalProof), - abi.encodePacked(getSlotProof()), - abi.encodePacked(getExecutionPayloadProof()), - abi.encodePacked(timestampProof), - abi.encodePacked(getHistoricalSummaryProof()), - uint64(getBlockRootIndex()), - uint64(getHistoricalSummaryIndex()), - uint64(getWithdrawalIndex()), - blockRoot, - slotRoot, - timestampRoot, - executionPayloadRoot - ); - } + + // Get an oracle timestamp + cheats.warp(GENESIS_TIME_LOCAL + 1 days); + oracleTimestamp = uint64(block.timestamp); } ///@notice Effective balance is > 32 ETH @@ -1074,16 +1776,15 @@ contract EigenPodUnitTests_WithdrawalTests is EigenPodHarnessSetup, ProofParsing setJSON("./src/test/test-data/withdrawal_credential_proof_302913.json"); // Set beacon state root, validatorIndex beaconStateRoot = getBeaconStateRoot(); - uint40 validatorIndex = uint40(getValidatorIndex()); - validatorFieldsProof = abi.encodePacked(getWithdrawalCredentialProof()); // Validator fields are proven here + validatorIndex = uint40(getValidatorIndex()); + validatorFieldsProof = getWithdrawalCredentialProof(); // Validator fields are proven here validatorFields = getValidatorFields(); // Get an oracle timestamp - cheats.warp(GOERLI_GENESIS_TIME + 1 days); - uint64 oracleTimestamp = uint64(block.timestamp); + cheats.warp(GENESIS_TIME_LOCAL + 1 days); + oracleTimestamp = uint64(block.timestamp); eigenPodHarness.verifyWithdrawalCredentials( - oracleTimestamp, beaconStateRoot, validatorIndex, validatorFieldsProof, diff --git a/src/test/unit/RewardsCoordinatorUnit.t.sol b/src/test/unit/RewardsCoordinatorUnit.t.sol index 8cca424ea..609472199 100644 --- a/src/test/unit/RewardsCoordinatorUnit.t.sol +++ b/src/test/unit/RewardsCoordinatorUnit.t.sol @@ -1739,8 +1739,7 @@ contract RewardsCoordinatorUnitTests_processClaim is RewardsCoordinatorUnitTests /// @notice tests with earnerIndex and tokenIndex set to max value and using alternate claim proofs function testFuzz_processClaim_WhenMaxEarnerIndexAndTokenIndex( bool setClaimerFor, - address claimerFor, - uint8 numShift + address claimerFor ) public filterFuzzedAddressInputs(claimerFor) { // Hardcode earner address to earner in alternate claim proofs earner = 0x25A1B7322f9796B26a4Bec125913b34C292B28D6; @@ -1808,8 +1807,7 @@ contract RewardsCoordinatorUnitTests_processClaim is RewardsCoordinatorUnitTests /// @notice tests with single token leaf for the earner's subtree. tokenTreeProof for the token in the claim should be empty function testFuzz_processClaim_WhenSingleTokenLeaf( bool setClaimerFor, - address claimerFor, - uint8 numShift + address claimerFor ) public filterFuzzedAddressInputs(claimerFor) { // if setClaimerFor is true, set the earners claimer to the fuzzed address address claimer; @@ -1871,8 +1869,7 @@ contract RewardsCoordinatorUnitTests_processClaim is RewardsCoordinatorUnitTests /// @notice tests with single earner leaf in the merkle tree. earnerTreeProof in claim should be empty function testFuzz_processClaim_WhenSingleEarnerLeaf( bool setClaimerFor, - address claimerFor, - uint8 numShift + address claimerFor ) public filterFuzzedAddressInputs(claimerFor) { // Hardcode earner address to earner in alternate claim proofs earner = 0x0D6bA28b9919CfCDb6b233469Cc5Ce30b979e08E; diff --git a/src/test/utils/BeaconChainProofsWrapper.sol b/src/test/utils/BeaconChainProofsWrapper.sol new file mode 100644 index 000000000..d093848d4 --- /dev/null +++ b/src/test/utils/BeaconChainProofsWrapper.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "src/contracts/libraries/BeaconChainProofs.sol"; + +/// @notice This contract is used to test offchain proof generation +contract BeaconChainProofsWrapper { + + function verifyStateRoot( + bytes32 beaconBlockRoot, + BeaconChainProofs.StateRootProof calldata proof + ) external view { + BeaconChainProofs.verifyStateRoot(beaconBlockRoot, proof); + } + + function verifyValidatorFields( + bytes32 beaconStateRoot, + bytes32[] calldata validatorFields, + bytes calldata validatorFieldsProof, + uint40 validatorIndex + ) external view { + BeaconChainProofs.verifyValidatorFields(beaconStateRoot, validatorFields, validatorFieldsProof, validatorIndex); + } + + function verifyBalanceContainer( + bytes32 beaconBlockRoot, + BeaconChainProofs.BalanceContainerProof calldata proof + ) external view { + BeaconChainProofs.verifyBalanceContainer(beaconBlockRoot, proof); + } + + function verifyValidatorBalance( + bytes32 balanceContainerRoot, + uint40 validatorIndex, + BeaconChainProofs.BalanceProof calldata proof + ) external view { + BeaconChainProofs.verifyValidatorBalance(balanceContainerRoot, validatorIndex, proof); + } + + +} \ No newline at end of file diff --git a/src/test/utils/EigenLayerUnitTestSetup.sol b/src/test/utils/EigenLayerUnitTestSetup.sol index a273d2ecb..ee2664f23 100644 --- a/src/test/utils/EigenLayerUnitTestSetup.sol +++ b/src/test/utils/EigenLayerUnitTestSetup.sol @@ -19,7 +19,7 @@ abstract contract EigenLayerUnitTestSetup is EigenLayerUnitTestBase { strategyManagerMock = new StrategyManagerMock(); delegationManagerMock = new DelegationManagerMock(); slasherMock = new SlasherMock(); - eigenPodManagerMock = new EigenPodManagerMock(); + eigenPodManagerMock = new EigenPodManagerMock(pauserRegistry); addressIsExcludedFromFuzzedInputs[address(0)] = true; addressIsExcludedFromFuzzedInputs[address(strategyManagerMock)] = true; diff --git a/src/test/utils/EigenPodUser.t.sol b/src/test/utils/EigenPodUser.t.sol new file mode 100644 index 000000000..8e62b26ef --- /dev/null +++ b/src/test/utils/EigenPodUser.t.sol @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; + +import "src/contracts/pods/EigenPodManager.sol"; +import "src/contracts/pods/EigenPod.sol"; + +import "src/contracts/interfaces/IStrategy.sol"; + +import "src/test/integration/TimeMachine.t.sol"; +import "src/test/integration/mocks/BeaconChainMock.t.sol"; +import "src/test/integration/utils/PrintUtils.t.sol"; + +struct Validator { + uint40 index; +} + +interface IUserDeployer { + function timeMachine() external view returns (TimeMachine); + function beaconChain() external view returns (BeaconChainMock); + function eigenPodBeacon() external view returns (IBeacon); +} + +contract EigenPodUser is PrintUtils { + + Vm cheats = Vm(HEVM_ADDRESS); + + TimeMachine timeMachine; + BeaconChainMock beaconChain; + IBeacon public eigenPodBeacon; + + + string _NAME; + + // User's EigenPod and each of their validator indices within that pod + EigenPod public pod; + uint40[] validators; + + IStrategy constant BEACONCHAIN_ETH_STRAT = IStrategy(0xbeaC0eeEeeeeEEeEeEEEEeeEEeEeeeEeeEEBEaC0); + IERC20 constant NATIVE_ETH = IERC20(0xbeaC0eeEeeeeEEeEeEEEEeeEEeEeeeEeeEEBEaC0); + uint constant GWEI_TO_WEI = 1e9; + + bytes internal constant beaconProxyBytecode = + hex"608060405260405161090e38038061090e83398101604081905261002291610460565b61002e82826000610035565b505061058a565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610520565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610520565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108e7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe919061053b565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c65782516103bf576001600160a01b0385163b6103bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d0565b6103d083836103d8565b949350505050565b8151156103e85781518083602001fd5b8060405162461bcd60e51b81526004016101699190610557565b80516001600160a01b038116811461041957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044f578181015183820152602001610437565b838111156100f95750506000910152565b6000806040838503121561047357600080fd5b61047c83610402565b60208401519092506001600160401b038082111561049957600080fd5b818501915085601f8301126104ad57600080fd5b8151818111156104bf576104bf61041e565b604051601f8201601f19908116603f011681019083821181831017156104e7576104e761041e565b8160405282815288602084870101111561050057600080fd5b610511836020830160208801610434565b80955050505050509250929050565b60006020828403121561053257600080fd5b6102c882610402565b6000825161054d818460208701610434565b9190910192915050565b6020815260008251806020840152610576816040850160208701610434565b601f01601f19169190910160400192915050565b61034e806105996000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102f260279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb9190610249565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b03168560405161014191906102a2565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020d578251610206576001600160a01b0385163b6102065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610217565b610217838361021f565b949350505050565b81511561022f5781518083602001fd5b8060405162461bcd60e51b81526004016101fd91906102be565b60006020828403121561025b57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028d578181015183820152602001610275565b8381111561029c576000848401525b50505050565b600082516102b4818460208701610272565b9190910192915050565b60208152600082518060208401526102dd816040850160208701610272565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d51e81d3bc5ed20a26aeb05dce7e825c503b2061aa78628027300c8d65b9d89a64736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564"; + + constructor(string memory name) { + IUserDeployer deployer = IUserDeployer(msg.sender); + + timeMachine = deployer.timeMachine(); + beaconChain = deployer.beaconChain(); + eigenPodBeacon = deployer.eigenPodBeacon(); + pod = EigenPod(payable( + Create2.deploy( + 0, + bytes32(uint256(uint160(address(this)))), + // set the beacon address to the eigenPodBeacon + abi.encodePacked(beaconProxyBytecode, abi.encode(eigenPodBeacon, "")) + ))); + pod.initialize(address(this)); + + _NAME = name; + } + + modifier createSnapshot() virtual { + timeMachine.createSnapshot(); + _; + } + + receive() external payable {} + + function NAME() public view override returns (string memory) { + return _NAME; + } + + /******************************************************************************* + BEACON CHAIN METHODS + *******************************************************************************/ + + /// @dev Uses any ETH held by the User to start validators on the beacon chain + /// @return A list of created validator indices + /// @return The amount of wei sent to the beacon chain + /// Note: If the user does not have enough ETH to start a validator, this method reverts + /// Note: This method also advances one epoch forward on the beacon chain, so that + /// withdrawal credential proofs are generated for each validator. + function startValidators() public createSnapshot virtual returns (uint40[] memory, uint) { + _logM("startValidators"); + + return _startValidators(); + } + + function exitValidators(uint40[] memory _validators) public createSnapshot virtual returns (uint64 exitedBalanceGwei) { + _logM("exitValidators"); + + return _exitValidators(_validators); + } + + /******************************************************************************* + EIGENPOD METHODS + *******************************************************************************/ + + function verifyWithdrawalCredentials( + uint40[] memory _validators + ) public createSnapshot virtual { + _logM("verifyWithdrawalCredentials"); + + _verifyWithdrawalCredentials(_validators); + } + + function startCheckpoint() public createSnapshot virtual { + _logM("startCheckpoint"); + + _startCheckpoint(); + } + + function completeCheckpoint() public createSnapshot virtual { + _logM("completeCheckpoint"); + + _completeCheckpoint(); + } + + /******************************************************************************* + INTERNAL METHODS + *******************************************************************************/ + + /// @dev Uses any ETH held by the User to start validators on the beacon chain + /// @return A list of created validator indices + /// @return The amount of wei sent to the beacon chain + /// Note: If the user does not have enough ETH to start a validator, this method reverts + /// Note: This method also advances one epoch forward on the beacon chain, so that + /// withdrawal credential proofs are generated for each validator. + function _startValidators() internal returns (uint40[] memory, uint) { + uint balanceWei = address(this).balance; + + // Number of full validators: balance / 32 ETH + uint numValidators = balanceWei / 32 ether; + balanceWei -= (numValidators * 32 ether); + + // If we still have at least 1 ETH left over, we can create another (non-full) validator + // Note that in the mock beacon chain this validator will generate rewards like any other. + // The main point is to ensure pods are able to handle validators that have less than 32 ETH + uint lastValidatorBalance; + uint totalValidators = numValidators; + if (balanceWei >= 1 ether) { + lastValidatorBalance = balanceWei - (balanceWei % 1 gwei); + balanceWei -= lastValidatorBalance; + totalValidators++; + } + + require(totalValidators != 0, "startValidators: not enough ETH to start a validator"); + uint40[] memory newValidators = new uint40[](totalValidators); + uint totalBeaconBalance = address(this).balance - balanceWei; + + _log("- creating new validators", newValidators.length); + _log("- depositing balance to beacon chain (wei)", totalBeaconBalance); + + // Create each of the full validators + for (uint i = 0; i < numValidators; i++) { + uint40 validatorIndex = beaconChain.newValidator{ + value: 32 ether + }(_podWithdrawalCredentials()); + + newValidators[i] = validatorIndex; + validators.push(validatorIndex); + } + + // If we had a remainder, create the final, non-full validator + if (totalValidators == numValidators + 1) { + uint40 validatorIndex = beaconChain.newValidator{ + value: lastValidatorBalance + }(_podWithdrawalCredentials()); + + newValidators[newValidators.length - 1] = validatorIndex; + validators.push(validatorIndex); + } + + // Advance forward one epoch and generate withdrawal and balance proofs for each validator + beaconChain.advanceEpoch_NoRewards(); + + return (newValidators, totalBeaconBalance); + } + + function _exitValidators(uint40[] memory _validators) internal returns (uint64 exitedBalanceGwei) { + _log("- exiting num validators", _validators.length); + + for (uint i = 0; i < _validators.length; i++) { + exitedBalanceGwei += beaconChain.exitValidator(_validators[i]); + } + + _log("- exited balance to pod (gwei)", exitedBalanceGwei); + + return exitedBalanceGwei; + } + + function _startCheckpoint() internal { + pod.startCheckpoint(false); + } + + function _completeCheckpoint() internal { + _log("- active validator count", pod.activeValidatorCount()); + _log("- proofs remaining", pod.currentCheckpoint().proofsRemaining); + + uint64 checkpointTimestamp = pod.currentCheckpointTimestamp(); + if (checkpointTimestamp == 0) { + revert("User._completeCheckpoint: no existing checkpoint"); + } + + CheckpointProofs memory proofs = beaconChain.getCheckpointProofs(validators, checkpointTimestamp); + _log("- submitting num checkpoint proofs", proofs.balanceProofs.length); + + pod.verifyCheckpointProofs({ + balanceContainerProof: proofs.balanceContainerProof, + proofs: proofs.balanceProofs + }); + } + + function _verifyWithdrawalCredentials(uint40[] memory _validators) internal { + CredentialProofs memory proofs = beaconChain.getCredentialProofs(_validators); + + pod.verifyWithdrawalCredentials({ + beaconTimestamp: proofs.beaconTimestamp, + stateRootProof: proofs.stateRootProof, + validatorIndices: _validators, + validatorFieldsProofs: proofs.validatorFieldsProofs, + validatorFields: proofs.validatorFields + }); + } + + function _podWithdrawalCredentials() internal view returns (bytes memory) { + return abi.encodePacked(bytes1(uint8(1)), bytes11(0), address(pod)); + } + + function getActiveValidators() public view returns (uint40[] memory) { + uint40[] memory activeValidators = new uint40[](validators.length); + + uint numActive; + uint pos; + for(uint i = 0; i < validators.length; i++) { + if (beaconChain.isActive(validators[i])) { + activeValidators[pos] = validators[i]; + numActive++; + pos++; + } + } + + // Manually update length + assembly { mstore(activeValidators, numActive) } + + return activeValidators; + } +} \ No newline at end of file diff --git a/src/test/utils/ProofParsing.sol b/src/test/utils/ProofParsing.sol index fd69678ec..e3607e07b 100644 --- a/src/test/utils/ProofParsing.sol +++ b/src/test/utils/ProofParsing.sol @@ -115,13 +115,13 @@ contract ProofParsing is Test { return slotProof; } - function getStateRootProof() public returns(bytes32[] memory) { + function getStateRootProof() public returns(bytes memory) { bytes32[] memory stateRootProof = new bytes32[](3); for (uint i = 0; i < 3; i++) { prefix = string.concat(".StateRootAgainstLatestBlockHeaderProof[", string.concat(vm.toString(i), "]")); stateRootProof[i] = (stdJson.readBytes32(proofConfigJson, prefix)); } - return stateRootProof; + return abi.encodePacked(stateRootProof); } function getWithdrawalProofDeneb() public returns(bytes32[10] memory) { @@ -174,18 +174,18 @@ contract ProofParsing is Test { return validatorFields; } - function getBalanceUpdateProof() public returns(bytes32[] memory) { + function getBalanceUpdateProof() public returns(bytes memory) { // Balance update proofs are the same as withdrawal credential proofs return getWithdrawalCredentialProof(); } - function getWithdrawalCredentialProof() public returns(bytes32[] memory) { + function getWithdrawalCredentialProof() public returns(bytes memory) { bytes32[] memory withdrawalCredentialProof = new bytes32[](46); for (uint i = 0; i < 46; i++) { prefix = string.concat(".WithdrawalCredentialProof[", string.concat(vm.toString(i), "]")); withdrawalCredentialProof[i] = (stdJson.readBytes32(proofConfigJson, prefix)); } - return withdrawalCredentialProof; + return abi.encodePacked(withdrawalCredentialProof); } function getValidatorFieldsProof() public returns(bytes32[] memory) {