Recovery Mechanism for Lost Delegation Funds due to User Mistakes

Summary

A recovery mechanism for delegation funds that get lost in the consensus layer due to a user’s mistake interacting with the IPTokenStaking contract. Two methods are suggested: execute fallback staking operations or refund the fund via the staking withdrawal queue.

Motivation

When a user attempts to create a validator that already exists, the transaction will succeed on the execution layer as the IPTokenStaking smart contract does not validate pre-existence. Similarly, the contract will burn the received stake and emit the Deposit event when a user delegates to a non-existent validator. (Refer to these two mistaken operations as “mishandled delegation operations.”)

However, in both cases, the consensus layer will skip over the parsed events and log an error. This leads to the mishandled delegation (self-delegation in the first case) being lost. If a user attempts to withdraw their delegation after a mishandled delegation operation, the consensus layer will catch an error and skip the parsed Withdraw event.

This proposal offers two methods for refunding the lost stake in the case of a mishandled delegation operation. Both methods modify the consensus layer only and require a hardfork.

Proposal

Method 1: Execute fallback staking operations

For the duplicate creation of a validator, CL converts the creation request to a self-delegation. Hence, the delegator, who is also the validator in the normal creation process, accrues more self-delegation.

When delegating to a non-existent validator, CL creates the validator with minimal information before continuing the delegation process. Since creating a validator requires a minimum self-delegation of 1024 IP, the delegator will lose 1024 IP while the validator will gain 1024 IP, which its owner (if found) can withdraw later. Then, the delegator can withdraw the remaining stake amount regardless of the validator’s status.

This method preserves the intended requests of the users, so users can expect their stakes to have been delegated successfully on the consensus layer. The downside is the user losing 1024 IP to a validator’s self-delegation when staking to a non-existent validator.

Method 2: Refund via the staking withdrawal queue

For both mishandled delegation operations, redirect the received stake fund to the withdrawal queue. To prevent spamming of the withdrawal queue, CL must parameterize the return percentage to be less than 100% (refer to it as the “refund fee”), so the spammer will lose all funds after a finite number of attempts.

This method ensures that users receive their funds back to EL for their mishandled delegation operations, minus the refund fee. The downside is that the staking withdrawal queue will get busier and lead to some wait time (the withdrawal queue only processes a fixed number of requests per block). This method necessitates careful parameterization of the refund fee, on top of the existing gas fee on the execution layer, to ensure that the withdrawal queue will not get spammed.

Drawback

There is no drawback as these methods strictly attempt to recover funds previously lost in mishandled delegation operations.

User Impact

There is no direct user impact. Delegators and validators will benefit from this change.

7 Likes

Not clear to me for the method 1. If the user delegate to a non-exist validator, how the CL create the validator? Will it be a default validator?

method 2 seems clear to me. Need to define a refund fee if users made a mistake. The downside is how much refund fee would be a reasonable amount to prevent attack. Another improvement is to wait for 14 days to withdraw so to prevent attack and no need a refund fee.

3 Likes

CL will create a validator with some basic data inferred. More specifically:

k.CreateaValidator(
    cachedCtx,
    validatorAddr.String(),
    validatorPubkey,
    sdk.NewCoin(sdk.DefaultBondDenom, minDelegation), // min. delegation
    validatorAddr.String(),  // moniker
    // commssion rate: 5%, max: 20%, max change: 5%
    int64(500),
    int64(2000),
    int64(500),
    minDelegation, // min. self-delegation
    int32(1), // supports unlocked: true
);

As you can see, some values are inferred and commission rates are hard-coded as default values (which can be updated by the validator later).

I agree method 2 is more straightforward and the refund fee + wait period would make it spam-proof. Method 1 maintains the expected flow of the user’s staking.

We can even do a hybrid recovery mechanism where:

  1. Duplicate creation of validator → convert to self-delegation (since delegator == validator)
  2. Deposit to non-existent validator → refund via withdrawal queue
3 Likes

I like the idea of 14 days withdrawal delay even though we may not need the 14 days. The downside is that it makes the system more complex (We likely need to introduce another queue here)

5 Likes

LFG IP is rocking. Looking forward to what comes next :rocket:

1 Like

I think a workable solution is:

  • Duplicate creation of validator → convert to flexible self-delegation (since delegator == validator), which is supported for both locked & unlocked validators.
  • Deposit to non-existent validator → take 1% refund fee (parameter) and add to unbonding queue in the staking module with 1 day of unbonding time. Gets processed by the existing withdrawal queue once unbonded.

For the second case, I imposed both the unbonding time and refund fee. I think having zero refund fee opens up for zero-cost spam attack on the unbonding queue since technically it costs zero (only EL gas) to add to the UBD. Alternatively, we could extend the unbonding time for refunds to 14 days and remove the refund fee.

1 Like