Skip to main content
This is the shortest path from no strategy to a validated deposit/withdrawal pair. You will build a reserve manager for one yield source: when idle assets are too high, it deposits; when idle assets are too low, it withdraws.

What You Are Building

A drift-trigger reserve pair:
  • A DEPOSIT strategy fires when vault_free_assets is above 10% of vault TVL.
  • A WITHDRAWAL strategy fires when vault_free_assets is below 5% of vault TVL.
  • The withdrawal half redeems part of the deployed position back into the reserve when idle assets run low.
Two strategies, one yield source, one EXPR rule each, no indicators.

1. Choose the Lane

Strategy actions group into lanes. The lane determines where the strategy appears in the canvas and how ordering works. See Strategy Canvas for the UI model.

2. Pick the Action

Each strategy has one action_config.action. Use DEPOSIT for the inflow strategy and WITHDRAWAL for the outflow strategy. The other action_config fields tell OMS how to execute: See Action Config for the full field reference.

3. Write the Trigger

The trigger is a rules tree. The simplest form is a single EXPR leaf that returns a boolean.
vault_free_assets is sourced live from chain as IERC20(asset).balanceOf(strategy) through the EVM RPC datafeed, so the trigger reflects the strategy contract’s actual idle balance. vault_tvl is derived from yield-source allocations on the subgraph cadence. Both are in the underlying asset’s base units.
Avoid division in trigger expressions. The validator dry-runs expressions against an empty snapshot where values can be zero. vault_free_assets / vault_tvl > 0.10 can fail with division by zero at create/update time. Use the multiplicative form: vault_free_assets > 0.10 * vault_tvl.
See Strategy DSL for rule-tree syntax and variable notes.

4. Size the Action

action_config.size_expr is evaluated when the rule fires. It must return a positive number at runtime. For the deposit half, deploy idle assets:
For the withdrawal half, redeem part of the deployed position. Withdrawals execute through the ERC-4626 Redeem4626VaultHook, which calls redeem(shares), so the size is in yield-source share units, not asset units. Size off the position’s ys_<address>_shares:
Deposit and withdrawal sizes use different units. A DEPOSIT sizes in underlying asset base units; a WITHDRAWAL through Redeem4626VaultHook sizes in yield-source share base units. Converting an asset target to shares means dividing by ys_<address>_pps, which the validator rejects at create/update time — the dry-run snapshot makes pps zero, triggering division by zero. Prefer a share-denominated expression such as a fraction of ys_<address>_shares.
The deposit size is positive whenever idle assets exist; the withdrawal size is positive whenever the position holds shares. A size_expr that evaluates to 0 or less is dropped before it reaches OMS.

5. Deposit Strategy JSON

Replace the vault ID, yield-source address, hook address, and executor address before sending. These payloads pass StrategyValidator (shape, identifier, and dry-run checks), but note the validator does not confirm that execution_name exists in the live hook registry or that size_expr units match the hook — verify both against Action Config.

6. Withdrawal Strategy JSON

7. POST and Run

Each strategy is one create request:
Repeat with the withdrawal payload. A successful response returns the persisted strategy with state: "CREATED". Move each strategy to RUNNING when the vault has upkeep, merkle proof coverage, whitelisted yield sources, and OMS session-key readiness:
See Strategy Engine API for endpoint details.

What to Watch

If creation, ticking, or execution fails, use Strategy Troubleshooting.