Bonding curves as ALife organisms · deep dive

Expansion of seven topics from the bonding-curve gallery: lifecycle & mortality, homeostasis, ecological niche, partner trading, predator-prey, mimesis, MAP-Elites.

Each topic gets: three new figures, a mechanism walk-through, a cadCAD-wiring sketch, a plausible-finding summary, and a paper anchor. Synthetic data — regenerate with python3 generate.py.

BC2Lifecycle & mortality

The lifecycle picture is the proposal's hook: bonding curves have birth, metabolism, adaptation, and death. To make that claim empirically rigorous we need three things — a definition of each phase, the statistical distribution of how long curves spend in each, and a decomposition of how they actually die.

↗ open hero figure (BC2)
Mechanism — how phases are detected

Phases are not declared up-front; they're inferred from state-variable signatures. Three time-series features drive the classifier:

  • mint / burn flux — when net flux ≫ 0, curve is in growth; when ≈ 0, maturity; when ≪ 0, senesce.
  • holder-count derivative — saturating slope marks the growth→maturity transition.
  • governance-event density — a cluster of votes within a window flips the curve into the adapt phase for the window duration.

A simple hidden-state HMM over these three features recovers crisp phase labels and gives us BC2a (definitional), BC2b (duration), and BC2c (mortality) as derived products of the same labelling pass.

BC2a phase atlas
BC2a Phase atlas — five definitional cards. Each panel shows the characteristic price trajectory for that phase plus the state-variable signature used to classify it. This is the field-guide page for the rest of the lifecycle work; everything else presupposes these definitions.
BC2b phase durations
BC2b Phase-duration violins across 50 synthetic organisms, log y-axis. Maturity has the longest median and largest spread (the "old-age" effect); deploy is tight and short. Heteroscedasticity across phases is itself a finding — it implies different generative processes per phase.
BC2c cause and age
BC2c Mortality decomposition. Left: pareto of cause-of-death counts with cumulative share (Lorenz-style). Right: age-at-death distribution stratified by cause — bank runs kill young, deprecation kills old, gov shutdowns are heavy-tailed. Together these answer "what kills bonding curves, and when?" — the organismal-biology question the proposal claims to address.
cadCAD wiring — what to instrument
state_vars = {
    'reserve':      0.0,
    'supply':       0.0,
    'price':        0.0,
    'holders':      set(),
    'gov_events':   [],            # (timestep, proposal_id, accepted)
    'phase_label':  None,          # inferred each block
    'death_cause':  None,          # set once when phase → 'dead'
}
psubs = [
    {'policies':   {'mint_burn':   mint_burn_policy},
     'variables':  {'reserve':     s_reserve,
                    'supply':      s_supply,
                    'price':       s_price}},
    {'policies':   {'phase_clf':   phase_classifier_policy},
     'variables':  {'phase_label': s_phase}},
    {'policies':   {'mortality':   mortality_check_policy},
     'variables':  {'death_cause': s_death}},
]

Phase-label is a derived field updated once per block via phase_classifier_policy. Mortality is checked last so the death cause can reference the final pre-death state.

Plausible findings
  • Curves with a long maturity phase relative to their growth phase show lower mortality across all causes — "slow growth, long life" generalizes.
  • Mortality is bimodal in age: young deaths from bank runs / arb attacks, old deaths from deprecation. Mid-life deaths are rare and almost always governance-driven.
  • The adapt phase is a mortality multiplier: organisms die during or shortly after governance events at 2-3× the base rate.
Paper anchor

No direct paper anchor in Papers/; this is one of the original contributions of the proposal. Survival-analysis framing borrows from clinical epidemiology (Kaplan-Meier in BC11). Phase decomposition is conceptually adjacent to Pedersen et al. 2025's notion of developmental stages in evolving hypernetworks.

BC3Homeostasis & shock response

An organism that can't restore homeostasis after perturbation isn't an organism — it's a one-shot mechanism. The hero figure (BC3) shows four archetypes recovering after a single shock; the deep-dive expands to a population view, a multi-shock view, and a comparative-resilience view across the population.

↗ open hero figure (BC3)
Mechanism — what counts as "recovery"

For a homeostatic ratio r(t) = reserve(t) / reserve_target(t), recovery after a shock at time t₀ is characterised by two numbers:

  • recovery τ — time for |r(t) − 1| to fall below half its post-shock peak.
  • overshoot amplitude — peak |r(t) − 1| after crossing back through 1 (signed if needed).

The (τ, overshoot) plane partitions curves into qualitatively distinct stability regimes — that's what BC3a clusters.

