Skip to main content
This guide provides solutions and explanations for common issues encountered when using the DeFindex protocol. It covers API errors, environment setup, contract error codes, transaction failures, and frequently asked questions.

Table of Contents

API

API Error Reference

HTTP status codes returned by the DeFindex API:

API Rate Limits

The DeFindex API uses a rate limiter with a 5 minute window. Limits are applied per API key (authenticated requests) or per IP address (unauthenticated requests).

Rate Limit Tiers

Contact PaltaLabs🥑 team on discord to upgrade tier.

Response Headers

Every API response includes rate limit headers:
Tip: Use the GET /rate-limits/tiers endpoint to retrieve the current rate limit configuration for your API key.

Handling 429 Responses

When you exceed the rate limit, the API returns 429 (Too Many Requests). Use exponential backoff to handle this:
Usage example:

Environment & Configuration

Step-by-Step Debugging Guide

1. Check Environment Variables

  • Ensure all required environment variables (e.g., MAINNET_RPC_URL) are set correctly.
  • Example (.env):

2. Validate Network and Contract Deployment

  • Confirm you are connected to the correct network (testnet/mainnet).
  • Verify the contract address is correct and the contract is deployed.

3. Simulate Transactions Before Sending

  • Use the SDK’s simulation methods to check for errors before submitting transactions.
  • Review simulation results for error codes or failed preconditions.

4. Handle Transaction Failures

  • If a transaction fails, inspect the error code returned.
  • Refer to the tables in this page to interpret the error and apply the suggested fix.

5. Check Parameter Types and Lengths

  • Ensure all parameters (amounts, addresses, etc.) are of the correct type and length.
  • For multi-asset vaults, input arrays must match the number of assets.

6. Review Contract and SDK Versions

  • Make sure you are using compatible versions of the SDK and smart contracts.

7. Debug XDR manually

Smart Contracts

Error Log Debbugging Example

