> ## Documentation Index
> Fetch the complete documentation index at: https://litprotocol-vincent.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Morpho

The Morpho Ability enables Vincent Apps to interact with Morpho lending vaults on behalf of Vincent Users. This allows Vincent Apps to provide yield-generating DeFi functionality through Morpho's lending markets, including depositing assets to earn yield, withdrawing funds, and managing vault positions.

## Key Features

* **Yield Vault Operations**: Supports deposit, withdraw, and redeem operations with Morpho's ERC-4626 compliant vaults using Vincent Wallets within a secure Trusted Execution Environment
* **Multi-Chain Support**: Works across multiple networks where Morpho vaults are deployed including Ethereum, Base, Arbitrum, Optimism, and Polygon
* **Comprehensive Vault Discovery**: Utilizes the Morpho Vault API to discover and filter vaults by asset, chain, APY, TVL, and other criteria
* **Gas Sponsorship**: Optional integration with Alchemy's gas sponsorship for gasless transactions via EIP-7702

## How It Works

The Morpho Ability is built using the Vincent Ability SDK and operates in two phases:

<Steps>
  <Step title="Precheck Phase">
    Validates all prerequisites for the Morpho operation:

    * Validates operation type, vault address, and amount format
    * Verifies the vault exists using the built-in Morpho Vault client and retrieves asset information
    * For deposits, checks the Vincent App User's Vincent Wallet's token balance and allowance
    * For withdrawals/redeems, checks the Vincent App User's Vincent Wallet's has a vault share balance
    * For withdrawals, converts the requested asset amount to the required vault shares using ERC-4626 `convertToShares`
    * Estimates gas costs for the operation
    * Returns detailed validation results with current balance/shares
  </Step>

  <Step title="Execution Phase">
    Executes the Morpho vault operation:

    * Discovers and retrieves vault information using the Morpho Vault API, which enables filtering by asset, chain, APY, TVL, and more
    * Constructs the appropriate Morpho vault transaction using ERC-4626 standard methods
    * Signs and submits the transaction (with optional EIP-7702 Alchemy gas sponsorship)
    * Returns transaction hash and operation details
  </Step>
</Steps>

## Getting Started

Depending on your role in the Vincent Ecosystem, you'll be interacting with this Ability in different ways. Click on the link below that matches your role to see how to get started:

* **Vincent App Developers**: If you're building a Vincent App that needs to interact with Morpho vaults, go [here](#adding-the-ability-to-your-vincent-app).
* **Vincent App Delegatees**: If you're executing this ability on behalf of Vincent App Users, go [here](#executing-the-ability-as-a-vincent-app-delegatee).

## Adding the Ability to your Vincent App

If you want to enable your App Delegatees to perform Morpho vault operations on behalf of your Vincent App Users, you can add this Ability to your App.

