> ## Documentation Index
> Fetch the complete documentation index at: https://xoxno.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Stellar lending DeFindex strategy

> The open-source DeFindex vault adapter: one WASM per asset, one controller account per vault, and the DeFindexStrategyTrait API.

The `defindex-strategy` contract is a reference vault adapter in `contracts/defindex-strategy/`. 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_id` per vault.** Vaults never share a lending account.
* **Strategy is the caller** on all controller mutations (`supply`, `withdraw`).

Constructor:

```rust theme={"system"}
__constructor(asset: Address, init_args: Vec<Address>)
// init_args[0] = controller address
// Validates market is listed; stores {asset, controller, pool}
```

## Trait API

| Entrypoint                   | Auth                  | Returns   | Behavior                                                       |
| ---------------------------- | --------------------- | --------- | -------------------------------------------------------------- |
| `asset()`                    | —                     | `Address` | Configured underlying asset                                    |
| `deposit(amount, from)`      | `from.require_auth()` | `i128`    | Pull tokens, supply to controller, return post-deposit balance |
| `balance(from)`              | —                     | `i128`    | `collateral_amount_for_token(account_id, asset)`               |
| `withdraw(amount, from, to)` | `from.require_auth()` | `i128`    | Withdraw to `to`; `amount = 0` closes the full position        |
| `harvest(from, data)`        | —                     | —         | Emits `HarvestEvent` with 12-decimal `price_per_share`         |
| `lending_account_id(vault)`  | —                     | `u64`     | Live controller account id (reconciles stale mapping)          |
| `has_lending_account(vault)` | —                     | `bool`    | Whether the vault has a live account                           |

## Deposit flow

```text theme={"system"}
from (vault) --auth--> deposit(amount)
  1. transfer(from → strategy, amount)
  2. prepare_vault_account_for_supply()     // clears stale mapping before auth
  3. authorize_as_current_contract(transfer(strategy → pool, amount))
  4. controller.supply(strategy, stored_id_or_0, spoke_id, [(hub_asset, amount)])
  5. persist new account_id in VaultAccount(vault)
  6. return collateral_amount_for_token(account_id, asset)
```

`prepare_vault_account_for_supply` may call `controller.account_exists` before `authorize_as_current_contract`. If auth were emitted first, re-deposit after a full withdraw would fail with `Auth InvalidAction`.

## Withdraw flow

```text theme={"system"}
from (vault) --auth--> withdraw(amount, from, to)
  1. reconcile vault → account_id (0 → InsufficientBalance)
  2. balance = collateral_amount_for_token(account_id, asset)
  3. reject if amount > balance (strategy-level check; stricter than controller clamp)
  4. if amount == balance → withdraw_amount = 0 (full close sentinel)
  5. controller.withdraw(strategy, account_id, [(asset, withdraw_amount)], Some(to))
  6. return remaining collateral (0 if account deleted)
```

Withdraw pays `to` directly from the pool. No pre-authorization is required on the strategy side.

## Harvest and price per share

`harvest` emits a 12-decimal `price_per_share` derived from the market supply index:

```text theme={"system"}
price_per_share = supply_index_ray / (RAY / 1_000_000_000_000)
```

The value is market-wide (from `supply_index_ray`), not per-vault. `harvest` makes no on-chain state change; DeFindex vaults use the event for share accounting.

## Controller integration

| Concern       | Implementation                                                                |
| ------------- | ----------------------------------------------------------------------------- |
| Balance reads | `collateral_amount_for_token` — oracle-free, accrues to now                   |
| Supply auth   | Pre-authorize `transfer(strategy → pool)`                                     |
| Withdraw auth | None; pool pays recipient directly                                            |
| Pool address  | Resolved at init via `controller.get_pool_address()`                          |
| Stale mapping | Cleared on supply after full withdraw; read paths return `0` until re-deposit |

## Auth recipe

Supply requires the strategy to authorize its own token transfer to the pool before calling `controller.supply`:

```rust theme={"system"}
env.authorize_as_current_contract(vec![
    &env,
    InvokerContractArgs {
        contract: pool_address,
        fn_name: "transfer",
        args: (strategy_address, pool_address, amount).into_val(&env),
    },
]);
```

Withdraw does not need a pre-authorization; the pool transfers to `to` on the controller's behalf.

## Strategy errors

| Code | Error                 |
| ---- | --------------------- |
| 401  | `NotInitialized`      |
| 460  | `AmountNotPositive`   |
| 461  | `InsufficientBalance` |
| 462  | `ArithmeticError`     |

## Fork checklist

When adapting the reference strategy:

* Enforce vault-side inflation guards before trusting `deposit` return values.
* Extend TTL for strategy instance and vault-mapping keys.
* Run the integration test matrix in `contracts/defindex-strategy/tests/`.
* Keep one WASM per asset; do not share strategy instances across underlyings.

## Next

<CardGroup cols={2}>
  <Card title="Vault integrations" icon="plug" href="/stellar-lending/dev/vault-integrations">
    Generic vault integration model, lifecycle rules, and auth patterns.
  </Card>

  <Card title="Supply and borrow" icon="arrow-right-arrow-left" href="/stellar-lending/dev/supply-and-borrow">
    Underlying controller supply and withdraw semantics.
  </Card>

  <Card title="Interest and revenue" icon="chart-line" href="/stellar-lending/dev/interest-and-revenue">
    How supply indexes accrue and how `price_per_share` tracks yield.
  </Card>

  <Card title="Controller ABI" icon="code" href="/stellar-lending/dev/controller-abi">
    `supply`, `withdraw`, and `collateral_amount_for_token` signatures.
  </Card>
</CardGroup>