BC3a recovery clusters
BC3a Recovery-profile clusters across ~100 curves in (τ, overshoot) space. Four natural clusters emerge: damped (low τ, low overshoot — engineering ideal), slow (high τ, low overshoot), oscillatory (medium τ, high overshoot), brittle (huge τ, may not recover at all). Stars mark the four hero archetypes from BC3 — they're not hand-picked, they're the cluster modes.
BC3b multi-shock
BC3b Same curve, three shock pathologies: reserve drain (LP withdrawal), holder exit (panic sell), governance attack (malicious param flip). The recovery signature differs — reserve drain is a fast decay, holder exit is oscillatory, gov attack shows a delayed self-correction once the vote reverses. A real organism's pathology profile is a vector, not a scalar.
BC3c perturbation matrix
BC3c Perturbation-response matrix — 5 shock types × 8 curves, colour = log₁₀ recovery time. Numbers in cells are raw step counts. ✗ marks failure to recover within the simulation window. Lets you read off each curve's resilience profile at a glance: which pathologies it survives, which kill it.
cadCAD wiring
# shocks injected as exogenous policy actions
shock_schedule = {
    60: ('reserve_drain', {'fraction': 0.35}),
    140: ('holder_exit', {'fraction': 0.4}),
    220: ('gov_attack',  {'param': 'slope', 'multiplier': 3.0}),
}

def shock_policy(params, step, history, state):
    if step in shock_schedule:
        return {'shock_event': shock_schedule[step]}
    return {'shock_event': None}

# Optuna-driven sweep over shock_t × curve_params produces BC3c
Plausible findings
  • The (τ, overshoot) clusters are stable across cadCAD seeds — they track curve topology, not noise.
  • "Damped" curves correlate strongly with high reserve_ratio and moderate slope; "brittle" curves cluster around low reserve_ratio regardless of slope.
  • Multi-shock response is non-additive: a curve resilient to reserve drain may still die to oracle desync, and vice versa (sparse vs dense rows in BC3c).
Paper anchor

Closest connection: Bielawski et al. 2025 — Efficient Discovery of Unique Interventions. Shocks here are interventions; BC3c is the same instrument they use to characterise an intervention's effect signature. Reframing shock-response as intervention-discovery opens up adaptive shock-design (smarter than random — pick the shock that maximally distinguishes curves).

BC4Ecological niche

Niche theory is the bridge between single-organism biology and ecosystem dynamics. The radar in BC4 shows niche position; the deep-dive adds niche distance (overlap matrix), structure (PCA), and development (temporal drift).

↗ open hero figure (BC4)
Mechanism — defining the niche

Each curve at time t gets a 6D trait vector:

  • stability — 1 − rolling-std(price)
  • growth — Δ supply / Δ t
  • holder diversity — 1 − holder-Gini
  • gov activity — proposal / vote count per window
  • capital efficiency — TVL / reserve
  • peg tightness — 1 − rolling-std(price / peg-target) where defined

Niche overlap = cosine similarity between vectors. Hutchinson's n-dimensional niche concept maps directly onto this.

BC4a niche overlap
BC4a Niche-overlap matrix across 8 curves (2 per archetype). Block-diagonal structure = curves within an archetype share a niche. High off-diagonal values flag competitive-exclusion candidates — pairs of curves likely to be in zero-sum competition for the same ecological role. If we see one of each pair die, the metric predicted it.
BC4b niche PCA
BC4b Trait-space PCA. 72 curves projected onto the first two principal components (~70% of total variance combined). Convex hulls per archetype show how cleanly the four niches separate. Tight, non-overlapping hulls would be strong evidence that bonding-curve parameter space discretizes into natural categories rather than being continuous.
BC4c temporal drift
BC4c Niche drift through one organism's lifecycle. At deploy the curve is high-growth, low-stability; by maturity it has rotated toward high stability + capital efficiency; senescence collapses the diversity and peg axes. Sequential radar shapes = developmental trajectory of a single curve.
cadCAD wiring
# trait vector computed once per block, persisted to state
def niche_trait_policy(params, step, history, state):
    window = 100
    recent = history[-window:]
    return {'trait_vec': np.array([
        1 - np.std([h['price'] for h in recent]),
        (state['supply'] - recent[0]['supply']) / window,
        1 - gini([h['holders'] for h in recent[-1]]),
        sum(1 for h in recent if h['gov_event']) / window,
        state['tvl'] / state['reserve'],
        1 - np.std([h['price'] / h['peg_target']
                    for h in recent if h['peg_target']]),
    ])}
