feat: matured TaoFlow EMA to reduce capital recycling attacks#2704
Open
igoraxz wants to merge 1 commit into
Open
feat: matured TaoFlow EMA to reduce capital recycling attacks#2704igoraxz wants to merge 1 commit into
igoraxz wants to merge 1 commit into
Conversation
bc69263 to
8c8b229
Compare
The user-flow EMA driving emission allocation reacts symmetrically to inflows and outflows, letting transient capital inflate a subnet's emission share before it is withdrawn. This adds a second EMA on top of the user-flow EMA and uses the lower of the two as the signal: raw = flow EMA of (buys - sells) [existing] slow = flow EMA of raw [new] matured = min(raw, slow) [used in the share calc] Because slow lags raw, the clamp is asymmetric: Inflow spike: raw rises above slow -> matured = slow (credit accrues slowly) Outflow: raw drops below slow -> matured = raw (applies immediately) Steady flow: raw ~= slow -> matured ~= raw (no penalty) Transient inflows are credited only at the slow EMA's pace while withdrawals take effect immediately; durable sustained inflow still converges to the full signal. Design notes: - No new parameter: slow reuses FlowEmaSmoothingFactor. A sweep of the maturity half-life against both manipulation resistance and honest-subnet bootstrap time put the optimum at the same half-life as the main flow EMA (the knee of the trade-off); equal factors make slow a clean double-EMA of the flow. - SubnetEmaSlowTaoFlow stores the unclamped EMA(raw), not min(raw, slow), so the slow EMA tracks the true long-run signal and can recover; the clamp is applied only at read time. - On first access the slow EMA seeds at the current raw EMA (no emission cliff at deployment) with last_block = 0, so the update branch runs and persists; the first update is a no-op (slow = raw). - Protocol EMA is not matured -- only user demand is delayed. Builds on the normalized protocol cost change (opentensor#2675). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8c8b229 to
4d5725e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The user-flow EMA that drives emission allocation reacts symmetrically to inflows and outflows. That symmetry lets a participant temporarily inflate a subnet's emission share with capital that is later withdrawn, rather than rewarding durable demand.
Change
Add a second EMA on top of the existing user-flow EMA, and use the lower of the two as the signal:
Because
slowlagsraw, the clamp is asymmetric:rawjumps aboveslow->matured = slow: credit accrues slowly.rawdrops belowslow->matured = raw: the decrease applies immediately.raw ~= slow->matured ~= raw: no penalty for real demand.So transient inflows are credited only at the slow EMA's pace, while withdrawals take effect immediately. Durable, sustained inflow still converges to the full signal.
Design notes
slowreusesFlowEmaSmoothingFactor. A sweep of the maturity half-life against both manipulation resistance and honest-subnet bootstrap time put the optimum at the same half-life as the main flow EMA: it is the knee of the trade-off (shorter weakens the clamp, longer barely improves resistance while slowing new-subnet onboarding). Equal factors also makeslowa clean double-EMA of the flow.SubnetEmaSlowTaoFlowstores the unclampedEMA(raw), notmin(raw, slow)-- the clamp is applied only at read time, so the slow EMA keeps tracking the true long-run signal and can recover.slow = rawso existing subnets see no emission cliff at deployment.Test plan
Builds on #2675 (normalized protocol cost), already merged to devnet-ready.