Karak

Karak DSS connected registered operators to slashable vault collateral in the 2024 protocol

Karak DSS let operators register for service tasks and back those commitments with restaked vault assets in the 2024 protocol. A Distributed Secure Service (DSS) set its tasks and rewards, while Core recorded membership and allocation. Joining a service and staking a vault were separate operations, so an operator's registration alone didn't establish collateral backing.

The relevant contracts identified this design as version 2.0.0. V1 staking, V2 staking and K2 bridge access now carry a legacy label. These historical rules don't confirm current operator admission or the availability of new vault allocations.

In short: In the 2024 protocol, operator registration established service membership, while a separate delayed update committed a vault's collateral.

Stakers, operators and DSS contracts

Stakers supplied assets, operators performed service tasks and DSS contracts defined the obligations that those operators accepted. Deposits entered an operator's vault, which represented the depositor's claim through shares. Each accepted asset had a dedicated vault in the documented design. Once an operator committed a vault to a DSS, that vault's collateral could back the service's economic security under its slashing rules, while depositors continued to hold their claims through the vault's share accounting and shared the consequences of an asset penalty.

Core coordinated those memberships and vault commitments. A DSS handled its own task requirements and rewards. Vault implementations supplied asset accounting, with standard token vaults using ERC-4626-style shares and NativeVault following its native-restaking path. A slashing handler determined how the protocol processed penalized assets.

Service registration fixed the slashing ceiling

A DSS registered its contract with Core before operators could join it through the protocol. Core required the service-registration caller to be a smart contract. The service declared its maximum slashable percentage during registration. The 2024 design stored that value once, so an existing registration couldn't overwrite it by registering again. This ceiling constrained the percentages that Core accepted in that service's slashing requests.

The percentage used fixed-point WAD encoding, a scaled integer representation of the slashing percentage. Core exposed the stored bound through getDssMaxSlashablePercentageWad . The service's permitted maximum and its requested penalty remained different values: a request had to stay within the declared maximum. Repeated requests also faced a cooldown for the same DSS and operator.

Did registering an operator also stake a vault?

Operator registration established service membership; it didn't add a vault to that service's staked set.

Core's registerOperatorToDSS accepted the target DSS and service-specific registration data. The caller's address supplied the operator identity. The DSS had to be registered already, the registration function had to be unpaused and any registration hook that Core invoked had to succeed. These conditions governed admission before a separate vault allocation could follow.

Successful registration emitted RegisteredOperatorToDSS . The membership query isOperatorRegisteredToDSS exposed the recorded relationship. Neither the event nor that Boolean response specified an allocated asset amount. The event recorded successful registration; a true query result confirmed that Core recorded the membership when queried.

Before requesting any vault allocation, a newly registered operator had no new stake to unwind in Core. If it had no existing vaults staked to that DSS, it could end that membership. This stopping point concerned Core's collateral records; the service's own rules governed any separate service duties.

A depositor's share balance wasn't evidence that every service associated with the operator already had a vault commitment.

Registration hooks controlled service admission

Registration hooks let a DSS apply its admission logic within the protocol's operator-registration call. Core passed the operator address and registration data to registrationHook when Core's interface check succeeded and the service reported support for that hook. A failing registration hook reverted the whole call, including the membership change. Hooks were optional, so a service without that implemented interface followed the remaining Core checks. The service contract determined any required registration data.

Vault allocation used a delayed update

Vault staking changed the collateral commitment through a queued update after the operator had joined the DSS. The request identified the vault, the service and whether the operator intended to stake or unstake. Only the operator could initiate its vault's update. Core checked membership, and the operator's vault records had to contain the selected vault.

Requesting an update created pending metadata, including its starting timestamp and intended direction. Finalization applied that direction only after the required delay and a match against the stored request. A queued request therefore didn't establish that allocation had finished. The same delayed mechanism covered adding a vault to a DSS and removing it from one.

Visual summary: Vault allocation used a delayed update (Karak DSS)

Open full-size image

A supported request-stage staking hook could reject allocation. An unstaking request used different failure handling for that hook, allowing the exit request to survive a service callback failure. That rule concerned the hook's execution; the request still had to satisfy Core's other checks. Service admission and vault admission could therefore apply different conditions to the same operator.

Timing parameters in the 2024 V2 design

The 2024 V2 timing constants separated vault updates from slashing review and repeated penalty requests. The 2024 V2 implementation set MIN_STAKE_UPDATE_DELAY to 9 days. These values belonged to that contract design and weren't a current availability promise.

Protocol parameter 2024 value and application
MIN_STAKE_UPDATE_DELAY 9 days; delay before finalizing either staking or unstaking.
SLASHING_WINDOW 7 days; component of stake-update and withdrawal delays.
SLASHING_VETO_WINDOW 2 days; minimum wait before finalizing a queued slashing request.
SLASHING_COOLDOWN 2 days; cooldown per DSS-operator pair between slashing requests.

