Skip to content

Commit

Permalink
feat: slashing
Browse files Browse the repository at this point in the history
* chore: pending delay calc cleanup

* chore: storage pointer cleanup

* eigenpods slashing updates (#745)

* squash yet again

* change again

* update checkpoint struct

* feat: AllocationManager Storage Simplification  (#787)

* feat: cleanup

* feat: add helper func

* fix: simplification

* chore: clean up magnitude info usage and type conversions

* refactor: review changes

* fix: order struct params by size

* fix: correct and simplify calc for slashed pending magnitude

* fix: storage gap

* feat: cleanup

* chore: remove some type conversion bs and minor formatting

* chore: clean up free magnitude logic

* chore: rename pending deallocations and fix stack too deep

* feat: slashing magnitudes cleanup (#786)

* refactor: slashing magnitudes cleanup
* refactor: assert `bipToSlash` is bounded
* assert `bipsToSlash` is lte 100% and gt 0%.

* refactor: move `isOperatorSlashable` -> AVSD

* refactor: batch validate opsets on allocations

- adds `AVSD.isOperatorSetBatch(operatorSets)`

* feat: add pausing to ALM

* refactor: remove single use helper

- removes `_getLatestTotalMagnitude(operator, strategy)`

* refactor: rename `ALLOCATION_DELAY_CONFIGURATION_DELAY`

* refactor: remove `Slasher`

* refactor: move constants + immutables to storage contracts

* refactor: custom errors `RewardsCoordinatorStorage`

* chore: dependency cleanup

* fix: remove unused internal getter

* chore: batch validate operator sets and minor cleanup

* fix: fix stack too deep and compiler errors

---------

Co-authored-by: wadealexc <[email protected]>
  • Loading branch information
gpsanant and wadealexc committed Oct 4, 2024
1 parent cc96e9f commit 069c669
Show file tree
Hide file tree
Showing 87 changed files with 7,906 additions and 2,666 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,7 @@ InheritanceGraph.png
surya_report.md

.idea

*state.json
deployed_strategies.json
populate_src*
1 change: 0 additions & 1 deletion .solhintignore
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
Slasher.sol
85 changes: 0 additions & 85 deletions certora/harnesses/SlasherHarness.sol

This file was deleted.

2 changes: 1 addition & 1 deletion certora/scripts/core/verifyDelegationManager.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ solc-select use 0.8.27
certoraRun certora/harnesses/DelegationManagerHarness.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/strategies/StrategyBase.sol src/contracts/core/StrategyManager.sol \
src/contracts/core/Slasher.sol src/contracts/permissions/PauserRegistry.sol \
src/contracts/permissions/PauserRegistry.sol \
--verify DelegationManagerHarness:certora/specs/core/DelegationManager.spec \
--solc_via_ir \
--solc_optimize 1 \
Expand Down
2 changes: 1 addition & 1 deletion certora/scripts/core/verifyStrategyManager.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ 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/strategies/StrategyBase.sol src/contracts/core/DelegationManager.sol \
src/contracts/core/Slasher.sol src/contracts/permissions/PauserRegistry.sol \
src/contracts/permissions/PauserRegistry.sol \
--verify StrategyManagerHarness:certora/specs/core/StrategyManager.spec \
--solc_via_ir \
--solc_optimize 1 \
Expand Down
2 changes: 1 addition & 1 deletion certora/scripts/pods/verifyEigenPod.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fi

# 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/permissions/PauserRegistry.sol \
# src/contracts/core/StrategyManager.sol \
# src/contracts/strategies/StrategyBase.sol \
# lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol \
Expand Down
2 changes: 1 addition & 1 deletion certora/scripts/pods/verifyEigenPodManager.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fi

# 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 \
# src/contracts/permissions/PauserRegistry.sol \
# --verify EigenPodManagerHarness:certora/specs/pods/EigenPodManager.spec \
# --optimistic_loop \
# --optimistic_fallback \
Expand Down
1 change: 0 additions & 1 deletion certora/scripts/strategies/verifyStrategyBase.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ certoraRun src/contracts/strategies/StrategyBase.sol \
lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol \
src/contracts/core/StrategyManager.sol \
src/contracts/permissions/PauserRegistry.sol \
src/contracts/core/Slasher.sol \
--verify StrategyBase:certora/specs/strategies/StrategyBase.spec \
--solc_via_ir \
--solc_optimize 1 \
Expand Down
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This document provides an overview of system components, contracts, and user rol
* [Depositing Into EigenLayer](#depositing-into-eigenlayer)
* [Delegating to an Operator](#delegating-to-an-operator)
* [Undelegating or Queueing a Withdrawal](#undelegating-or-queueing-a-withdrawal)
* [Completing a Withdrawal as Shares](#completing-a-withdrawal-as-shares)
* [Completing a Withdrawal as OwnedShares](#completing-a-withdrawal-as-shares)
* [Completing a Withdrawal as Tokens](#completing-a-withdrawal-as-tokens)
* [Withdrawal Processing: Validator Exits](#withdrawal-processing-validator-exits)
* [Withdrawal Processing: Partial Beacon Chain Withdrawals](#withdrawal-processing-partial-beacon-chain-withdrawals)
Expand Down Expand Up @@ -156,7 +156,7 @@ Undelegating from an Operator automatically queues a withdrawal that needs to go

![.](./images/Staker%20Flow%20Diagrams/Queue%20Withdrawal.png)

##### Completing a Withdrawal as Shares
##### Completing a Withdrawal as OwnedShares

This flow is mostly useful if a Staker wants to change which Operator they are delegated to. The Staker first needs to undelegate (see above). At this point, they can delegate to a different Operator. However, the new Operator will only be awarded shares once the Staker completes their queued withdrawal "as shares":

Expand Down
10 changes: 5 additions & 5 deletions docs/core/DelegationManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,9 @@ For each strategy/share pair in the `Withdrawal`:

`Withdrawals` concerning `EigenPodManager` shares have some additional nuance depending on whether a withdrawal is specified to be received as tokens vs shares (read more about "why" in [`EigenPodManager.md`](./EigenPodManager.md)):
* `EigenPodManager` withdrawals received as shares:
* Shares ALWAYS go back to the originator of the withdrawal (rather than the `withdrawer` address).
* Shares are also delegated to the originator's Operator, rather than the `withdrawer's` Operator.
* Shares received by the originator may be lower than the shares originally withdrawn if the originator has debt.
* OwnedShares ALWAYS go back to the originator of the withdrawal (rather than the `withdrawer` address).
* OwnedShares are also delegated to the originator's Operator, rather than the `withdrawer's` Operator.
* OwnedShares received by the originator may be lower than the shares originally withdrawn if the originator has debt.
* `EigenPodManager` withdrawals received as tokens:
* Before the withdrawal can be completed, the originator needs to prove that a withdrawal occurred on the beacon chain (see [`EigenPod.verifyAndProcessWithdrawals`](./EigenPodManager.md#eigenpodverifyandprocesswithdrawals)).

Expand All @@ -288,10 +288,10 @@ For each strategy/share pair in the `Withdrawal`:
* See [`EigenPodManager.withdrawSharesAsTokens`](./EigenPodManager.md#eigenpodmanagerwithdrawsharesastokens)
* If `!receiveAsTokens`:
* For `StrategyManager` strategies:
* Shares are awarded to the `withdrawer` and delegated to the `withdrawer's` Operator
* OwnedShares are awarded to the `withdrawer` and delegated to the `withdrawer's` Operator
* See [`StrategyManager.addShares`](./StrategyManager.md#addshares)
* For the native beacon chain ETH strategy (`EigenPodManager`):
* Shares are awarded to `withdrawal.staker`, and delegated to the Staker's Operator
* OwnedShares are awarded to `withdrawal.staker`, and delegated to the Staker's Operator
* See [`EigenPodManager.addShares`](./EigenPodManager.md#eigenpodmanageraddshares)

*Requirements*:
Expand Down
2 changes: 1 addition & 1 deletion docs/core/EigenPod.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Checkpoint proofs comprise the bulk of proofs submitted to an `EigenPod`. Comple
* 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.
When a checkpoint is completed, shares are updated accordingly for each of these events. OwnedShares 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)
Expand Down
37 changes: 21 additions & 16 deletions docs/storage-report/AVSDirectory.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
| Name | Type | Slot | Offset | Bytes | Contract |
|---------------------|------------------------------------------------------------------------------------------|------|--------|-------|--------------------------------------------------|
| _initialized | uint8 | 0 | 0 | 1 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _initializing | bool | 0 | 1 | 1 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[50] | 1 | 0 | 1600 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _owner | address | 51 | 0 | 20 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[49] | 52 | 0 | 1568 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| pauserRegistry | contract IPauserRegistry | 101 | 0 | 20 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _paused | uint256 | 102 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[48] | 103 | 0 | 1536 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _DOMAIN_SEPARATOR | bytes32 | 151 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| avsOperatorStatus | mapping(address => mapping(address => enum IAVSDirectory.OperatorAVSRegistrationStatus)) | 152 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| operatorSaltIsSpent | mapping(address => mapping(bytes32 => bool)) | 153 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[47] | 154 | 0 | 1504 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _status | uint256 | 201 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[49] | 202 | 0 | 1568 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| Name | Type | Slot | Offset | Bytes | Contract |
|-----------------------|---------------------------------------------------------------------------------------------------------------|------|--------|-------|--------------------------------------------------|
| _initialized | uint8 | 0 | 0 | 1 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _initializing | bool | 0 | 1 | 1 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[50] | 1 | 0 | 1600 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _owner | address | 51 | 0 | 20 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[49] | 52 | 0 | 1568 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| pauserRegistry | contract IPauserRegistry | 101 | 0 | 20 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _paused | uint256 | 102 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[48] | 103 | 0 | 1536 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _DOMAIN_SEPARATOR | bytes32 | 151 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| avsOperatorStatus | mapping(address => mapping(address => enum IAVSDirectory.OperatorAVSRegistrationStatus)) | 152 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| operatorSaltIsSpent | mapping(address => mapping(bytes32 => bool)) | 153 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| isOperatorSetAVS | mapping(address => bool) | 154 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| isOperatorSet | mapping(address => mapping(uint32 => bool)) | 155 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _operatorSetsMemberOf | mapping(address => struct EnumerableSet.Bytes32Set) | 156 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _operatorSetMembers | mapping(bytes32 => struct EnumerableSet.AddressSet) | 157 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| operatorSetStatus | mapping(address => mapping(address => mapping(uint32 => struct IAVSDirectory.OperatorSetRegistrationStatus))) | 158 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[42] | 159 | 0 | 1344 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| _status | uint256 | 201 | 0 | 32 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
| __gap | uint256[49] | 202 | 0 | 1568 | src/contracts/core/AVSDirectory.sol:AVSDirectory |
Loading

0 comments on commit 069c669

Please sign in to comment.