Plausible findings
  • Competitive-exclusion-candidate pairs (BC4a high off-diag) have lower joint survival than random pairs — when two curves overlap strongly in niche, one typically dies.
  • PCA loadings reveal the dominant axes are stability vs growth and diversity vs efficiency — a 2D summary of bonding-curve design space.
  • Temporal drift shows curves specialise over their lifecycle: radar shapes get pointier (lower entropy) with age.
Paper anchor

Loosely connects to Cimpeanu et al. 2025 — Hidden Price of Cooperation (the cooperative niche is one trait dimension) and Nishimoto 2025 — Partner Choice Cooperation (partner choice is conditioned on niche similarity / dissimilarity).

BC5Partner trading & cooperation

Curves don't exist in isolation — they trade with each other through liquidity pools, arbitrage paths, and routing aggregators. Mapping the topology and dynamics of that trading network is the operational test of "ecosystem".

↗ open hero figure (BC5)
Mechanism — building the trading graph

For each block, increment edge weight (i, j) by the volume swapped between curve i and j's tokens (through any pool or aggregator). Aggregate over a sliding window. The resulting weighted graph is the substrate; everything in BC5 derives from standard graph metrics on it.

  • community detection — Louvain modularity on the windowed graph (BC5a).
  • modularity Q over time — track Q as the window slides (BC5b).
  • directed flow — keep signed volume per edge (who initiates each swap) for the Sankey (BC5c).
BC5a community graph
BC5a The same trade-volume matrix from BC5 laid out as a graph with Louvain community detection. Edge width = volume. Three communities emerge naturally; four bridge edges connect them. The bridges are structurally important: their failure fragments the ecosystem.
BC5b modularity over time
BC5b Modularity Q against inter-community trade share, plotted over the simulation. Phase-transition behaviour: an initial rise in Q (cliques form), then a shock event reactivates bridges. The crossover points are the moments of topological reorganisation in the ecosystem.
BC5c trade Sankey
BC5c Directed flow Sankey — same set of 6 curves shown as source / sink columns with weighted arcs. Reveals asymmetries invisible in the symmetric heatmap: e.g. CRV-A is a net source, flows are mostly downstream. The asymmetry is the predator-prey signature seen explicitly in BC6.
cadCAD wiring
state_vars['trade_graph'] = nx.DiGraph()

def trade_policy(params, step, history, state):
    swaps = simulate_block_swaps(state)
    return {'swaps': swaps}

def s_trade_graph(params, step, history, state, signals):
    G = state['trade_graph'].copy()
    for sw in signals['swaps']:
        if G.has_edge(sw.from_curve, sw.to_curve):
            G[sw.from_curve][sw.to_curve]['weight'] += sw.volume
        else:
            G.add_edge(sw.from_curve, sw.to_curve, weight=sw.volume)
    # window: decay old edges
    for u, v, d in G.edges(data=True):
        d['weight'] *= 0.99
    return ('trade_graph', G)
Plausible findings
  • Trading communities (BC5a) align with niche clusters (BC4b) — curves in the same niche tend to be in the same trade community. But not perfectly: bridges connect distant niches.
  • Modularity Q anticorrelates with ecosystem resilience: very high Q means a shock to one community can't be absorbed by the others.
  • Sankey asymmetry (BC5c) predicts predator-prey roles in BC6 — net-source curves are prey, net-sink curves are predators.
Paper anchor

Nishimoto 2025 — Partner Choice Cooperation. Their core finding: partner-choice mechanisms (refusing to interact with defectors) stabilise cooperation. In the bonding-curve translation, refusal = routing-aggregator deprioritisation; defection = liquidity siphoning. Whether the curve-ecosystem reproduces their stabilisation result is a falsifiable claim BC5 can answer.

BC6Lotka-Volterra & coexistence

The original BC6 shows a single predator-prey trajectory; the deep-dive characterises the system as a whole — under what parameters it oscillates, when a third species changes the picture, and which initial conditions lead to coexistence vs extinction.

↗ open hero figure (BC6)
Mechanism — the model

The classic two-species system:

dx/dt =  a·x  −  b·x·y      (prey: speculative curves)
dy/dt = −c·y  +  d·x·y      (predator: arbitrageur curves)

Bonding-curve interpretation:

  • x — net inflow rate into speculative curves (they grow on their own at rate a).
  • y — arbitrageur capital allocated to extract from those curves (decays at rate c when nothing to extract).
  • b·x·y — extraction term: arbs draw value proportional to opportunity × predator capital.
  • d·x·y — predator growth: extraction translates into more predator capital.
