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

Residual vesting account bookkeeping after slashing could result in premature unlocking of subsequent grants #4300

Closed
JimLarson opened this issue Jan 14, 2022 · 1 comment
Assignees
Labels
agoric-cosmos bug Something isn't working
Milestone

Comments

@JimLarson
Copy link
Contributor

Filing this as an agoric-sdk issue since this is not a cosmos/cosmos-sdk feature.

Describe the bug

To avoid needing to debit a huge number of staker accounts after a slash, cosmos-sdk uses a lazy method to defer the deduction until a staker decides to unstake from a slashed validator.

There is no interface for declaring that one is using vested or unvested funds for staking. To maximize the freedom to transfer unstaked funds, vesting accounts assign unvested funds to staking before vested funds. When slashing occurs, unvested funds are lost before vested funds.

To avoid needing to traverse staking data structures and compute slashing effects and get an accurate balance of the number of staked and unstaking tokens when trying to transfer funds out of a vesting account, vesting accounts have their own bookkeeping of the fund that flow in and out of staking, and use this bookkeeping to determine whether funds can be transferred out.

This bookkeeping has some inaccuracies after slashing, but it doesn't matter as long as the unvested amount in the account goes monotonically down to zero.

However, with the feature of #3956 to allow new grants to an existing periodic vesting account, that assumption is no longer true. The residual bookkeeping can lean to premature unlocking of funds.

Bookkeeping details

V = unvested amount (time-dependent)
DF = delegated free (vested), stored with account
DV = delegated unvested, stored with account

Unstaked coins which are locked = max(0, V - DV)

Delegating D > 0
    X := min(max(V - DV, 0), D)
    DV += X
    DF += D - X

Undelegating D > 0:
    X := min(DF, D)
    Y := min(DV, D - X)
    DF -= X
    DV -= Y

Note that DF + DV is less than the total staked amount after slashing - the bookkeeping only handles the normal user-requested staking and unstaking operations.

To Reproduce

  1. Deposit 5000 in a periodic vesting account.
  2. Stake it all (DV = 5000)
  3. Get slashed for 1000.
  4. Unstake the remaining 4000 (DV = 1000).
  5. Wait for it all to vest and transfer the 4000 out of the account.
  6. Get a new grant for 1000, unlocking in 100 years.
  7. Immediately transfer it out of the account.
  8. Repeat for an arbitrary number of similar grants in the future.

Expected behavior

Locked funds should not be transferrable.

Possible Solutions

The best solution is to track the total delegated + undelegating tokens more accurately. Knowing the account balance BC and the delegated + undelegating amount DT, the number of locked tokens in that balance is max(0, V - DT).

To minimize how often we need to traverse the staking data structures, we can cache the result of computing DT, incrementally change it when manually staking and unstaking, and notice new staking events by timestamp.

@JimLarson JimLarson added the bug Something isn't working label Jan 14, 2022
@JimLarson JimLarson self-assigned this Jan 14, 2022
JimLarson added a commit to agoric-labs/cosmos-sdk that referenced this issue Jan 14, 2022
michaelfig pushed a commit to agoric-labs/cosmos-sdk that referenced this issue Jan 15, 2022
@Tartuffo Tartuffo added the MN-1 label Jan 21, 2022
JimLarson added a commit to agoric-labs/cosmos-sdk that referenced this issue Jan 30, 2022
@Tartuffo Tartuffo removed the MN-1 label Feb 7, 2022
JimLarson added a commit to agoric-labs/cosmos-sdk that referenced this issue Feb 15, 2022
JimLarson added a commit to agoric-labs/cosmos-sdk that referenced this issue Feb 15, 2022
@Tartuffo
Copy link
Contributor

@JimLarson Will create a new ticket for the remaining work of correct handling of clawback + slashing.

@Tartuffo Tartuffo added this to the Mainnet 1 milestone Mar 23, 2022
JeancarloBarrios pushed a commit to agoric-labs/cosmos-sdk that referenced this issue Sep 28, 2024
JeancarloBarrios pushed a commit to agoric-labs/cosmos-sdk that referenced this issue Sep 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
agoric-cosmos bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants