Skip to content

Commit

Permalink
feat: squashed slashing for devnet
Browse files Browse the repository at this point in the history
chore: forge fmt src/contracts

fix: ci and bindings

chore: dmgr error tweaks

chore: error tweaks for consistency and clarity

feat: bump oz version (#755)

* feat: bump oz version -> 0.4.9

- also moved remappings -> foundry.toml
- removes remappings.txt

* bindings

---------

Co-authored-by: gpsanant <gpsanant@gmail.com>

test: custom errors passing (#783)

* test: custom errors AVSDir

* test: custom errors IPausable

* test: custom errors Delegation

* test: custom errors EigenPodManager

* test: custom errors EigenPod

* test: custom errors Pausable

* test: custom errors RewardsCoordinator

* test: custom errors IStrategy

* test: custom errors StrategyManager

* test: custom errors DelegationManager

* test: custom errors

refactor: review reconciliation

refactor: review reconciliation

refactor: review reconciliation

chore: forge fmt src/contracts

feat: slashing

* 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 <pragma-services@proton.me>

feat: dm cleanup (#788)

Co-authored-by: wadealexc <pragma-services@proton.me>

Revert "feat: dm cleanup (#788)" (#799)

This reverts commit c27004e.

fix: compiles (#800)

fix: refactor (#801)

* fix: refactor

* default was history

* reline

* rename

rename

test: generally compiling + AVSM unit tests compiling

chore: forge fmt src/contracts

add events, fix bugs, abstract better (#806)

* fix bugs, add events, cleanup

* wrap conditional

* fmt

* only one slash per timestamp

test(wip): generally compiling

update docs (#804)

fix: revert change to event

feat: am refactor

add to wads to slash

cleanup

refactor: change totalMagnitude to maxMagnitude
* condense slashOperator params
* some struct field renaming

remove unused eigenpod storage

chore: storage report (#809)

* chore: storage report

* patch eigenpod

---------

Co-authored-by: gpsanant <gpsanant@gmail.com>

feat: eip712 fixes (#808)

* feat: use OZ SignatureChecker

* feat: add `SignatureUtils` mixin

* refactor: cleanup

* feat: make storage report

* storage report

---------

Co-authored-by: gpsanant <gpsanant@gmail.com>

test: slashing tests passing (#812)

fix: merge issues

update events

refactor: rename total magnitudes to max magnitudes
* various formatting and cleanup
* standardize allocation manager getter functions
* update and improve commenting

refactor: reorder functions to match interface

fix: remove memory overwrite bug in delegation manager

chore: forge fmt

refactor: clean up getDepositedShare logic

chore: remove old oz + forge update foundry-rs/forge-std

feat: replace getSlashableMagnitudes with general purpose allocation info query

Feat: SM/StrategyBase Unit Tests + Formatting (#813)

refactor: delegation manager refactors

test: AllocationManager progress

feat: change event names

feat: update doc

fix: compile

test: AllocationManager progress

fix: tests progress

add Strategy <> OperatorSet mapping in storage, and APIs and events (#814)

* feat: add strategy to operator set mapping with corresponding functions and events

* fix: update

* fix: remove pagination of getStrategiesInOperatorSet

* fix: update

* fix: compiles

* fix: add checks

* fix: address -> IStrategy

* fix: storage gap

---------

Co-authored-by: gpsanant <gpsanant@gmail.com>

Slashing: DM Happy Path Test Cases (#815)

* test: basic dm tests

* test: start on share increase/decrease delegated shares tests

* test: add DM unit tests passing except queue/complete

* test: undelegate tests

* test: queue withdrawals

* test: completed DM happy path test cases

* fix: compilation, rebase errors

* chore: format

Add view funcs (#816)

* fix: add new view funcs

* fix: update docs

test: fix avsD tests (#817)

chore: format

fix: from scratch deploy

feat: add shares to slashing event

Slashing: Modify Allocations Happy Path Tests (#821)

* refactor: add test contract per func

* test: modify allocations

* chore: format

slashing: allocation delay happy path tests (#822)

feat: wadSlashed (#820)

Slashing: Clear Modification Queue Happy Path Tests (#823)

test: basic allocation tests (#824)

feat: inheritdoc

refactor: alm test cleanup

test: multiple allocations, only one slashed

test: one pending alloc, slash

test: revert bound refactor so tests pass

Slashing: Add additional happy path AM test cases (#828)

* test: happy path AM tests

* chore: format

Slashing: Get all tests passing (#829)

* test: all tests passing

* fix: mainnet integration test comment out

Fix misset storage gaps (#831)

* fix: misset storage gaps from #814

* fix: update gap to account for previous refactor

fix: update coverage yml name (#833)

Fix: Single Deallocation Queue (#827)

* test: base regression

* test: regression

* fix: remove console

* test: logs

* test: add actual regression

* fix: use a single deallocation queue

* fix: comments

* refactor: use deallocation queue everywhere

* fix: address test comments

* fix: test comment

Feat: Update legacy withdrawal timestamp param to legacy withdrawal check (#836)

* fix: make comment on timestamp clearer

* chore: format

Feat: Public Devnet Deploy (#838)

* feat: slashing public devnet

* fix: filepath

* test: validation

* fix: add test

* fix: test
  • Loading branch information
8sunyuan authored and ypatil12 committed Oct 17, 2024
1 parent 861b7c8 commit 25617f0
Show file tree
Hide file tree
Showing 141 changed files with 15,444 additions and 6,465 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
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

0 comments on commit 25617f0

Please sign in to comment.