BC6a stability map
BC6a Parameter sweep across (a, c) — for each (prey-growth, predator-decay) pair, classify the long-term behaviour: stable coexistence, prey extinction, predator runaway, sustained oscillation. The hero point from BC6 sits squarely in the oscillation band. Contours show oscillation amplitude. This is the "where do bonding-curve ecosystems live in parameter space" picture.
BC6b three species
BC6b Add a third species — a stablecoin curve with logistic self-regulation (carrying capacity) and weak coupling to the predator. Time-series + three pairwise phase portraits. The stablecoin acts as a damping element: it caps predator capital and reduces oscillation amplitude. Suggests stable curves play an ecological role beyond their trader-facing utility.
BC6c outcome basins
BC6c Outcome basins in (x₀, y₀) initial-condition space. Same dynamical parameters, different starting populations → different long-term fates. Sample trajectories overlaid. Tells you that the state at launch can determine whether an ecosystem survives — not just the rules.
cadCAD wiring
# at the meta-simulation level: each cadCAD run = one (x₀, y₀, a, b, c, d) point
# wrap in a parameter sweep
sweep = {
    'a':      np.linspace(0.2, 1.5, 30),
    'c':      np.linspace(0.2, 1.5, 30),
    'x_init': [40],
    'y_init': [12],
    'b':      [0.025],
    'd':      [0.018],
}
# Optuna or grid runs the sweep; classification policy labels outcomes
# from the final 200-step window of each run.
Plausible findings
  • Sustained oscillation is the modal regime in realistic parameter ranges — predator-prey coupling is structurally unstable.
  • Adding a logistic third species shrinks the oscillation region (BC6b stability gain). This is the testable case for "structural diversity = ecosystem resilience" in crypto.
  • Outcome basins (BC6c) are non-convex — small perturbations to initial conditions can flip a curve-pair from coexistence to extinction. Launch state matters.
Paper anchor

Not directly paper-anchored. Closest connection: Cimpeanu et al. 2025 — Hidden Price of Cooperation, where the three-species extension makes precise the trade-off between predator/prey instability and stabiliser cost.

BC7Mimesis — cultural transmission of mechanisms

Curves don't only inherit from parents — they copy from successful unrelated curves. The mimesis tree showed structure; the deep dive asks whether copying actually helps, which copies help most, and which mechanisms achieve cultural saturation.

↗ open hero figure (BC7)
Mechanism — defining a "copy" event

Within each generation, a curve can choose to imitate one parameter from any other curve in its visibility radius. Imitation policy:

P(imitate j) ∝ exp(β · fitness(j))
   subject to: only-mechanism-with-higher-fitness-than-mine
   tie-break on niche-overlap

The chosen mechanism is copied (with small mutation) into the imitator's parameter vector. This is Carr et al.'s cybernetic-mimesis operator instantiated for bonding curves.

BC7a copy success
BC7a Copy-success rate per mechanism — share of imitation events that improved the imitator's fitness. Combined slope+RR copies are cultural winners (~78%); vesting copies are barely better than neutral (~41%). The neutral baseline (50%) is the no-effect line.
BC7b fitness delta
BC7b Fitness-delta histogram across all imitation events. Bimodal: a positive-skewed bulk (most copies help slightly) and a smaller negative bump (some copies are catastrophic — copying a mechanism that depends on parameters the imitator lacks). Mean is positive: cybernetic mimesis is on average adaptive.
BC7c cultural transmission
BC7c Mechanism × generation heatmap of adoption frequency. Different mechanisms have different transmission dynamics: slope spreads early and decays (fad), reserve-ratio rises monotonically (durable innovation), slope+RR shows late breakout (a meme that took a while to find its niche). Vesting stays low — culturally invisible.
cadCAD wiring
def mimesis_policy(params, step, history, state):
    candidates = visible_curves(state, radius=params['vis_r'])
    higher_fit = [c for c in candidates if c.fitness > state.fitness]
    if not higher_fit:
        return {'imitation': None}
    weights = np.exp(params['beta'] * np.array([c.fitness for c in higher_fit]))
    target = np.random.choice(higher_fit, p=weights / weights.sum())
    mech = pick_mechanism_to_copy(target, state, niche_overlap=...)
    return {'imitation': (target.id, mech)}
Plausible findings
  • Compound-mechanism copies (slope+RR) outperform single-parameter copies — they preserve mechanism coherence.
  • Mean fitness-delta is positive but small (~+0.04). Mimesis is a gradient-climbing operator, not a leap-finder. Pairs naturally with MAP-Elites exploration (BC8) which provides the leaps.
  • Cultural-transmission curves resemble innovation-diffusion S-curves from cultural-evolution literature — the same machinery applies.