Consider the following error log from a withdraw transaction:
Breakdown:
  1. Identify the Error:
    • Events 0 and 1 indicate the error: Error(Contract, #160).
    • Error code: 160 (InsufficientOutputAmount)
  2. Understand the Context:
    • Event 0: The contract explicitly triggered an error.
    • Event 1: Confirms the contract error code is 160.
  3. Determine Function Arguments:
    • Event 11 shows the withdraw function call and its arguments:
      • 9999563: withdraw_shares (number of shares to burn)
      • [10000065]: min_amounts_out (minimum expected output amount)
      • GBI6SIGPSKXTBLXGSAFT2TN5DYFBHIJXKO7IGGQTR7DKO2ANWILGXIDA: to (recipient address)
  4. Interpret the Error in Context:
    • The withdraw transaction failed because the vault could not provide at least 10000065 stroops of the underlying asset when burning 9999563 shares.

Common Contract Errors

The DeFindex contracts return specific error codes when a transaction fails. Below is a comprehensive reference grouped by contract and category.

Vault Errors

Initialization Errors (100–108)

Validation Errors (110–129)

Arithmetic Errors (120–127)

Authorization Errors (130–131)

Strategy Operation Errors (140–144)

Asset Errors (150–151)

Input Errors (160–162)

External / Swap Errors (190–202)

Factory Errors

Strategy Errors

Validation Errors (401–418)

Protocol Errors (420–423)

Blend Strategy Errors (451–455)

Deposit with invest: true stays idle

Symptom

You deposit with invest: true (the API default), the transaction succeeds, but the funds show up under idle_amount in fetch_total_managed_funds and invested_amount stays at 0. No error is returned and no Invest event is emitted.

Why Does This Happen?

invest does not pick a strategy. It tells the vault to split the deposit across its strategies in the same proportion as the funds already invested. On a vault that has never invested anything, that proportion is empty, so the contract skips the asset and keeps the deposit idle. It is the first deposit of every new vault, by design. You will hit it when:
  • The vault was created from the Console with Deposit on creation off, or with Auto-invest deposited funds off.
  • The vault was created with POST /factory/create-vault or POST /factory/create-vault-deposit and the first rebalance was never run.
  • Every strategy was unwound to zero (for example after a rescue), so there is no allocation left to follow.

Fix: One Invest Rebalance

The Manager or the Rebalance Manager (Vault Roles) runs rebalance once, with one Invest instruction per strategy for the idle amount. Three ways to do it:
  • Console: open the vault, go to the Admin tab, add a Rebalance instruction of type Invest with the strategy and the amount in stroops, and sign with the manager wallet.
  • API: POST /vault/{vaultAddress}/rebalance with { "caller": "<MANAGER_OR_REBALANCE_MANAGER>", "instructions": [{ "type": "Invest", "strategy_address": "<STRATEGY_ADDRESS>", "amount": <IDLE_AMOUNT_IN_STROOPS> }] }, then sign and send the XDR. See Vault Administration.
  • stellar-cli: rebalance --caller <MANAGER> --instructions '[{"Invest":["<STRATEGY_ADDRESS>", "<IDLE_AMOUNT_IN_STROOPS>"]}]', as in Step 5 of Creating a Vault.
Once the vault holds an allocation, every later deposit with invest: true is invested automatically in that proportion. If you created several vaults at once, each one needs its own first Invest.

Withdrawing All — Dust Left Behind

Why Does This Happen?

When withdrawing all shares, a tiny residual balance (typically 1–3 stroops per asset) may remain. This is by design, not a bug. The vault calculates each asset’s withdrawal amount using integer floor division:
Since Soroban uses integer arithmetic (no decimals), the division truncates any fractional stroop. In multi-asset vaults, this truncation can happen once per asset per division step, compounding to a few stroops total. This behavior is intentional: it prevents the vault from ever paying out more than it holds.

How Much Dust?

Typically 1–3 stroops per asset (1 stroop = 0.0000001 XLM or the smallest unit of a Soroban token). This is economically negligible.

Workaround: Two-Step Withdraw

If you need to recover the dust, use a two-step approach:

Soroban Transaction Errors

These are Stellar/Soroban transaction-level errors that occur before or outside of contract execution. They appear in the transaction result rather than in contract event logs.

Frequently Asked Questions (FAQ)

Q: My transaction fails with WrongAmountsLength (112). What does this mean?
  • A: The number of amounts you provided does not match the number of assets in the vault. Double-check your input arrays.
Q: What should I do if I get InsufficientOutputAmount (160)?
  • A: The vault could not provide the minimum output you requested. Try lowering your minimums or check if the vault has enough liquidity.
Q: How do I know which error code was returned?
  • A: Inspect the transaction response object. The error code will be included in the failure reason or logs.
Q: How can I debug contract errors further?
  • A: Review the contract’s error.rs file for detailed error definitions. Use simulation and logging to narrow down the cause.
Q: Are there any environment setup issues I should be aware of?
  • A: Yes. Ensure all required environment variables are set, dependencies are installed, and you are using the correct network and contract addresses.
Q: When I withdraw a specific amount, why might I receive slightly more than requested?
  • A: Due to the fluctuating ratio between the underlying asset and vault shares (caused by Blend strategy gains) and the Soroban contract’s handling of the smallest asset unit (“stroop”), the contract uses ceiling division to calculate the shares to burn. This ensures you receive at least the requested amount, but it can sometimes result in a slightly higher output. The contract prioritizes fulfilling the minimum withdrawal amount.
Q: When I deposit a specific amount, will I always receive the same number of shares?
  • A: No. Similar to withdrawals, the number of shares you receive when depositing a fixed amount of the underlying asset can vary. This is because the ratio between the asset and shares changes constantly. A deposit made moments apart can yield slightly different share amounts.
Q: I deposited with invest: true but the funds are idle. Is the flag ignored?
  • A: No. invest follows the vault’s current allocation, and a vault that has never invested has none, so the first deposit stays idle. The manager runs one Invest rebalance and later deposits invest on their own. See Deposit with invest: true stays idle.
Q: I withdrew all my shares but still have a tiny balance (1–3 stroops). Is this a bug?

Additional Resources

If you encounter an issue not covered here, please open an issue on the project’s GitHub repository.