Skip to content

[Feature] Fully automated cross-vault yield routing (delegated rebalance) #469

Description

@collinsezedike

Summary

The vault's active adapter is static, changed only manually via set_adapter. Existing routing logic (selectBestVault in packages/stellar-sdk-helpers/src/routing.ts, recommendedVaultId in packages/api-core/src/vaults.ts) only steers new deposits toward the best available vault at deposit time; it never moves capital already deposited. router.rebalance() (packages/contracts/router/src/lib.rs) already exists and atomically moves a user's own position between two separate vault instances in one transaction, but it is user-signed, so a user's capital stays parked in a lower-yielding vault until they notice and sign a rebalance themselves.

Motivation

Automatic routing to the best available yield across deployed vault instances, without requiring a user to notice a rate change and manually sign a transaction, is the core value proposition of a yield aggregator. Without it, Meridian is a manual multi-vault dashboard, not an aggregator: capital doesn't actually move to wherever yield is best unless a human is watching and acting.

Proposed Solution

Build a delegated/pre-authorized triggering mechanism so an off-chain keeper can invoke router.rebalance() on a user's behalf without a fresh signature each time, gated by an explicit, revocable authorization the user grants once (e.g. a Soroban auth delegation with scope limits: which vaults, a max slippage/rate-improvement threshold before it can trigger, an expiry, and one-tap revocation). This is a distinct problem from #464 (adapter-level fund migration): rebalance() already safely moves a single user's own position between existing vault instances, so no vault-contract changes are needed there — the missing piece is entirely the delegation/authorization layer plus the off-chain rate-comparison keeper that decides when to trigger it.

Scope

Field Value
Area Contracts / API / SDK
Protocol affected Both
Network testnet
Breaking change? No (additive: opt-in delegation, manual rebalance unaffected)

Alternatives Considered

Semi-automated (UI prompt + user-signed rebalance() on every rate change): buildable today with zero new auth mechanism, but doesn't remove the dependency on the user being present and paying attention, which defeats the aggregator's purpose per the motivation above.

Acceptance Criteria

  • User can grant a scoped, revocable delegation authorizing an off-chain keeper to trigger rebalance() on their behalf
  • Delegation scope enforces at minimum: eligible vault set, minimum yield-improvement threshold before a rebalance can trigger, and an expiry
  • User can revoke the delegation at any time, effective immediately for future keeper attempts
  • Delegated rebalance cannot move funds anywhere other than between the vaults the user explicitly authorized
  • Off-chain keeper compares live rates across deployed vault instances and only triggers when the improvement clears the user's configured threshold (avoids needless fee-losing churn)
  • Security review of the delegation auth model: what a compromised keeper key can and cannot do to a user's funds
  • Tests cover: delegation grant, revocation, keeper trigger within scope, keeper attempt outside granted scope (must fail), and expired delegation (must fail)

Metadata

Metadata

Labels

contractsInvolves writing or testing Rust/Soroban contracts in packages/contractsenhancementNew feature or requesthardComplex implementation spanning multiple packages or involving Soroban contractssecuritySecurity hardening, vulnerability fixes, or audit-related worksorobanInvolves Soroban smart contract invocations or Soroban RPC calls

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions