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

# Testnet: Aave (Base Sepolia)

> Test the full lend / withdraw integration end-to-end on the Base Sepolia testnet using the Aave strategy and faucet USDC

This strategy is a standard **DeFi lending position** (`protocol: "Aave"`, `network: base-sepolia`)
running entirely on the **Base Sepolia testnet** (chain `84532`). Use it to integrate and test the
Pods lend / withdraw flow end-to-end **before** pointing your client at a mainnet Aave strategy.

You lend faucet USDC into the Aave v3 pool and receive an interest-bearing aToken position;
withdrawing redeems it back to USDC. Everything is **same-chain and synchronous** — there is no
bridge leg and no async order fill.

<Info>
  **Testnet only.** Funds have no real value. USD / TVL figures for this strategy are **not**
  meaningful — the faucet USDC has no price feed. Drive your test assertions off raw underlying
  balances and the on-chain aToken balance, not USD values.
</Info>

## Overview

| Item                 | Value                                                                            |
| -------------------- | -------------------------------------------------------------------------------- |
| **Strategy ID**      | `aave-aBasSepUSDC-base-sepolia`                                                  |
| **Protocol**         | `Aave`                                                                           |
| **Network**          | Base Sepolia (`84532`)                                                           |
| **Strategy asset**   | `aBasSepUSDC` aToken — `0x10F1A9D11CDf50041f3f8cB7191CBE2f31750ACC` (6 decimals) |
| **Underlying asset** | Faucet USDC — `0xba50Cd2A20f6DA35D788639E581bca8d0B5d4D5f` (6 decimals)          |
| **Actions**          | `lend` (deposit) / `withdraw` (redeem)                                           |
| **Settlement**       | Synchronous, single chain (no bridge, no async fill)                             |

```
Lend:     USDC (Base Sepolia)  → [client signs on Base Sepolia] → aBasSepUSDC shares
Withdraw: aBasSepUSDC shares    → [client signs on Base Sepolia] → USDC (Base Sepolia)

Position: queried with the wallet on Base Sepolia
```

<Info>
  `GET /strategies/:id/bytecode` returns `bytecode[]` (to execute on-chain) plus tracking fields
  (`id`, `feeCharged`, `chainIdIn`, `chainIdOut`, `crossChain`). For a direct same-chain
  lend/withdraw the `quote` field is **`null`** — it is only populated when an extra swap or bridge
  leg is involved. aTokens are **1:1** with the underlying at any instant — 1 USDC lent ≈ 1
  aBasSepUSDC share.
</Info>

## Initial setup

Before your first request, the signing wallet must be funded **on Base Sepolia**:

