-
Notifications
You must be signed in to change notification settings - Fork 329
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
base: custom-errors
Are you sure you want to change the base?
Conversation
f2a7515
to
f0873d1
Compare
9f91f03
to
b9fe3e5
Compare
This comment was marked as spam.
This comment was marked as spam.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review on alloc/dealloc
Would it be bad / hard / undesirable to enforce this ordering on the checkpoints history level? I would suggest that if an attempt is made to push an entry with a timestamp that is earlier than the timestamp of the previous entry, either (a) it's simply not allowed or (b) the new entry has its timestamp modified to match (or be 1 higher? not sure if the ascending ordering you have is strict or non-strict). Perhaps some option (c) could work where you keep the original timestamp but overwrite the intentions of the other entry? IDK if that would be incompatible with other aspects of the storage model though. I was initially thinking option (b) was the most logical but modifying entries before pushing them can be messy, especially if the entry or its contents is used elsewhere (e.g. if the timestamp is emitted in events, its hard to make sure the event emits the correct timestamp when you have conditional logic for modifying it). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor slashing comments
src/contracts/core/AVSDirectory.sol
Outdated
{ | ||
uint256 queuedDeallocationIndicesLen = | ||
_queuedDeallocationIndices[operator][strategies[i]][msg.sender][operatorSetId].length; | ||
for (uint256 j = queuedDeallocationIndicesLen; j > 0; --j) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since MAX_PENDING_UPDATES
is 1, we don't need a loop here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gpsanant mentioned we want to check without assuming max 1 and be able to update in the future to change MAX_PENDING_UPDATES
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gpsanant Should I remove the loop?
678f212
to
e70e85d
Compare
* encoding of the operatorSet. This is to prevent duplicate operatorSets being passed in. The easiest way to ensure | ||
* ordering is to sort allocated operatorSets by address first, and then sort for each avs by ascending operatorSetIds. | ||
*/ | ||
function modifyAllocations( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we include a signature based variant, so anyone can modify allocations on behalf of an operator?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed because it was bloating code and we are adding delegated accounts
wdyt @ypatil12 @wadealexc ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leave to delegated accounts IMO
|
||
// If we've reached a pending modification that isn't completable yet, | ||
// we can stop. Any subsequent modificaitons will also be uncompletable. | ||
if (block.timestamp < info.effectTimestamp) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check diff != 0
function registerAsOperator( | ||
OperatorDetails calldata registeringOperatorDetails, | ||
uint32 allocationDelay, | ||
string calldata metadataURI | ||
) external { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are comfortable changing this interface, let's make it a little more sane and use a new version of the OperatorDetails
struct that includes an allocationDelay
and does not have deprecated fields
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OperatorDetails
is only storing delegationApprover
at this point, I'd say just remove this OperatorDetails struct from the interface and only use it to store for backwards compatability.
Perhaps something like the following
function registerAsOperator(
address delegationApprover,
uint32 allocationDelay,
string calldata metadataURI
) external {
/** | ||
* @notice Original EIP-712 Domain separator for this contract. | ||
* @dev The domain separator may change in the event of a fork that modifies the ChainID. | ||
* Use the getter function `domainSeparator` to get the current domain separator for this contract. | ||
*/ | ||
bytes32 internal _DOMAIN_SEPARATOR; | ||
bytes32 internal __deprecated_DOMAIN_SEPARATOR; |
Check warning
Code scanning / Slither
State variables that could be declared constant
modifier onlyEigenPodManager() { | ||
require(msg.sender == address(eigenPodManager), OnlyEigenPodManager()); | ||
_; | ||
} |
Check notice
Code scanning / Slither
Incorrect modifier
|
||
// Mutatables | ||
|
||
bytes32 internal __deprecated_DOMAIN_SEPARATOR; |
Check warning
Code scanning / Slither
State variables that could be declared constant
* Use the getter function `domainSeparator` to get the current domain separator for this contract. | ||
*/ | ||
bytes32 internal _DOMAIN_SEPARATOR; | ||
bytes32 internal __deprecated_DOMAIN_SEPARATOR; |
Check warning
Code scanning / Slither
State variables that could be declared constant
|
||
// Mutatables | ||
|
||
bytes32 internal __deprecated_DOMAIN_SEPARATOR; |
Check warning
Code scanning / Slither
State variables that could be declared constant
StakerScalingFactors memory ssf | ||
) internal pure returns (uint64) { | ||
return | ||
!ssf.isBeaconChainScalingFactorSet && ssf.beaconChainScalingFactor == 0 ? WAD : ssf.beaconChainScalingFactor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be simplified to:
return ssf.isBeaconChainScalingFactorSet ? ssf.beaconChainScalingFactor : WAD;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Followup: the code seems to imply that it's possible for beaconChainScalingFactor
to equal 0. However, this would cause mulDiv
to revert if it's used as the denominator!
If this can be zero, we need to fix that.
If this can't be zero, this code is incorrect.
// 2. If there is a pending deallocation, reduce pending deallocation proportionally. | ||
// This ensures that when the deallocation is completed, less magnitude is freed. | ||
if (info.pendingDiff < 0) { | ||
uint64 slashedPending = uint64(uint256(uint128(-info.pendingDiff)).mulWad(params.wadToSlash)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
slashedPending
is not used anywhere else so can we remove this uint64 cast?
Added this rewards methods to ElContracts ChainWriter: - `set_claimer_for` - `process_claim` Still missing this methods (they are still not merged on dev branch of eigenlayer-contracts - will be merged with the [slashing PR](Layr-Labs/eigenlayer-contracts#679)): - `ForceDeregisterFromOperatorSets` - `SetOperatorCommissionBips`
db2ccda
to
153d625
Compare
eabea03
to
25617f0
Compare
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 fix: compile chore: format
e94d7d9
to
d98c5a7
Compare
* feat: add shares to queue event * fix: submodule * chore: rename
* feat: named mapping params * refactor: natspec * refactor: natspec * chore: forge fmt * refactor: nits
|
* feat: add getCurrent * chore: fmt * chore: storoage report * chore: new storage
|
|
* chore: cleanup * chore: comments and add legacy view * chore: complete => clear * chore: reorder require check * fix: round up for slashed magnitudes * chore: nits and legacy complete withdrawals * feat: allow alloc delay 0 and fix tests * chore: clarify comment * chore: fmt * fix: fork test * chore: nits * test: roundup slashed magnitudes
|
Updated 9/20/24
Contract Descriptions
DONT REVIEW THE REWARDS COORDINATOR
AVSDirectory
New Core contract: AllocationManager! (basically the Slasher contract)
modifyAllocations
can be called to configure updated allocations for a strategy per opSet. Allocations/deallocations are handled differently in the underlying storage.slashOperator
, from the perspective of an (operator, Strategy) tuple, slashes from current magnitude as well as queued deallocations. Whatever magnitude is slashed is also decremented from the totalMagnitude from the (operator, Strategy) tuple.freeMagnitude
in storage.StrategyManager/EigenPodManager/DelegationManager - Changes to Deposits/Withdrawals
This code comment explains a bunch:
Withdrawal
struct in the DelegationManager has been changed fromstartBlock
tostartTimestamp
. To account for legacy M2 withdrawals, we check that this field is less than a specific timestamp and handle accordingly.IShareManager
interfacedepositScalingFactor
is the k value used in the accounting docsstakerStrategyShares
is soperatorDelegatedShares
is optotalMagnitude
is m read from the AllocationManagerMisc Notes:
thirdPartyTransfersForbidden
is removed entirely. This mapping will be deprecated and never read from again.TODOs:
Deposits/Withdraws of Shares [WIP]
Allocator Configuration [WIP]