The veto window and the cooldown had equal lengths, but they governed different actions.

Rewards followed service participation

DSS task rewards belonged to the service's own payment system in the 2024 design. Core and the vaults didn't distribute those rewards. A DSS could calculate rewards off-chain and pay them through a Merkle drop. The reward policy called for calculations to stop counting a vault's stake when its operator initiated unallocation, even though the delayed update hadn't finished. The same exclusion applied to assets that a staker queued for withdrawal; Core didn't perform that rewards accounting.

Slashing requests and veto rights

Slashing connected a DSS's penalty request to vault collateral that the operator had committed to that service. Core required the operator-service registration and the targeted vault allocation. The requested percentage had to remain within the service's registered ceiling. Core enforced these structural conditions; it didn't determine whether an operator had performed its off-chain tasks correctly. The DSS's own rules supplied that task-level judgment.

An accepted slashing request identified the operator and targeted vaults, then earmarked an amount for each vault from its requested percentage and its totalAssets at that point, while the veto delay kept penalty execution pending. A vault could cap execution at its remaining assets, so the request wasn't proof of a completed transfer.

The veto committee could cancel a queued request while it remained pending. Cancellation removed that request from Core's executable queue. When slashing proceeded, the standard token vault called its handler to process the penalty. NativeVault first reduced its accounted assets; a later snapshot could move available slashed ETH to its slash store. Handler designs could burn assets, swap them before burning or distribute them to affected parties. The vault and handler implementations determined the asset's treatment.

Shared vault backing and service-specific jailing

Multiple DSSs could rely on the same vault backing in the 2024 design. An operator could commit a vault's full collateral to more than one service, creating overlapping obligations over shared assets. Those commitments didn't create additional collateral balances. A DSS could reject or jail an operator whose combined commitments exceeded that service's tolerance.

Jailing was a service-level participation sanction that could affect tasks or rewards. Core didn't impose a universal jailing policy. A DSS could implement restrictions such as withholding rewards or requiring unallocation. The service's chosen rules determined the consequence, and jailing remained optional. Removing task access therefore didn't itself describe how the protocol would slash or release vault assets.

Service exit differed from a staker withdrawal

Leaving a DSS required the operator to end every vault allocation to that service before removing its membership. An unstaking request entered the delay process. Unregistration remained blocked while Core still listed a vault as staked to that DSS. The AllVaultsNotUnstakedFromDSS error referred to that outstanding allocation, even if another interface displayed a withdrawal request.

Operator unallocation changed a service commitment. A staker withdrawal changed a depositor's claim on vault assets. Their timing served related slashing protections, yet completing one didn't perform the other. Once an allocation had finalized, ending membership required the separate unallocation process. Removing the operator's membership didn't withdraw depositor assets.

Quick answers about Karak DSS

Why does operator registration return DSSNotRegistered?

DSSNotRegistered meant that Core didn't recognize the target service contract as a registered DSS in the 2024 design. The registry used the service's stored maximum slashable percentage, with zero identifying an unset record. An operator's membership request couldn't create that service registration on its behalf. This error concerned the target DSS record, so owning a vault didn't resolve it.

What happens if an operator registers twice with the same DSS?

The 2024 implementation rejected duplicate membership with OperatorAlreadyRegisteredToDSS. Core checked whether the operator already belonged to that particular service before adding the relationship. Resubmitting different registration data didn't update an existing membership or add another allocation. Registration with another DSS was a separate relationship, subject to its admission rules and the 2024 limit of 32 DSS memberships per operator.

Can another account finalize an operator's queued vault update?

Another account could finalize a valid queued vault update in the 2024 implementation. The operator had to initiate the request, which identified the operator, vault, service and intended staking direction. Finalization checked the stored request hash and elapsed delay. It didn't let the finalizer substitute another vault or DSS. The function's pause state and other transaction checks still applied.

Will a pending update for one DSS block a new request for another DSS?

A pending stake update occupied the same vault's update slot across DSSs in the 2024 implementation. The pendingStakeUpdates mapping keyed requests by vault address, so changing the service didn't create another slot. A new request for that vault reverted with PendingStakeUpdateRequest until the pending record cleared. Different vaults had separate slots, although their requests still needed the operator's membership and their own validation.

Does a failed unregistration hook keep an operator registered?

A failed DSS unregistration hook didn't reverse Core's membership removal in the 2024 design. That callback ran with its execution failure ignored. The operator still needed to have no vaults staked to the DSS. This rule didn't bypass other contract checks or guarantee that a transaction with insufficient gas would finish. Successful removal from Core and a failed service callback could therefore coexist.

Updated on