<Steps>
  <Step title="Have funds of the underlying asset (faucet USDC)">
    There is no point buying it — it has no value. **Mint it from the Aave faucet** (see
    [Get the faucet](#1-get-the-faucet-usdc) below).
  </Step>

  <Step title="Have Base Sepolia ETH for gas">
    Your wallet signs and broadcasts the `lend` / `withdraw` transaction, so it needs native ETH to
    pay gas. Grab some from any Base Sepolia faucet.
  </Step>

  <Step title="Have a Pods API key">
    Every request is authenticated with the `x-api-key` header. See
    [Authentication](/getting-started/authentication).
  </Step>
</Steps>

Once the wallet holds faucet USDC **and** a little Base Sepolia ETH, you can run the full lend →
position → withdraw cycle.

## 1. Get the faucet (USDC)

The underlying is a **mock USDC** deployed by Aave for Base Sepolia. You acquire it by minting from
the Aave testnet faucet — you cannot buy it and it carries no value.

| Token       | Address                                      | Decimals | Chain   |
| ----------- | -------------------------------------------- | -------- | ------- |
| Faucet USDC | `0xba50Cd2A20f6DA35D788639E581bca8d0B5d4D5f` | 6        | `84532` |
| aBasSepUSDC | `0x10F1A9D11CDf50041f3f8cB7191CBE2f31750ACC` | 6        | `84532` |

<Info>
  You only ever mint **USDC** (the underlying). The `aBasSepUSDC` aToken is minted **by the Aave
  pool** when you `lend` — never mint or transfer it directly.
</Info>

### Option A — Aave faucet UI (recommended)

<Steps>
  <Step title="Open the Aave faucet">
    Go to [app.aave.com/faucet](https://app.aave.com/faucet/).
  </Step>

  <Step title="Select Base Sepolia">
    Switch the network selector to **testnet** mode and pick **Base Sepolia**.
  </Step>

  <Step title="Connect your wallet">
    Connect the wallet you will use to sign Pods transactions.
  </Step>

  <Step title="Mint USDC">
    Click **Faucet** on **USDC** — it mints a fixed batch of test USDC to your wallet (repeatable).
    Confirm the transaction.
  </Step>
</Steps>

After it confirms, the faucet USDC (`0xba50Cd2A20f6DA35D788639E581bca8d0B5d4D5f`) shows up in your
wallet balance. Import the token address if it doesn't appear automatically.

### Option B — mint directly via BaseScan

The Aave faucet is an on-chain contract; you can mint without the UI:

<Steps>
  <Step title="Find the Faucet address">
    Get the **Faucet** address for the Aave v3 Base Sepolia market from the Aave
    [`address-book`](https://github.com/bgd-labs/aave-address-book) (testnet markets), or read it
    from the Aave UI transaction in Option A.
  </Step>

  <Step title="Open the contract on BaseScan">
    Open it on [sepolia.basescan.org](https://sepolia.basescan.org) →
    **Contract → Write Contract → Connect**.
  </Step>

  <Step title="Call mint">
    Call `mint(address token, address to, uint256 amount)` with `token` = the faucet USDC,
    `to` = your wallet, `amount` = base units (6 decimals — `100000000` = 100 USDC).
  </Step>
</Steps>

### Base Sepolia ETH for gas

You also need a small amount of native ETH on Base Sepolia to pay gas. A fraction of an ETH covers
many test transactions. Public faucets (these are the ones we used):

* [Alchemy — Base Sepolia faucet](https://www.alchemy.com/faucets/base-sepolia)
* [Chainlink — Base Sepolia faucet](https://faucets.chain.link/base-sepolia)
* Coinbase Developer Platform / QuickNode Base Sepolia faucets
* Or bridge Sepolia ETH → Base Sepolia via the official Base bridge

<Info>
  These faucets dispense **ETH for gas**, not USDC. Get the underlying USDC from the Aave faucet
  ([Option A](#option-a-aave-faucet-ui-recommended) / [Option B](#option-b-mint-directly-via-basescan)) above.
</Info>

## 2. Integration flow

```
LEND (deposit)                              WITHDRAW (redeem)
──────────────                              ─────────────────
1. GET /v2/strategies?protocol=Aave&network=base-sepolia  → strategyId   (same)
2. Confirm wallet has faucet USDC + ETH     Confirm wallet holds the position
3. GET /strategies/:id/bytecode             GET /strategies/:id/bytecode
     action=lend                              action=withdraw
     amount=<usdcBaseUnits>                    amount=<usdcBaseUnits>
     wallet=<address>                          wallet=<address>
4. Review feeCharged / amounts               Review feeCharged / amounts
5. Sign & broadcast bytecode[] on Base Sepolia (1 tx, synchronous)  (same)
6. Wait for the on-chain receipt             (same)
7. Refresh position                          (same)
```

## 3. Resolve the strategy ID

The strategy ID is fixed (`aave-aBasSepUSDC-base-sepolia`), but you can also discover it:

```http theme={null}
GET /v2/strategies?protocol=Aave&network=base-sepolia
```

Returns `{ data: [...], pagination }`. Pick the strategy where `asset` matches the aToken
(`0x10F1A9D11CDf50041f3f8cB7191CBE2f31750ACC`) and `networkId === 84532`. Use actions `lend` and
`withdraw` from `availableActions`.

## 4. Lend — `lend`

```http theme={null}
GET /strategies/:strategyId/bytecode
```

| Parameter | Required | Description                                                            |
| --------- | -------- | ---------------------------------------------------------------------- |
| `action`  | yes      | `lend`                                                                 |
| `wallet`  | yes      | Address that signs on Base Sepolia and holds the position              |
| `amount`  | yes      | Faucet USDC in **base units** (6 decimals — `1000000` = 1 USDC)        |
| `output`  | no       | `bytecode` (default) / `userOperation` / `fireblocks` / `instructions` |

**Example request:**

```http theme={null}
GET /strategies/aave-aBasSepUSDC-base-sepolia/bytecode?action=lend&amount=10000000&wallet=0x1234...
```

**Example response:**

```jsonc theme={null}
{
  "feeCharged": "0",                 // entry fee deducted from the deposit, in USDC base units
  "chainIdIn": 84532,
  "chainIdOut": 84532,
  "id": "65f3a1c8e9b2d4f8a7c1d2e3", // action id (record-keeping; queryable via GET /actions/:id)
  "crossChain": { "isCrossChain": false, "chainIdIn": 84532, "chainIdOut": 84532 },
  "quote": null,                     // null for a direct same-chain lend
  "bytecode": [
    // typically: entry-fee transfer (if any) → ERC20 approve(USDC, AavePool) → AavePool.supply → tracking
    { "to": "0x…", "value": "0", "data": "0x…", "chainId": 84532 }
  ]
}
```

All `bytecode` legs are on `chainId 84532` (Base Sepolia). Sign and broadcast them on Base Sepolia;
the position is live as soon as the transaction confirms.

<Info>
  An **entry fee** may be deducted from the deposited amount (configured per customer). The amount
  charged is reported in the top-level `feeCharged` field, and the aToken shares you receive
  correspond to the amount **after** the fee.
</Info>

## 5. Withdraw — `withdraw`

```http theme={null}
GET /strategies/:strategyId/bytecode
```

| Parameter | Required | Description                                                            |
| --------- | -------- | ---------------------------------------------------------------------- |
| `action`  | yes      | `withdraw`                                                             |
| `wallet`  | yes      | Address on Base Sepolia that holds the position                        |
| `amount`  | yes      | Underlying USDC to redeem, in **base units** (6 decimals)              |
| `output`  | no       | `bytecode` (default) / `userOperation` / `fireblocks` / `instructions` |

Because aTokens are 1:1 with the underlying, `amount` is denominated in **USDC base units** (not a
separate share unit). To exit the full position, use the current position value (see
[Position](#6-position)). The response shape matches lend (`feeCharged`, `chainIdIn`, `chainIdOut`,
`id`, `crossChain`, `quote: null`, `bytecode`); all legs are on `chainId 84532`.

<Info>
  A **performance fee** may be charged on profit at withdraw time and transferred out as part of the
  bytecode — the redeemed amount reflects the amount after that fee.
</Info>

## 6. Position

The `wallet` is the same EVM address used for signing (always on Base Sepolia for this strategy).
Pass `wallet` to get position fields; omit it to get only APY fields.

**Single strategy position:**

```http theme={null}
GET /v2/strategies/:strategyId?wallet=<address>
```

or `GET /v2/wallets/:address/strategies/:strategyId` (same shape).

**Wallet snapshot (all positions):** `GET /v2/wallets/:address?include=all` — Aave positions appear
under `earn.positions` where `strategy.protocol === "Aave"`.

**Position shape (with `wallet`).** Balance fields are `AssetAmount` objects
(`{ value, decimals, symbol, displaySymbol }`), where `value` is the raw integer string:

```jsonc theme={null}
{
  "spotPosition": {
    "currentPosition":   { "value": "<raw>", "decimals": 6, "symbol": "USDC", "displaySymbol": "USDC" },
    "principal":         { "value": "<raw>", "decimals": 6, "symbol": "USDC", "displaySymbol": "USDC" },
    "profit":            { "value": "<raw>", "decimals": 6, "symbol": "USDC", "displaySymbol": "USDC" },
    "cumulativeProfit":  { "value": "<raw>", "decimals": 6, "symbol": "USDC", "displaySymbol": "USDC" },
    "profitInUSD": 0,            // null/0 on testnet — no USDC price feed
    "underlyingBalanceUSD": 0,   // null/0 on testnet — no USDC price feed
    "apy": 0.0,                  // net APY (after performance fee)
    "grossAPY": 0.0,
    "netAPY": 0.0,
    "apyAfterFees": 0.0,
    "inceptionApy": 0.0,
    "avgApy": 0.0,
    "performanceFee": "<raw>"    // optional
  },
  "strategy": {
    "protocol": "Aave",
    "id": "aave-aBasSepUSDC-base-sepolia",
    "asset": "0x10F1A9D11CDf50041f3f8cB7191CBE2f31750ACC",
    "networkId": 84532
  }
}
```

Without `wallet`, `spotPosition` contains only `apy`, `grossAPY`, `netAPY`, `inceptionApy`, `avgApy`
(and optionally `performanceFee`) — no balance fields.

<Warning>
  `underlyingBalanceUSD`, `profitInUSD` and any TVL/USD figure are **not meaningful** on testnet —
  the mock USDC has no USD rate. Assert on `currentPosition.value` (raw underlying) and the on-chain
  aToken balance.
</Warning>

## 7. Track the transaction

Settlement is **synchronous**: once the Base Sepolia transaction confirms, the lend / withdraw is
complete — there is no separate async order to await.

* Wait for the on-chain receipt (`status === 1`) on `chainId 84532`.
* Refresh the position endpoints after confirmation.
* History is available via `GET /wallets/:wallet/history/:strategyId`. Ignore `INITIAL` status
  (a quote artifact). Optionally subscribe to `wss://<api-host>/updates` and the wallet channel for
  `action_update` events.

## 8. Network & addresses

| Item                     | Value                                                        |
| ------------------------ | ------------------------------------------------------------ |
| Network                  | Base Sepolia                                                 |
| Chain ID                 | `84532`                                                      |
| Explorer                 | [https://sepolia.basescan.org](https://sepolia.basescan.org) |
| Native gas asset         | ETH                                                          |
| Aave Pool                | `0x8bAB6d1b75f19e9eD9fCe8b9BD338844fF79aE27`                 |
| Aave DataProvider        | `0x3cB7B00B6C09B71998124196691e8bF2694De863`                 |
| Faucet USDC (underlying) | `0xba50Cd2A20f6DA35D788639E581bca8d0B5d4D5f` (6 decimals)    |
| aBasSepUSDC (aToken)     | `0x10F1A9D11CDf50041f3f8cB7191CBE2f31750ACC` (6 decimals)    |

## 9. End-to-end testnet run

A full smoke test from a clean wallet:

<Steps>
  <Step title="Fund the wallet">
    Mint faucet USDC (§1) and grab a little Base Sepolia ETH for gas. Verify both balances on
    BaseScan.
  </Step>

  <Step title="Resolve the strategy">
    Confirm `availableActions` includes `lend` and `withdraw` (§3).
  </Step>

  <Step title="Lend a small amount (e.g. 10 USDC)">
    ```bash theme={null}
    curl -H "x-api-key: $API_KEY" \
      "https://api.pods.finance/strategies/aave-aBasSepUSDC-base-sepolia/bytecode\
    ?action=lend&amount=10000000&wallet=0xYOUR_WALLET"
    ```

    Sign every `bytecode` leg (`chainId 84532`) on Base Sepolia.
  </Step>

  <Step title="Confirm the position">
    `currentPosition.value` should reflect ≈ 10 USDC in base units (minus entry fee, if configured):

    ```bash theme={null}
    curl -H "x-api-key: $API_KEY" \
      "https://api.pods.finance/v2/strategies/aave-aBasSepUSDC-base-sepolia?wallet=0xYOUR_WALLET"
    ```
  </Step>

  <Step title="Withdraw">
    ```bash theme={null}
    curl -H "x-api-key: $API_KEY" \
      "https://api.pods.finance/strategies/aave-aBasSepUSDC-base-sepolia/bytecode\
    ?action=withdraw&amount=10000000&wallet=0xYOUR_WALLET"
    ```

    Sign the `bytecode` on Base Sepolia.
  </Step>

  <Step title="Confirm the exit">
    Refresh the position — `currentPosition.value` drops back toward 0 and the USDC returns to the
    wallet (minus any performance fee).
  </Step>
</Steps>

<Tip>
  Keep amounts small, re-run the faucet whenever you run low, and assert on **raw underlying**
  balances / on-chain aToken balance rather than USD values (no testnet price feed).
</Tip>

## 10. Errors

The amount-specific errors (`LEND_AMOUNT_TOO_SMALL`, `WITHDRAW_AMOUNT_TOO_SMALL`,
`WITHDRAW_AMOUNT_REQUIRED`, `REQUEST_LEND_AMOUNT_TOO_LOW`) are **Ondo-stock specific** and do **not**
apply to this Aave strategy. The ones you can actually hit here:

| Code                             | HTTP | When                                                                            |
| -------------------------------- | ---- | ------------------------------------------------------------------------------- |
| `NO_API_KEY` / `INVALID_API_KEY` | 401  | Missing or invalid `x-api-key`                                                  |
| `QUOTE_NOT_FOUND`                | 404  | Quote no longer available — re-request the bytecode                             |
| `QUOTE_EXPIRED`                  | 400  | Quote expired — re-request the bytecode                                         |
| `BYTECODE_GENERATION_FAILED`     | 500  | Bytecode could not be built (e.g. wallet has no USDC / no position to withdraw) |
| `INTERNAL_SERVER_ERROR`          | 500  | Unexpected server error                                                         |

There is **no** dedicated insufficient-balance error code: lending more USDC than the wallet holds
(or withdrawing more than the position) surfaces as `BYTECODE_GENERATION_FAILED`, or the on-chain
transaction reverts. See [Error Codes](/error-codes) for the full list, and preserve `error.code`
in your UI for user-friendly messages.

## Integration notes

1. **Use the generic actions:** `lend` (deposit) and `withdraw` (redeem). There is **no**
   `request-lend` / `request-withdraw` here — settlement is synchronous and same-chain.
2. **Sign on Base Sepolia (`84532`)** for every leg; the position lives on the same wallet/chain.
3. **Amounts are in USDC base units (6 decimals)** for both lend and withdraw — aTokens are 1:1 with
   the underlying, so there is no separate share unit to convert.
4. **Fees:** an entry fee may reduce the lent amount (reported as top-level `feeCharged`); a
   performance fee may be taken on profit at withdraw.
5. **Testnet caveats:** USD / TVL values are unreliable (no price feed) — assert on raw balances.
6. **Smart accounts:** pass `output=userOperation`, or `output=fireblocks` with `accountId`.

## Next Steps

<CardGroup cols={2}>
  <Card title="Deposit to Yield" icon="arrow-up-right" href="/guides/yield/deposit">
    The full deposit reference (same-chain & cross-chain) for mainnet strategies
  </Card>

  <Card title="Check Positions" icon="chart-line" href="/guides/yield/check-positions">
    Monitor your open yield positions
  </Card>
</CardGroup>