Adding Abilities to your Vincent App is done using the [Vincent App Dashboard](https://dashboard.heyvincent.ai/). Visit the [Create Vincent App](/app/quickstart) guide to learn more about how to add Abilities to your App during creation, or check out the [Updating Your App](/app/updating-apps) guide to learn how to add Abilities to an existing App.

## Executing the Ability as a Vincent App Delegatee

Before executing Morpho vault operations, the following conditions must be met. You can use the Ability's `precheck` function to check if these conditions are met, or you can check them manually.

* **Native Token Balance for Gas Fees**: The Vincent App User's Vincent Wallet must have enough native tokens (ETH, MATIC, etc.) to cover the transaction gas fees for the Morpho operation.

* **ERC20 Token Approval**: For deposit operations, the Vincent App User's Vincent Wallet must have approved the Morpho vault contract to spend the underlying tokens.

<Info>
  To learn more about executing Vincent Abilities, see the [Executing Abilities](/ability/explaining-abilities) guide.
</Info>

<Note>
  If your Vincent App has enabled the [ERC20 Approval Ability](./erc20-approval), you can use it to handle submitting the approval transaction using the Vincent Wallet.
</Note>

### Operation-Specific Requirements

Each Morpho operation has specific validation requirements that are checked during the precheck phase:

<Tabs>
  <Tab title="Deposit">
    **Requirements for Deposit Operation:**

    * The Vincent App User's Vincent Wallet must have sufficient balance of the underlying token (e.g., USDC, WETH)
    * Morpho vault contract must be approved to spend the required token amount
    * Both balance and allowance must be greater than or equal to the deposit amount
  </Tab>

  <Tab title="Withdraw">
    **Requirements for Withdraw Operation:**

    * The Vincent App User's Vincent Wallet must have vault shares deposited in the Morpho vault
    * The Vincent Wallet must have sufficient vault shares to cover the withdrawal amount (converted from asset amount to shares)
    * The vault must have sufficient liquidity to fulfill the withdrawal
  </Tab>

  <Tab title="Redeem">
    **Requirements for Redeem Operation:**

    * The Vincent App User's Vincent Wallet must have vault shares in the specified Morpho vault
    * The Vincent Wallet must have sufficient vault share balance to cover the redeem amount
    * The vault must have sufficient underlying assets to exchange for the redeemed shares
  </Tab>
</Tabs>

### Executing the `precheck` Function

This Ability's `precheck` function validates all prerequisites for executing a Morpho vault operation and provides detailed account information.

<Tabs>
  <Tab title="Parameters">
    Before executing the `precheck` function, you'll need to provide the following parameters for the Morpho operation:

    ```typescript theme={null}
    {
      /**
       * The Morpho operation to perform (deposit, withdraw, redeem)
       */
      operation: 'deposit' | 'withdraw' | 'redeem';
      /**
       * The Morpho vault contract address
       */
      vaultAddress: string;
      /**
       * The amount to operate with, as a decimal string
       * For deposit/withdraw: amount of underlying asset (e.g., "100.5" for 100.5 USDC)
       * For redeem: amount of vault shares
       */
      amount: string;
      /**
       * The blockchain network to perform the operation on
       */
      chain: string;
      /**
       * Custom RPC URL (optional, for precheck only)
       */
      rpcUrl?: string;
      /**
       * Enable Alchemy gas sponsorship (optional)
       */
      alchemyGasSponsor?: boolean;
      /**
       * Alchemy API key (required if gas sponsorship enabled)
       */
      alchemyGasSponsorApiKey?: string;
      /**
       * Alchemy policy ID (required if gas sponsorship enabled)
       */
      alchemyGasSponsorPolicyId?: string;
    }
    ```
  </Tab>

  <Tab title="Implementation">
    To execute `precheck`, you'll need to:

    * Create an instance of the `VincentAbilityClient` using the `getVincentAbilityClient` function (imported from `@lit-protocol/vincent-app-sdk/abilityClient`)
      * Pass in the Ability's `bundledVincentAbility` object (imported from `@lit-protocol/vincent-ability-morpho`)
      * Pass in the `ethersSigner` you'll be using to sign the request to Lit with your Delegatee private key
    * Prepare the required parameters to call the `precheck` function
    * Use the `VincentAbilityClient` instance to call the `precheck` function

    ```typescript theme={null}
    import { getVincentAbilityClient } from '@lit-protocol/vincent-app-sdk/abilityClient';
    import { bundledVincentAbility } from '@lit-protocol/vincent-ability-morpho';

    // Create ability client
    const abilityClient = getVincentAbilityClient({
      bundledVincentAbility: bundledVincentAbility,
      ethersSigner: yourEthersSigner,
    });

    // Example: Deposit 100 USDC into a Morpho vault on Base
    const morphoParams = {
      operation: 'deposit' as const,
      vaultAddress: '0x...', // Morpho USDC vault address on Base
      amount: '100.0', // 100 USDC
      chain: 'base',
      rpcUrl: 'https://mainnet.base.org', // Optional for precheck
    };

    const precheckResult = await abilityClient.precheck(morphoParams, {
      delegatorPkpEthAddress: '0x...', // The Vincent App User's Vincent Wallet address
    });

    if (precheckResult.success) {
      const result = precheckResult.result;
      console.log('Operation valid:', result.operationValid);
      console.log('User balance:', result.userBalance);
      console.log('Current allowance:', result.allowance);
      console.log('Vault shares:', result.vaultShares);
      console.log('Estimated gas:', result.estimatedGas);
    } else {
      // Handle different types of failures
      if (precheckResult.runtimeError) {
        console.error('Runtime error:', precheckResult.runtimeError);
      }
      if (precheckResult.schemaValidationError) {
        console.error('Schema validation error:', precheckResult.schemaValidationError);
      }
      if (precheckResult.result) {
        console.error('Morpho precheck failed:', precheckResult.result.error);
      }
    }
    ```
  </Tab>

  <Tab title="Response">
    **Success Response**

    A successful `precheck` response will contain detailed validation information:

    ```typescript theme={null}
    {
      /**
       * Whether the requested operation is valid
       */
      operationValid: boolean;
      /**
       * Whether the specified vault address is valid
       */
      vaultValid: boolean;
      /**
       * Whether the specified amount is valid
       */
      amountValid: boolean;
      /**
       * The user's current balance of the vault's underlying asset (for deposits)
       */
      userBalance?: string;
      /**
       * The current allowance approved for the vault contract (for deposits)
       */
      allowance?: string;
      /**
       * The user's current vault share balance (for withdrawals/redeems)
       */
      vaultShares?: string;
      /**
       * Estimated gas cost for the operation
       */
      estimatedGas?: number;
    }
    ```

    **Failure Response**

    A failure `precheck` response will contain:

    ```typescript theme={null}
    {
      /**
       * A string containing the error message if the precheck failed
       */
      error: string;
    }
    ```
  </Tab>
</Tabs>

### Executing the `execute` Function

This Ability's `execute` function performs the actual Morpho vault operation.

<Tabs>
  <Tab title="Parameters">
    The `execute` function expects the same parameters as the `precheck` function (except `rpcUrl` which is not allowed):

    ```typescript theme={null}
    {
      /**
       * The Morpho operation to perform (deposit, withdraw, redeem)
       */
      operation: 'deposit' | 'withdraw' | 'redeem';
      /**
       * The Morpho vault contract address
       */
      vaultAddress: string;
      /**
       * The amount to operate with, as a decimal string
       * For deposit/withdraw: amount of underlying asset (e.g., "100.5" for 100.5 USDC)
       * For redeem: amount of vault shares
       */
      amount: string;
      /**
       * The blockchain network to perform the operation on
       */
      chain: string;
      /**
       * Enable Alchemy gas sponsorship (optional)
       */
      alchemyGasSponsor?: boolean;
      /**
       * Alchemy API key (required if gas sponsorship enabled)
       */
      alchemyGasSponsorApiKey?: string;
      /**
       * Alchemy policy ID (required if gas sponsorship enabled)
       */
      alchemyGasSponsorPolicyId?: string;
      // Note: rpcUrl is NOT allowed in execute
    }
    ```

    <Warning>
      The `rpcUrl` parameter is not allowed in the `execute` function for security reasons. Only the `chain` parameter should be used.
    </Warning>
  </Tab>

  <Tab title="Implementation">
    The `execute` function can be called using the same `VincentAbilityClient` instance:

    ```typescript theme={null}
    // Remove rpcUrl for execute - chain parameter is used instead
    const executeParams = {
      operation: 'deposit' as const,
      vaultAddress: '0x...', // Morpho USDC vault address on Base
      amount: '100.0', // 100 USDC
      chain: 'base',
      // Optional: Enable gas sponsorship
      alchemyGasSponsor: true,
      alchemyGasSponsorApiKey: 'YOUR_API_KEY',
      alchemyGasSponsorPolicyId: 'YOUR_POLICY_ID',
    };

    const executeResult = await abilityClient.execute(executeParams, {
      delegatorPkpEthAddress: '0x...', // The Vincent App User's Vincent Wallet address
    });

    if (executeResult.success) {
      const result = executeResult.result;

      console.log('Transaction hash:', result.txHash);
      console.log('Operation:', result.operation);
      console.log('Vault address:', result.vaultAddress);
      console.log('Amount:', result.amount);
      console.log('Timestamp:', result.timestamp);
    } else {
      // Handle different types of failures
      if (executeResult.runtimeError) {
        console.error('Runtime error:', executeResult.runtimeError);
      }
      if (executeResult.schemaValidationError) {
        console.error('Schema validation error:', executeResult.schemaValidationError);
      }
      if (executeResult.result) {
        console.error('Morpho execution failed:', executeResult.result.error);
      }
    }
    ```
  </Tab>

  <Tab title="Response">
    **Success Response**

    A successful `execute` response will contain:

    ```typescript theme={null}
    {
      /**
       * The transaction hash of the executed operation
       */
      txHash: string;
      /**
       * The type of Morpho operation that was executed
       */
      operation: 'deposit' | 'withdraw' | 'redeem';
      /**
       * The vault address involved in the operation
       */
      vaultAddress: string;
      /**
       * The amount of tokens/shares involved in the operation
       */
      amount: string;
      /**
       * The Unix timestamp when the operation was executed
       */
      timestamp: number;
    }
    ```

    **Failure Response**

    A failure `execute` response will contain:

    ```typescript theme={null}
    {
      /**
       * A string containing the error message if the execution failed
       */
      error: string;
    }
    ```
  </Tab>
</Tabs>

## Supported Networks

The Morpho Ability supports operations on the following networks where Morpho vaults are deployed:

| Network Type | Supported Chains |
| - | - |
| **Mainnets** | `ethereum`, `base`, `arbitrum`, `optimism`, `polygon` |
| **Testnets** | `sepolia` |

## Important Considerations

<AccordionGroup>
  <Accordion title="Amount Format" icon="calculator">
    The `amount` parameter should be specified in human-readable format (e.g., "100.5" for 100.5 tokens), not in wei or smallest units.
  </Accordion>

  <Accordion title="Vault Shares vs Underlying Assets" icon="coins">
    * For `deposit` and `withdraw`: Amount represents underlying assets (e.g., USDC)
    * For `redeem`: Amount represents vault shares
  </Accordion>

  <Accordion title="Gas Sponsorship" icon="gas-pump">
    When using Alchemy gas sponsorship:

    * Transactions are gasless for the Vincent App User's Vincent Wallet
    * Requires valid Alchemy API key and policy ID
    * Uses EIP-7702 for gasless transactions
  </Accordion>

  <Accordion title="Chain Parameter vs RPC URL" icon="link">
    * For `precheck`: You can provide either `chain` or `rpcUrl`
    * For `execute`: Only `chain` is allowed, `rpcUrl` will cause an error

    This is a security feature to prevent RPC URL injection attacks.
  </Accordion>
</AccordionGroup>

## Error Handling

<AccordionGroup>
  <Accordion title="Common Failure Scenarios" icon="bug">
    * **Insufficient Balance**: Not enough tokens for deposit or shares for withdrawal
    * **Missing Approval**: Token not approved for Morpho vault contract
    * **Invalid Vault**: Vault address doesn't exist or isn't a valid Morpho vault
    * **Invalid Chain**: Chain not supported or vault not deployed on that chain
    * **Gas Issues**: Insufficient native tokens for transaction gas fees
    * **Liquidity Issues**: Vault doesn't have sufficient liquidity for withdrawals
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.