How it works
The stabilizer combines two on-chain mechanisms. Both are opt-in and both are reversible.Fee control
You register your vault, and the stabilizer contract takes over the vault’s Manager role. From then on, the vault fee is adjusted automatically against live yield data:- When the strategies earn more than the target, the fee rises and the surplus is captured as vault fees.
- When the strategies earn less than the target, the fee falls toward your minimum, so depositors keep as much of the yield as possible.
minFeeBps to maxFeeBps range you set at registration, and that bound is enforced by the contract itself on every change. Adjustments are gradual: the fee moves in small steps rather than jumping, so a single noisy data point cannot swing it.
Boosts
Fee control can only trim yield that is above the target. It cannot lift yield that is below it. For that, you fund a boost campaign: an escrow account in the vault’s asset, held by the stabilizer’s treasury contract. When the vault’s yield runs below target and the campaign has budget, funds are streamed from the escrow into the vault. That raises the value of every vault share, which is exactly how depositors experience yield. Boosts spend only what the campaign holds: when the budget runs out, boosting stops and the vault returns to its organic rate. A boost carries no vault fee, so it lifts your users’ APY and not your revenue. Ask us before you plan a campaign you expect to earn from. Campaigns are per vault and only supported for single-asset vaults. We register the campaign for you; once it is active, anyone can add funds to it.Leaving
Registration is not a one-way door. Calling the exit endpoint returns the Manager role to your admin address and the stabilizer stops touching the vault.Availability
- Mainnet only for now.
- Enabled per account. The endpoints below return
403 Forbiddenuntil the feature is switched on for your API key. Contact us on Discord to enable it.
Endpoints
All routes live underhttps://api.defindex.io/stabilizer/{vaultAddress} and take an optional ?network=mainnet query parameter. Authentication is the standard Authorization: Bearer <api_key> header used across the API.
Every write endpoint returns an unsigned transaction for the caller you pass in the body:
xdr with the caller’s key and submit it, either directly through your own RPC connection or through the API’s POST /send endpoint, the same flow as any Vault Operation. Smart wallet callers (C-addresses) cannot sign a prebuilt transaction, so for them xdr comes back null and isSmartWallet is true: build your own transaction around operationXDR instead.
GET /stabilizer/{vaultAddress}/status
Read-only snapshot of the vault’s stabilizer state:
config is null when the vault is not registered. campaign is null when the vault has no boost campaign. The two are independent: a vault can be registered without a campaign, and vice versa. Campaign amounts are in stroops of the campaign asset, and lastBoostedAt is unix seconds, 0 meaning never.
POST /stabilizer/{vaultAddress}/register
caller must be the vault’s current Manager and becomes the vault’s stabilizer admin: the address that controls the settings below and the only one that can exit. The returned transaction both registers the vault and hands the Manager role to the stabilizer contract, so one signature covers the whole handoff.
All rates are basis points: 10000 is 100%, 800 is 8%. minFeeBps must be less than or equal to maxFeeBps.
POST /stabilizer/{vaultAddress}/target-apy
caller must be the vault’s stabilizer admin.
POST /stabilizer/{vaultAddress}/fee-bounds
caller must be the vault’s stabilizer admin, and minFeeBps must be less than or equal to maxFeeBps.
POST /stabilizer/{vaultAddress}/exit
caller must be the vault’s stabilizer admin.
POST /stabilizer/{vaultAddress}/boost/deposit
amount is stroops of the campaign asset, as a string. Anyone may fund an active campaign, not just the admin. Returns 404 if the vault has no campaign registered and 400 if the campaign is inactive.
Errors
Custody
Your depositors’ funds never leave the vault and their withdrawals are never frozen. The stabilizer only moves the fee inside your range, boosts only transfer in, and exit returns the Manager role to you. The boost budget is escrowed separately per vault and operated by DeFindex.Audit
Audited by Runtime Verification, delivered July 2026, against defindex-io/stellar-apy-stabilizer at commit6b2b2a4: DeFindex APY Stabilizer Audit Report.
Ten findings, one Low and one Medium, the rest informative. The Low and seven of the informative findings were fixed during the engagement.
The Medium is open and worth reading before you deploy: a boost is a plain token transfer into the vault, which lifts the price per share for everyone holding at that moment, so someone can deposit just before a boost and withdraw just after to capture part of it. The mitigation sits in the boost bot rather than the contracts: boosting at least hourly keeps the amount per boost small, and unpredictable timing makes it harder to front-run.
The bot, the off-chain tooling and the deployment infrastructure were outside the audit scope.