Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: slashing release #679

Open
wants to merge 33 commits into
base: custom-errors
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d98c5a7
feat: squashed slashing for devnet
8sunyuan Sep 12, 2024
89bbc30
feat: add shares to queue event (#847)
gpsanant Oct 21, 2024
c1c8c6b
feat: named mapping params (#848)
0xClandestine Oct 22, 2024
f0b746d
chore: new storage (#851)
gpsanant Oct 23, 2024
5ca71fc
Gpsanant/current stakes (#846)
gpsanant Oct 23, 2024
12848bb
slashing: cleanup (#842)
8sunyuan Oct 23, 2024
b30e1c7
slashing: fully slashed strategies (#850)
8sunyuan Oct 28, 2024
9975936
EigenPod/EPM Happy Path Test Cases (#857)
ypatil12 Oct 28, 2024
385dc53
slashing: revert timestamps delegation (#861)
8sunyuan Oct 30, 2024
4b4298d
refactor: optimize pausable (#854)
0xClandestine Oct 30, 2024
0b6b009
feat: small delegation refactors (#866)
wadealexc Nov 1, 2024
26c1697
slashing: change queue withdrawal input to deposit shares (#869)
8sunyuan Nov 4, 2024
2639e35
feat: remove delegate to by signature (#871)
wadealexc Nov 4, 2024
88b5f17
feat: track staker withdrawals (#864)
0xClandestine Nov 4, 2024
b850371
Fix: Flaky DM Test (#875)
ypatil12 Nov 5, 2024
9ee60c8
feat: move operator set functionality to alm (#860)
wadealexc Nov 6, 2024
b18ec68
fix: change to sharesToWithdraw (#878)
gpsanant Nov 6, 2024
deff1ba
feat: add tasks to prepare chain state ready for slashing (#868)
grezle Nov 7, 2024
bf0e200
test: slashing todos (#880)
0xClandestine Nov 8, 2024
d59be03
feat: add getMinimumSlashableStake (#889)
wadealexc Nov 13, 2024
d14790a
refactor: pull beacon chain slashing out of slashing lib (#876)
wadealexc Nov 14, 2024
725d3df
test: slashing test todos (#885)
0xClandestine Nov 14, 2024
eed61f2
feat: burn erc20s on slashing (#881)
8sunyuan Nov 20, 2024
4aa717f
test: DelegationManager unit tests (#886)
8sunyuan Nov 20, 2024
3bc4bc1
test: fix env requirement (#899)
8sunyuan Nov 20, 2024
b6372a0
fix: compile warnings (#900)
0xClandestine Nov 21, 2024
179e413
fix: slashing local deploy (#898)
ypatil12 Nov 22, 2024
fbf7c19
test: slashing integration framework (#894)
0xClandestine Nov 22, 2024
28fc33e
refactor: EigenPods and beacon chain slashing (#892)
wadealexc Nov 22, 2024
601f8e2
refactor: remove deprecated methods (#903)
wadealexc Nov 25, 2024
cdbd942
test: `withdrawSharesAsTokens` regression (#904)
ypatil12 Nov 25, 2024
d1c9402
chore: remove unnecessary delegate checks (#908)
ypatil12 Nov 26, 2024
eb9a614
feat: user access management (#870)
ypatil12 Nov 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ jobs:
version: nightly
- name: Run coverage
run: forge coverage --report lcov
env:
RPC_MAINNET: ${{ secrets.RPC_MAINNET }}
RPC_HOLESKY: ${{ secrets.RPC_HOLESKY }}
- name: Prune coverage report
run: lcov --remove ./lcov.info -o ./lcov.info.pruned 'src/test/*' 'script/*' '*Storage.sol' --ignore-errors inconsistent
- name: Generate reports
Expand Down
15 changes: 8 additions & 7 deletions .github/workflows/testinparallel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ jobs:
RPC_HOLESKY: ${{ secrets.RPC_HOLESKY }}
CHAIN_ID: ${{ secrets.CHAIN_ID }}

- name: Run integration mainnet fork tests
run: forge test --match-contract Integration
env:
FOUNDRY_PROFILE: "forktest"
RPC_MAINNET: ${{ secrets.RPC_MAINNET }}
RPC_HOLESKY: ${{ secrets.RPC_HOLESKY }}
CHAIN_ID: ${{ secrets.CHAIN_ID }}
# TODO: uncomment this item once we've added the proper upgrade tests
# - name: Run integration mainnet fork tests
# run: forge test --match-contract Integration
# env:
# FOUNDRY_PROFILE: "forktest"
# RPC_MAINNET: ${{ secrets.RPC_MAINNET }}
# RPC_HOLESKY: ${{ secrets.RPC_HOLESKY }}
# CHAIN_ID: ${{ secrets.CHAIN_ID }}
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
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
145 changes: 145 additions & 0 deletions docs/release/slashing/AVSDirectory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# AVSDirectory

## Overview

The AVSDirectory contract is where registration relationships are defined between AVSs, operatorSets, and operators. Registration and deregistration are used in the protocol to activate and deactivate slashable stake allocations. They're also used to make the protocol more legible to external integrations.

The slashing release introduces the concept of operatorSets, which are simply an (address, uint32) pair that the define an AVS and an operator set ID. OperatorSets are used to group operators by different tasks and sets of tokens. For example, EigenDA has an ETH/LST operatorSet and an Eigen operatorSet. A bridge may have on operatorSet for all operators that serve a particular chain. Overall, operatorSets are mainly used for protocol legibility.

Functionality is provided for AVSs to migrate from an pre-operatorSet registration model to an operatorSet model. Direct to AVS registration is still supported for AVSs that have not migrated to the operatorSet model, but is slated to be deprecated soon in the future.

## `becomeOperatorSetAVS`
```solidity
/**
* @notice Sets the AVS as an operator set AVS, preventing legacy M2 operator registrations.
*
* @dev msg.sender must be the AVS.
*/
function becomeOperatorSetAVS() external;
```

AVSs call this to become an operator set AVS. Once an AVS becomes an operator set AVS, they can no longer register operators via the legacy M2 registration path. This is a seperate function to help avoid accidental migrations to the operator set AVS model.

## `createOperatorSets`
```solidity
/**
* @notice Called by an AVS to create a list of new operatorSets.
*
* @param operatorSetIds The IDs of the operator set to initialize.
*
* @dev msg.sender must be the AVS.
*/
function createOperatorSets(
uint32[] calldata operatorSetIds
) external;
```

AVSs use this function to create a list of new operator sets.They must call this function before they add any operators to the operator sets. The operator set IDs must be not already exist.

This can be called before the AVS becomes an operator set AVS. (TODO: we should make this so that it can only be called after the AVS becomes an operator set AVS?)

## `migrateOperatorsToOperatorSets`
```solidity
/**
* @notice Called by an AVS to migrate operators that have a legacy M2 registration to operator sets.
*
* @param operators The list of operators to migrate
* @param operatorSetIds The list of operatorSets to migrate the operators to
*
* @dev The msg.sender used is the AVS
* @dev The operator can only be migrated at most once per AVS
* @dev The AVS can no longer register operators via the legacy M2 registration path once it begins migration
* @dev The operator is deregistered from the M2 legacy AVS once migrated
*/
function migrateOperatorsToOperatorSets(
address[] calldata operators,
uint32[][] calldata operatorSetIds
) external;
```

AVSs that launched before the slashing release can use this function to migrate operators that have a legacy M2 registration to operator sets. Each operator can only be migrated once for the AVS and the AVS can no longer register operators via the legacy M2 registration path once it begins migration.

## `registerOperatorToOperatorSets`
```solidity
/**
* @notice Called by AVSs to add an operator to list of operatorSets.
*
* @param operator The address of the operator to be added to the operator set.
* @param operatorSetIds The IDs of the operator sets.
* @param operatorSignature The signature of the operator on their intent to register.
*
* @dev msg.sender is used as the AVS.
*/
function registerOperatorToOperatorSets(
address operator,
uint32[] calldata operatorSetIds,
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature
) external;
```

AVSs use this function to add an operator to a list of operator sets. The operator's signature is required to confirm their intent to register. If the operator has a slashable stake allocation to the AVS, it takes effect when the operator is registered (and up to `DEALLOCATION_DELAY` seconds after the operator is deregistered).

The operator set must exist before the operator can be added to it and the AVS must be an operator set AVS.

## `deregisterOperatorFromOperatorSets`
```solidity
/**
* @notice Called by AVSs to remove an operator from an operator set.
*
* @param operator The address of the operator to be removed from the operator set.
* @param operatorSetIds The IDs of the operator sets.
*
* @dev msg.sender is used as the AVS.
*/
function deregisterOperatorFromOperatorSets(address operator, uint32[] calldata operatorSetIds) external;
```

AVSs use this function to remove an operator from an operator set. The operator is still slashable for its slashable stake allocation to the AVS until `DEALLOCATION_DELAY` seconds after the operator is deregistered.

The operator must be registered to the operator set before they can be deregistered from it.


## `forceDeregisterFromOperatorSets`
```solidity
/**
* @notice Called by an operator to deregister from an operator set
*
* @param operator The operator to deregister from the operatorSets.
* @param avs The address of the AVS to deregister the operator from.
* @param operatorSetIds The IDs of the operator sets.
* @param operatorSignature the signature of the operator on their intent to deregister or empty if the operator itself is calling
*
* @dev if the operatorSignature is empty, the caller must be the operator
* @dev this will likely only be called in case the AVS contracts are in a state that prevents operators from deregistering
*/
function forceDeregisterFromOperatorSets(
address operator,
address avs,
uint32[] calldata operatorSetIds,
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature
) external;
```

Operators can use this function to deregister from an operator set without requiring the AVS to sign off on the deregistration. This function is intended to be used in cases where the AVS contracts are in a state that prevents operators from deregistering (either malicious or unintentional).

Operators can also deallocate their slashable stake allocation seperately to avoid slashing risk, so this function is mainly for external integrations to interpret the correct state of the protocol.

## `updateAVSMetadataURI`
```solidity
/**
* @notice Called by an AVS to emit an `AVSMetadataURIUpdated` event indicating the information has updated.
*
* @param metadataURI The URI for metadata associated with an AVS.
*
* @dev Note that the `metadataURI` is *never stored* and is only emitted in the `AVSMetadataURIUpdated` event.
*/
function updateAVSMetadataURI(
string calldata metadataURI
) external;
```

This function allows an AVS to update the metadata URI associated with the AVS. The metadata URI is never stored on-chain and is only emitted in the `AVSMetadataURIUpdated` event.

## View Functions

See the [AVS Directory Inteface](../../../src/contracts/interfaces/IAVSDirectory.sol) for view functions.
Loading
Loading