Skip to content

Convictions (stake locks)#2599

Merged
sam0x17 merged 47 commits intodevnet-readyfrom
feat/conviction
May 1, 2026
Merged

Convictions (stake locks)#2599
sam0x17 merged 47 commits intodevnet-readyfrom
feat/conviction

Conversation

@gztensor
Copy link
Copy Markdown
Contributor

@gztensor gztensor commented Apr 17, 2026

Description

  • Implements an exponential lock mechanism where coldkeys can lock alpha stake to a specific hotkey per subnet, building conviction over time.
  • Lock state uses lazy evaluation: locked_mass stays constant over time and conviction grows as=t maturity rate calculated as c1 = c0 + (m - c0) * exp(-dt/tau), where c is conviction, and m is locked mass.
  • Enforces lock invariant on unstake (validate_remove_stake) and move/transfer (validate_stake_transition): total coldkey alpha on subnet must remain >= current locked amount.
  • New extrinsic lock_stake with MaturityRate configurable decay timescale (default half-life ~90 days).
  • User can unlock X amount of locked stake (with new extrinsic unlock_stake), which immediately drops conviction by X, but does not immediately allow to unstake.
  • The unlocked stake will become for the user to unstake or to lock again gradually over time with exponential decay rate of UnlockRate (default half-live ~30 days).

Updates:

  • Request 2026-04-19 (const): Can change the hotkey of a lock but when you do it resets the conviction.
  • 2026-04-21: Implementation decision - coldkey swap will fail if new coldkey already has any locks. Hotkey swap will reset conviction.

Known gaps

  • 1. do_recycle_alpha / do_burn_alpha bypass lock - calls decrease_stake_for_hotkey_and_coldkey_on_subnet without lock check.
  • 2. clear_small_nomination_if_required bypasses unlock period.
  • 3. Subnet dissolution orphans Lock entries - destroy_alpha_in_out_stakes removes all Alpha but not Lock storage; stale locks persist across netuid reuse.
  • 4. Coldkey swap does not migrate Lock entries.
  • 5. Hotkey swap does not update Lock entries.
  • 6. subnet_king needs optimization to avoid O(n) Lock iteration (another map possibly).

Implementation checklist

  • Hotkey conviction RPC
  • Allow moving from one hotkey to another without resetting conviction if coldkey owns both hotkeys
  • Extrinsic to switch hotkey in the lock (with loss of conviction)
  • Do not store zero entries in Lock and HotkeyLock maps
  • Bake in flexibility in state maps to lock to multiple hotkeys, enforce 1-1 lock in code
  • Unlocking behavior (exp decay of unlocks)
  • Add stake availability check in lock extrinsic
  • Tests for unlocking:
    • Cannot unstake immediately
    • Cannot lock immediately
    • Can unstake X after waiting Y
    • Can lock X after waiting Y, in which case cannot unstake after locked again
    • Can transfer or move, but the stake stays unavailable
  • More tests
    • Cannot double-lock

Questions

  • Does hotkey account need to exist in order for coldkeys to be able to lock to it? Currently it is not enforced.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Other (please describe):

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have run ./scripts/fix_rust.sh to ensure my code is formatted and linted correctly
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

@gztensor gztensor added the skip-cargo-audit This PR fails cargo audit but needs to be merged anyway label Apr 17, 2026
@gztensor gztensor marked this pull request as ready for review April 23, 2026 15:21
@gztensor gztensor marked this pull request as draft April 29, 2026 21:00
@gztensor gztensor marked this pull request as ready for review April 30, 2026 15:37
Comment thread pallets/subtensor/src/staking/lock.rs Outdated
sam0x17
sam0x17 previously approved these changes May 1, 2026
@sam0x17 sam0x17 merged commit b05822e into devnet-ready May 1, 2026
207 of 208 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-cargo-audit This PR fails cargo audit but needs to be merged anyway

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants