Skip to content

EarnPool — Withdraw

Overview

The Trader retrieves USDC from an enabled EarnPool back to KPortfolio. This may be triggered manually for rebalancing, or automatically by the vault when user redemptions require liquidity replenishment.

Access Control

Trader role for manual withdrawals. Vault contract may also trigger via onVaultWithdraw for user redemptions.


Flow

sequenceDiagram
    actor Tr as Trader
    participant Port as KPortfolio
    participant Pool as EarnPool
    participant Proto as Underlying Protocol

    Tr->>Port: withdrawPool(poolAddress, amount)
    Port->>Pool: withdraw(amount)
    Pool->>Proto: withdraw/redeem USDC
    Proto-->>Pool: USDC returned
    Pool-->>Port: USDC transferred
    Port-->>Tr: Success

Automatic Replenishment (User Withdrawal)

When a user calls redeem() and the vault's idle cash is insufficient:

sequenceDiagram
    participant Vault as KingsVault
    participant Port as KPortfolio
    participant Pool as EarnPool (preferred)
    participant Pool2 as EarnPool (fallback)

    Vault->>Port: onVaultWithdraw(shortage)
    Port->>Pool: withdraw(shortage)
    alt Pool has sufficient balance
        Pool-->>Port: USDC returned
    else Insufficient in primary pool
        Pool-->>Port: partial amount
        Port->>Pool2: withdraw(remaining)
        Pool2-->>Port: USDC returned
    end
    Port-->>Vault: USDC consolidated

The system prioritizes a single preferred pool, then falls back to other enabled pools if needed.


Preconditions

Condition Enforcement
Pool is enabled Pool must be in activePools whitelist.
Pool has sufficient balance pool.valuesOf() >= amount
Caller has Trader role (manual) AccessControl modifier
Caller is Vault contract (auto) onlyVault modifier for onVaultWithdraw

Security Considerations

  1. Slippage: Withdrawing from protocols like Morpho or Aave during high-utilization periods may incur slippage or be temporarily blocked.
  2. Cascading Failures: If a primary pool is paused (e.g., Aave governance pause), the fallback mechanism must handle the failure gracefully without reverting the entire withdrawal.
  3. Friction Costs: frictionCosts() on KPortfolio estimates the cost of unwinding positions, which should be factored into NAV calculations.