defindex-strategy contract is a reference vault adapter. It maps each
DeFindex vault to one controller supply account for a single underlying asset.
Share accounting lives in the DeFindex vault contract; the strategy holds only a
vault-to-account mapping.
Deployment model
- One WASM per underlying asset. Deploy a separate strategy instance per listed market.
- One controller
account_idper vault. Vaults never share a lending account. - Strategy is the caller on all controller mutations (
supply,withdraw).
#401 NotInitialized. The
constructor then checks that a market index exists for asset on hub_id,
resolves the pool address from the controller, and stores this in instance
storage:
VaultAccount(vault_address) -> u64, which maps a
vault to the controller account holding its collateral.
Trait API
The contract implementsDeFindexStrategyTrait and exposes exactly these five
entrypoints — there is no account-id lookup view.
Deposit flow
authorize_as_current_contract, and that ordering is
load-bearing: it reconciles the stored mapping against
controller.account_exists first, so a re-deposit after a full withdraw does not
fail with Auth InvalidAction.
Step 1 is a measured transfer — the amount actually received is what gets
supplied, not the amount requested.
Withdraw flow
to directly from the pool. No pre-authorization is required on
the strategy side.
Harvest and price per share
harvest emits HarvestEvent (["strategy", "harvest"]) with a 12-decimal
price_per_share (PPS_DECIMALS = 12). It reads the controller’s
get_market_index(hub_asset).supply_index and floor-rescales it from RAY:
harvest moves no funds — the event’s
amount field is always 0 — and makes no on-chain state change; DeFindex
vaults use the event for share accounting.
Controller integration
Auth recipe
Supply requires the strategy to authorize its own token transfer to the pool before callingcontroller.supply:
to on the
controller’s behalf.
Strategy errors
These are the adapter’s own enum, independent of the protocol error codes.The vault-to-account mapping is one-way
VaultAccount(vault) is the only route back to a vault’s collateral, and
there is no entry point to re-point it. If you clear it while the account is
still alive, that collateral becomes unreachable through the adapter.
resolve_vault_account is written around that. It calls
controller.try_account_exists(stored) and treats the three outcomes
differently:
That third row is the important one. A lookup that merely failed to answer is
not evidence the account is gone. Treating it as gone would clear the only
pointer to live collateral.
Fork checklist
When adapting the reference strategy:- Keep the three-way lookup above. Only an explicit “gone” may clear a mapping.
- Enforce vault-side inflation guards before trusting
depositreturn values. - Extend TTL for the strategy instance and the vault-mapping keys.
- Cover deposit, balance, and withdraw round trips; third-party payout; interest accrual with no index maintenance; and account recreation after a full exit.
- Keep one WASM per asset. Do not share a strategy instance across underlyings.
Next
Vault integrations
Generic vault integration model, lifecycle rules, and auth patterns.
Supply and borrow
Underlying controller supply and withdraw semantics.
Interest and revenue
How supply indexes accrue and how
price_per_share tracks yield.Controller ABI
supply, withdraw, and get_collateral_amount signatures.
