Overview
A persona is a deterministic behavior policy assigned to one class of simulated actor. The shipped catalog covers the failure modes Riptide's protocol fixtures and generic resource-grinder adapter care about. The riptide-config skill and riptide init --wizard can use the catalog for the protocol you picked plus a cross-protocol generic pool, then embed selected archetypes as [personas.<slug>] blocks in the adapter. Scenario run configs reference those slugs.
For the persona schema (label, action_rate_multiplier, action_weights, triggers) see Personas in the adapter spec. This page is the catalog and authoring guide.
Lending
Action vocab: deposit, borrow, repay, withdraw, liquidate.
- steady-lp · Steady LP — patient liquidity provider who compounds over time and only reacts to severe health-factor deterioration.
- cautious-yield-farmer · Cautious Yield Farmer — conservative depositor seeking stable yield who reduces exposure quickly when volatility rises.
- degen-borrower · Degen Borrower — max leverage, prefers more borrowing over safety, rarely exits voluntarily.
- aggressive-arb-bot · Aggressive Arb Bot — latency-focused; uses leverage aggressively and rotates capital when utilization spikes.
- panic-whale · Panic Whale — large holder who exits abruptly when the tape weakens. Canonical driver for the bad-debt failure mode.
- whale · Whale — outsized single-agent borrow with fixed-amount sizing; holds into the shock instead of unwinding.
AMM / DEX
Action vocab: swap, add_liquidity, remove_liquidity.
- swapper · Vanilla Swapper — baseline user swapping at a steady rate with no optimization.
- arbitrageur · Arbitrageur — swaps A→B aggressively when
pool.last_swap_pricedrifts below a reference. Drivesreserve_depletion. - lp-provider · Liquidity Provider — adds liquidity when reserves look healthy; pulls some back when the pool looks stressed.
- sandwich-attacker · Sandwich Attacker (approximate) — bursty one-directional swap activity around volume surges. Approximates the on-chain footprint (Riptide does not model mempool ordering).
- rug-puller · Rug-Puller — large LP burns all accumulated shares when the pool drifts to a favorable state or volume spikes. Probes the JIT-liquidity hook.
Perpetuals
Today's generic-path executable actions are deposit and withdraw; semantic flavor is encoded in weights and triggers referencing perp-specific observations.
- leveraged-long · Leveraged Long — heavy deposit weighting; rare withdraw; trigger boosts deposit when collateral falls below a band.
- leveraged-short · Leveraged Short — mirror of leveraged-long on the short side. Trigger fires on detectable open-interest skew.
- delta-neutral-farmer · Delta-Neutral Farmer — rebalances between deposit and withdraw to keep free collateral near a target band.
- funding-arbitrageur · Funding Arbitrageur (proxy) — uses
market.total_oi_longvstotal_oi_shortas a stand-in for funding-rate observations. - liquidator · Liquidator — waits for a liquidated victim, then withdraws the seized balance.
Liquid Staking
Action vocab: stake, request_unstake, claim_unstake.
- steady-staker · Steady Staker — quiet majority that holds LST through volatility. Reference population; no triggers.
- yield-maxi · Yield Maximizer — high-rate, stake-heavy. Trigger flips it briefly into profit-take redemption when exchange rate drifts up.
- panic-exiter · Panic Exiter — fires hard at
request_unstakewhen exchange rate falls below 9_500 bps. Kelp / rsETH-style panic shape. - arb-redeemer · Arb Redeemer — queue-aware churner. Boosts
claim_unstakewhen the pending queue refills.
Stablecoin
Action vocab: deposit_collateral, mint_stable, request_redeem, claim_redeem.
- cautious-minter · Cautious Minter — overcollateralizes well above the mint target. Reference population; no triggers.
- leverage-looper · Leverage Looper — yield-seeking minter who keeps pressing mint to maximize outstanding stable liability.
- panic-redeemer · Panic Redeemer — rushes
request_redeemwhenpool.effective_collateral_ratio_bpsfalls under par. UXD-style backing-stress shape. - arb-redeemer · Arb Redeemer — mirror of the LST arb-redeemer with the trigger flipped to
pool.pending_redemption_count.
Cross-Protocol Generic Pool
Every protocol bucket also offers these archetypes. Their action vocab came from whichever protocol they were authored against — re-bind action_weights to your adapter's real action names before using them outside that protocol.
- swapper, arbitrageur, lp-provider, sandwich-attacker, rug-puller — AMM-flavored.
- leveraged-long, leveraged-short, delta-neutral-farmer, funding-arbitrageur, liquidator — perps-flavored.
- whale — lending-flavored.
Writing Your Own Persona
None of the shipped archetypes are mandatory. When the catalog doesn't cover the actor class you want to model, add a new [personas.<slug>] block to your adapter and reference that slug from any run-config.json that should use it. The adapter block is both the reviewer-facing source of truth and the engine runtime input.
1. Start from the schema
Four declared fields, plus an optional persona_args:
label— display name in reports and the dashboard.action_rate_multiplier— how often this persona acts per tick relative to baseline (1.0 = baseline). Use0.5for a quiet majority,1.5–2.0for hot agents.action_weights— relative likelihood of each adapter action. Keys must exactly match names declared in[actions.*]; lint rejects unknown keys.triggersoptional — conditional weight boosts. Each entry is{ if = "<observation expr>", then = "<action>", weight_boost = <float> }.persona_argsoptional — named values referenced from[instructions.<ix>].argsvia"@persona.<key>". Use this when one action has discrete variants (swap direction, long vs short side) and you want different personas to commit to different choices.
2. Pick a behavior shape
Three shapes cover most of what the shipped catalog uses; copying one is usually faster than designing from scratch.
- Reference population — single high-weight action, no triggers. Used to set a baseline the stress personas push against. Examples: steady-lp, steady-staker, cautious-minter.
- Single-trigger panic — modest baseline weights with one aggressive trigger that flips behavior when an observation crosses a threshold. Examples: panic-exiter, panic-redeemer, panic-whale.
- Queue / opportunity sweeper — weights split across two related actions, with a trigger that boosts the second when a queue or counter refills. Examples: arb-redeemer (LST and stablecoin variants).
3. Worked example — drafting a "leveraged-loop-unwinder"
Suppose you have a lending program and want a persona that levers up while utilization is low but unwinds aggressively the moment utilization climbs past 8000 bps. The shape is single-trigger panic with two non-trivial action keys:
[personas.leveraged-loop-unwinder]
label = "Leveraged loop unwinder"
action_rate_multiplier = 1.2
action_weights = { deposit = 0.4, borrow = 0.5, repay = 0.05, withdraw = 0.05 }
triggers = [
{ if = "pool.utilization > 8000", then = "repay", weight_boost = 6.0 },
{ if = "pool.utilization > 8000", then = "withdraw", weight_boost = 4.0 },
]What's happening:
- Below the threshold, weights bias toward levering up — 90% deposit/borrow.
- When
pool.utilizationcrosses 8000 bps, both unwind actions get boosted; the runtime multiplies the boost into the weight, sorepayjumps from 0.05 to 0.30 andwithdrawfrom 0.05 to 0.20. The net effect: aggressive unwinding while the trigger holds. - The trigger keys (
pool.utilization) must be declared as observations on the adapter — see Observations.
4. Validate before running
Two cheap checks catch most authoring mistakes:
riptide lint <program>— flagsaction_weightskeys that don't match any[actions.*]declaration on the adapter. Common after copying a persona between protocols.- One-seed smoke — for adapter-only programs,
riptide adapt --adapter .riptide/adapters/<program>.tomlis enough. For harnessed programs, runriptide run --adapter .riptide/adapters/<program>.toml --harness .riptide/harness --seeds 1so persona actions encode and dispatch against real setup state.
5. Iterate from a real run
First-pass weights are guesses. Run the baseline scenario with the new persona active, watch the report's per-action counts, and tune from there. The riptide-config skill can also propose starter scenarios that exercise a new persona — see the Quickstart.