Paper anchor

Carr et al. 2025 — Cybernetic Mimesis. Their thesis is that mimesis is a distinctive cybernetic operator — it embeds learning at the population scale, not the individual scale. BC7 specifically asks: does mimesis improve population-level fitness in bonding-curve ecosystems? Anne et al. 2025's adversarial framing (next section) is naturally complementary: mimesis exploits, MAP-Elites explores.

BC8MAP-Elites & the discovery archive

MAP-Elites is the proposal's headline empirical engine: a way of systematically charting the bonding-curve design space, not just optimising within it. The deep-dive adds the standard QD metrics (coverage, QD-score) and connects archive cells to actual curve shapes.

↗ open hero figure (BC8)
Mechanism — the algorithm
  1. Initialise an archive: empty cells indexed by (behaviour descriptor 1, behaviour descriptor 2).
  2. Sample a parent uniformly from filled cells, mutate its genome (curve params), run the cadCAD simulation.
  3. Compute the child's behaviour descriptors and fitness. Find its archive cell.
  4. If the cell is empty or the child's fitness exceeds the current resident, replace the resident.
  5. Loop. Track coverage (% cells filled) and QD-score (Σ resident fitness) over generations.

Adversarial MAP-Elites (Anne et al.) injects a second population of "challenger" environments that score elites adversarially — the elite that survives the worst challenger wins.

BC8a coverage growth
BC8a Coverage growth — % of archive cells filled vs generation, for three search strategies: vanilla MAP-Elites, adversarial MAP-Elites, random search baseline. Adversarial saturates ~2× faster than vanilla; random search lags both significantly. This is the QD field's standard "did the algorithm work?" plot.
BC8b QD-score
BC8b QD-score — sum of elite fitnesses across all filled cells, over generations. The composite metric that rewards both quality (per-cell fitness) and diversity (number of filled cells). Adversarial advantage region shaded — area between the curves quantifies the benefit of adversarial pressure for discovery.
BC8c elite genomes
BC8c Elite genomes — four archive cells (different volatility / gini regimes) with their actual price-supply curve shapes shown underneath. Closes the loop from abstract archive cell to concrete curve mechanism. The high-vol / high-gini cell is a sharply convex curve; the low-vol / low-gini cell is nearly linear. Archive cells stop being abstract.
cadCAD wiring
# MAP-Elites loop wraps the cadCAD simulation
archive = {}     # (vol_bin, gini_bin) → (genome, fitness)

def map_elites_step(rng):
    if len(archive) < params['init_pop']:
        genome = sample_random_genome(rng)
    else:
        parent_key = rng.choice(list(archive))
        genome = mutate(archive[parent_key][0], rng)
    result = run_cadcad(genome)             # full cadCAD run
    bd1, bd2 = compute_descriptors(result)
    fit = compute_fitness(result)
    key = (bin(bd1), bin(bd2))
    if key not in archive or archive[key][1] < fit:
        archive[key] = (genome, fit)

Each evaluation is one cadCAD run. Optuna's TPE can drive the mutation operator for more sample-efficient exploration than uniform mutation.

Plausible findings
  • Adversarial MAP-Elites finds more robust elites in addition to filling the archive faster — Anne et al.'s core result reproduces in the bonding-curve domain.
  • The high-quality region of the archive is small relative to the explored region: most behaviour-descriptor combinations have no high-fitness elite. The map says where bonding curves can live, not just where they do live.
  • Coupling MAP-Elites (exploration) with mimesis (BC7, exploitation) outperforms either alone — empirical confirmation of the dual-process evolution argument.
Paper anchor

Anne et al. 2025 — Generational Adversarial MAP-Elites. They show that adversarial pressure during MAP-Elites discovery finds more robust archives than vanilla MAP-Elites. The bonding-curve interpretation: instead of just discovering curves that perform well in their generative environment, we discover curves that perform well across an evolving set of challenger environments (shocks, hostile gov scenarios, adversarial trading). This is the rigorous translation of "make robust crypto mechanisms" into ALife.

Closing — what this set gets you

The 21 figures here form three layers of evidence for the bonding-curves-as-ALife thesis:

When you've picked the 4-6 figures worth doing for real, I'll harden them: real axis units sourced from a candidate dataset, citation footnotes inline, Plotly versions for BC3a / BC4b / BC5a (the ones where hover details matter), and a Streamlit panel for BC5 (slide the modularity window) and BC8 (browse the archive interactively).