What is Pathfinder?
Pathfinder is Blend’s cross-chain yield router - an ERC-4626 compatible vault system that makes multi-chain DeFi feel like single-chain DeFi. Pathfinder abstracts away every layer of cross-chain complexity so users can access yield opportunities across any chain while only interacting with a single liquid token (USDC, USDT, or USDe) on their home chain. In practice: Deposit USDC on Arbitrum and get exposure to SOL on Solana, wstETH on Ethereum, or a Pendle PT - without bridging, swapping, or leaving your EVM wallet. The entire cross-chain stack is abstracted away.No Manual Bridging
No Asset Wrapping
No Manual Swapping
Non-Custodial
The Problem Pathfinder Solves
Traditional cross-chain DeFi requires users to be power users. To access yield on a different chain, you typically need to:- Bridge manually using third-party bridges (Across, Stargate, etc.)
- Understand chain-specific protocols (Aave on Ethereum vs Arbitrum vs Base)
- Manage multiple wallets and positions across different chains
- Swap into yield assets using chain-specific DEXs
- Monitor and rebalance positions as yields change
- Handle non-EVM assets by using wrapped versions or CEX on/off-ramps
How Pathfinder Works
To understand how Pathfinder achieves this abstraction, let’s examine the technical architecture and user flow: Pathfinder is built as a cross-chain ERC-4626 vault (OVault) that uses LayerZero’s OFT standard for seamless cross-chain token movement. The system operates through a hub-and-spoke architecture where the hub chain hosts the core vault logic, and spoke chains enable user interactions. Here’s how a complete user flow works:User deposits USDC on Arbitrum
pf-SHARE ERC-20 tokens representing her vault position. The vault’s target strategy is transparent, but Alice doesn’t need to execute any cross-chain operations.LayerZero bridges USDC to Solana
Vault swaps USDC → SOL
SOL generates yield
totalAssets() function accounts for both the common token balance and the secondary asset value (priced via oracle), giving Alice a unified share price.Alice exits to USDC on Arbitrum
pf-SHARE tokens on Arbitrum. If sufficient buffer exists, the vault transfers USDC directly. If not, the vault reverts and the rebalancing agent swaps SOL → USDC on Solana, then LayerZero bridges it back to Arbitrum. Alice receives USDC - all in one transaction from her perspective.pf-SHARE) represent ownership of the vault’s underlying assets across ALL chains simultaneously. You’re not holding “Arbitrum-wrapped Solana SOL” - you’re holding shares of a vault that owns SOL on Solana. The OFT standard ensures your shares are redeemable on any supported chain for the common token. This eliminates chain-specific wrappers and liquidity fragmentation, providing pure, unified accounting across the entire system.Architecture Overview
Pathfinder runs on a hub-and-spoke topology powered by LayerZero’s OFT messaging. The hub chain (today Solana) owns vault accounting and execution, while spoke chains (Arbitrum, Optimism, Base, …) expose a familiar ERC-20 interface for deposits and withdrawals.Hub Chain
The hub chain (e.g., Solana) hosts the core vault logic and accounting: Components:PathfinderVault: Core ERC-4626 vault with accounting logic (totalAssets(),convertToShares(),convertToAssets())PathfinderComposer: Handles cross-chain messages vialzCompose()ShareOFTAdapter: Bridges share minting/burning between vault and OFT- Manages asset allocation, rebalancing, and yield generation
Spoke Chain
Spoke chains (e.g., Arbitrum, Optimism) provide user-facing interfaces: Components:CommonTokenOFT: ERC-20 + OFT wrapper for common tokens (USDC, USDT, USDe)PathfinderShareOFT: ERC-20 + OFT wrapper for vault shares (pf-SHARE)- Users interact with these contracts on their home chain
- Share tokens are minted/burned via cross-chain messages, maintaining unified accounting
Hub Chain Responsibilities
- Maintain canonical accounting (
totalAssets(),convertToShares(),convertToAssets()) and enforce buffer constraints on redemptions. - Own the share supply via
ShareOFTAdapter, minting and burning pf-SHARE in response to cross-chain messages. - Execute deposits, redemptions, and curator-triggered rebalances under role-based access control.
- Produce the single source of truth for share price across every spoke chain.
Spoke Chain Responsibilities
- Expose a native ERC-20 interface for deposits (
CommonTokenOFT) and withdrawals (PathfinderShareOFT) in the user’s home environment. - Forward deposits and redemption intents to the hub via LayerZero, without holding inventory or running vault logic locally.
- Deliver pf-SHARE tokens back to users after deposits and return bridged common tokens after redemptions succeed on the hub chain.
- Provide immediate UX feedback — transfers, allowance management, and events all happen on the spoke chain the user already uses.
LayerZero Orchestration
LayerZero’s OFT messaging glues the hub and spokes together. Each deposit or redemption is split into two messages: the common-token leg and the share leg. Deterministic delivery plus LayerZero’s refund mechanics guarantee that failed on-hub execution simply returns the original assets to the user.Deposit Flow
User sends common token on spoke chain
CommonTokenOFT.send(amount, composeMsg) on Arbitrum. The OFT contract locks USDC locally and emits a LayerZero message destined for the hub chain.LayerZero delivers payload to the hub
lzSend/lzCompose. On Solana, PathfinderComposer receives the payload and forwards it to PathfinderVault.Vault mints shares
PathfinderVault.deposit(amount) credits the vault, updates accounting, and mints pf-SHARE through ShareOFTAdapter.Shares bridge back
ShareOFTAdapter sends the minted shares back across LayerZero. PathfinderShareOFT receives the message on Arbitrum and mints pf-SHARE to Alice.Alice holds pf-SHARE on her home chain
Withdrawal Flow (Sufficient Buffer)
User burns pf-SHARE on the spoke
PathfinderShareOFT.send(shares, composeMsg) on Arbitrum. Shares are burned locally and a LayerZero message is dispatched to the hub.Vault redeems on the hub
PathfinderComposer triggers PathfinderVault.redeem(shares). Because the buffer holds enough common tokens, the call succeeds immediately.Common tokens bridge home
commonBalance and instructs CommonTokenOFT (hub-side) to stream USDC back through LayerZero.User receives assets on the spoke
CommonTokenOFT on Arbitrum receives the message, re-mints USDC, and transfers it to Alice — completing the round trip.Withdrawal Flow (Insufficient Buffer)
Share burn request travels to the hub
PathfinderVault.redeem(shares) is executed.Vault enforces the buffer invariant
commonBalance >= assets. If the buffer is below target it reverts with InsufficientBuffer.Automatic refund to the spoke
PathfinderComposer._refund(), which instructs LayerZero to return the shares to the original spoke chain.User keeps pf-SHARE until rebalancing replenishes liquidity
Dual-Asset Accounting
Pathfinder vaults manage two asset types to balance liquidity for withdrawals with yield generation:- Common Token (
address public immutable commonToken): ERC-20 token (USDC, USDT, USDe) used for deposits/withdrawals. This provides the liquid buffer for user redemptions. - Secondary Asset (
address public immutable secondaryAsset): Yield-generating asset (wstETH, Pendle PT, SOL derivatives) held for yield generation. This is where the majority of vault assets are deployed to generate returns.
uint256 public commonBalance- Current balance of common tokenuint256 public secondaryBalance- Current balance of secondary assetuint256 public targetCommonRatio- Target allocation ratio (e.g., 20e16 = 20% common token)
commonBalance: Common token (USDC, USDT, USDe) - target 20% allocationsecondaryBalance: Yield-generating asset (wstETH, SOL, PT) - target 80% allocation
totalAssets() = commonBalance + (secondaryBalance × TWAP price)
sharePrice = totalAssets() / totalSupply()
Oracle System:
- Valuation Oracle (TWAP): Used in
totalAssets()for share price calculations - manipulation-resistant, time-weighted average - Swap Oracle (Spot): Used during
rebalance()for execution validation - real-time price from DEX aggregator
deposit(assets)→ mints shares based on current share priceredeem(shares)→ burns shares and returns assets based on current share price- Share price updates as vault balances and oracle prices change
Valuation System
The vault implements a dual-oracle architecture for manipulation-resistant pricing. This separation ensures that share price calculations use stable, time-weighted prices while swap execution uses real-time validation. Valuation Oracle (TWAP)- Used in
totalAssets()for share price calculations:commonBalance + (secondaryBalance * getPriceTWAP()) - Provides time-weighted average price over configurable window (e.g., 1 hour)
- Includes staleness check:
require(block.timestamp - lastUpdate <= maxStaleness) - Manipulation-resistant but may lag spot prices during volatile periods
- Used during
rebalance()for execution validation - Provides real-time spot price from DEX aggregator
- Validates
minAmountOutagainst spot price before swap execution - Acts as secondary check to prevent TWAP manipulation from affecting swap execution
totalAssets() function implements the ERC-4626 standard:
sharePrice = totalAssets() / totalSupply(), regardless of which chain they interact with. The TWAP oracle ensures share prices don’t fluctuate wildly with short-term market volatility.
Rebalancing Mechanism
Maintaining target allocations requires periodic rebalancing. The vault uses an asynchronous rebalancing mechanism that’s completely decoupled from user operations, preventing predictable swap patterns that could be exploited. An off-chain agent monitors allocation ratios and callsrebalance(uint256 amountIn, uint256 minAmountOut, bool swapToSecondary) when drift exceeds thresholds.
Rebalancing Logic:
- Calculates current ratio:
currentRatio = (commonBalance * 1e18) / totalAssets() - Compares to
targetCommonRatio(e.g., 20e16 = 20%) - Triggers swap when drift exceeds threshold (e.g., ±5% from target)
- Rebalancing is never triggered by user actions - only by the off-chain agent
-
Monitor: Off-chain agent calls
getCurrentAllocation()to check ifcommonRatiodrifts fromtargetCommonRatio(threshold: ±5%) -
Quote: If drift detected, agent queries DEX aggregator for swap quote (
getQuote(amountIn, tokenIn, tokenOut)) -
Calculate: Agent calculates
minAmountOut = quote × 0.95(5% slippage tolerance) -
Submit: Agent submits
rebalance(amountIn, minAmountOut, swapToSecondary)via private RPC (MEV protection) -
Validate: Vault validates
swapOracle.getPriceSpot() >= minAmountOutbefore execution -
Execute: Vault calls swap router, receives
amountOut, and updatescommonBalanceandsecondaryBalanceatomically
deposit()/redeem())
On-Chain Validation:
- Only callable by
rebalancerrole (off-chain agent) - Never triggered by user actions (
deposit()/redeem()) - Validates spot price against
minAmountOutbefore execution - MEV protection via private RPC submission
Security: Buffer-and-Revert Model
A primary innovation in Pathfinder is its withdrawal mechanism. Instead of automatically swapping assets to meet withdrawal demand (which would be vulnerable to MEV extraction and slippage), the vault enforces a strict buffer system that prevents forced liquidations.How It Works
The vault enforces buffer constraints inredeem(). When a user attempts to redeem shares, the vault checks if sufficient common token balance exists to fulfill the withdrawal:
- Maintains
commonBalance(target: 20% oftotalAssets()) - Maintains
secondaryBalance(target: 80% oftotalAssets()) totalAssets() = commonBalance + (secondaryBalance × TWAP price)
- User calls
redeem(shares) - Vault calculates
assets = convertToAssets(shares) - Vault checks:
require(commonBalance >= assets) - If sufficient: Transfer assets, burn shares, succeed
- If insufficient: Revert with
InsufficientBuffererror
- When withdrawal reverts, off-chain agent detects buffer depletion
- Agent monitors
commonBalance / totalAssets()ratio - When below threshold, agent calls
rebalance()to swap secondary → common - User can retry withdrawal after buffer is replenished
- Buffer Target:
targetCommonRatio(e.g., 20e16 = 20%) maintained via rebalancing to ensure sufficient liquidity - Revert Condition:
require(commonBalance >= assets)inredeem()- no automatic swap on insufficient buffer - Asynchronous Rebalancing: Off-chain agent monitors
commonBalance / totalAssets()and callsrebalance()when below threshold, allowing optimal swap execution - No User-Triggered Swaps:
deposit()andredeem()never call swap functions directly, preventing predictable MEV targets
Why This Matters
This design eliminates a major attack vector and prevents systemic risks by decoupling user withdrawals from swap execution:❌ Naive Approach: Auto-Swap on Withdraw
❌ Naive Approach: Auto-Swap on Withdraw
- Attacker could sandwich the swap, extracting value
- During market stress, forced swaps could happen at terrible prices
- MEV bots would monitor and front-run every large withdrawal
- The vault would slowly bleed value to arbitrageurs
✅ Pathfinder Approach: Buffer + Revert
✅ Pathfinder Approach: Buffer + Revert
- Rebalancing happens via off-chain quoted swaps with slippage protection
- No predictable on-chain swap triggers for MEV bots to exploit
- Large withdrawals require curator/agent coordination
- The vault never executes a swap it hasn’t explicitly approved
Macroeconomic Rationale: Bank Runs and Solvency
The buffer-and-revert model draws from traditional banking principles to prevent bank runs and maintain solvency. The design addresses a fundamental liquidity mismatch inherent in yield-generating vaults.The Bank Run Problem
In traditional banking, banks face a fundamental mismatch: they hold long-term illiquid assets (loans) but offer short-term liquid liabilities (deposits). If too many depositors withdraw simultaneously, the bank must liquidate assets at fire-sale prices, potentially becoming insolvent. Pathfinder faces a similar challenge:- Illiquid assets: Secondary yield assets (wstETH, SOL, PT) that generate returns but require time to swap at optimal prices
- Liquid liabilities: User deposits redeemable on-demand for USDC
- Swap large amounts of secondary assets at unfavorable prices (fire sales)
- Trigger a death spiral as poor execution reduces share value
- Cause remaining depositors to panic and withdraw, accelerating the collapse
How Buffering Prevents Runs
The buffer acts as a liquidity reserve preventing forced liquidations: Normal Operations:- Small withdrawals (2-5% of buffer) execute immediately
- Buffer decreases, agent detects drift from target ratio
- Agent calls
rebalance()to swap secondary → common - Buffer replenished to target 20% allocation
- Large withdrawal (e.g., 15% of total assets) requested
- Vault checks:
commonBalance >= assets? - If sufficient: Withdrawal succeeds, buffer decreases
- If insufficient: Transaction reverts with
InsufficientBuffer - Agent detects revert, calls
rebalance()to swap secondary → common - User retries withdrawal after buffer replenished
- No user-triggered swaps: Only rebalancer can execute swaps
- Price validation: Spot oracle validates
minAmountOutbefore swap - MEV protection: Swaps submitted via private RPC (Flashbots)
- Atomic updates: Balance updates happen atomically, no intermediate states
-
Prevents Fire Sales:
redeem()reverts withInsufficientBuffererror whencommonBalance < assets. No swap is executed automatically. The rebalancing agent can wait for optimal market conditions before callingrebalance(), ensuring swaps happen at favorable prices. -
Solvency Guarantee: The invariant
commonBalance >= sum(pending withdrawals)is maintained up totargetCommonRatio * totalAssets(). Withdrawals up to this threshold execute without touchingsecondaryBalance, preserving yield generation. -
Coordination Failure: When
commonBalance < assets, the transaction reverts. Users cannot coordinate simultaneous withdrawals exceeding buffer capacity. The rebalancing delay breaks run dynamics by forcing sequential withdrawals. -
Price Discovery: Asynchronous
rebalance()enables:- Multi-aggregator quote comparison (
getQuote()from 1inch, Paraswap) - Optimal timing (wait for favorable market conditions)
- MEV protection (private RPC submission via Flashbots)
- Slippage validation (
require(spotPrice >= minAmountOut))
- Multi-aggregator quote comparison (
Solvency Guarantees
The buffer model provides stronger solvency guarantees than auto-swapping:| Scenario | Auto-Swap Model | Buffer Model |
|---|---|---|
| Normal withdrawals | ✅ Works | ✅ Works |
| Large withdrawal | ⚠️ Forced swap at market price | ✅ Revert, rebalance optimally |
| Market stress | ❌ Fire sale prices | ✅ Wait for better conditions |
| Coordinated run | ❌ Death spiral | ✅ Buffer absorbs, breaks coordination |
| MEV extraction | ❌ Predictable targets | ✅ No predictable triggers |
Real-World Parallels
This design mirrors successful financial structures:- Bank Reserve Requirements: Banks must hold reserves to cover withdrawals, preventing runs
- Money Market Fund Gates: During stress, funds can suspend redemptions to prevent fire sales
- Central Bank Lender of Last Resort: Central banks provide liquidity during crises to prevent systemic collapse
Additional Security Features
Beyond the buffer-and-revert model, dual-oracle system, and MEV-protected rebalancing, Pathfinder includes several additional safeguards that work together to ensure system security:Oracle Staleness Checks
Oracle Staleness Checks
maxStaleness threshold (e.g., 1 hour), transactions revert. Prevents operation with outdated pricing during oracle downtime or manipulation attempts.Implementation: require(block.timestamp - oracle.lastUpdate() <= maxStaleness, "StalePrice");Inflation Attack Protection
Inflation Attack Protection
- Virtual Shares: Decimal offset (
_decimalsOffset) creates virtual shares, making first-deposit manipulation economically infeasible. Share price calculation:(totalAssets() + virtualAssets) / (totalSupply() + virtualSupply) - Seed Deposit: Vault initialized with seed deposit during deployment. Ensures
totalSupply() > 0andtotalAssets() > 0, preventing share price manipulation on first deposit.
Emergency Controls
Emergency Controls
- Pausability:
pause()function setspaused = true, reverting alldeposit(),redeem(), andrebalance()calls - Emergency Shutdown:
emergencyShutdown()swaps allsecondaryBalance→commonBalanceviarebalance(), then pauses vault - Timelock Governance: All
onlyOwnerfunctions require timelock delay (e.g., 48 hours), preventing instant malicious parameter changes
Cross-Chain Refund Mechanism
Cross-Chain Refund Mechanism
PathfinderComposer.lzCompose() calls Vault.redeem() and it reverts with InsufficientBuffer, the composer calls _refund() which triggers LayerZero’s lzReceive() on the origin chain. User’s shares are returned atomically. No funds lost due to failed cross-chain operations.Summary
Pathfinder abstracts cross-chain complexity for end users through a unified ERC-4626 vault interface. The system combines several key innovations: Core Components:- LayerZero OFT standard for seamless token streaming across chains without user interaction
- Hub-and-spoke architecture separating vault logic (hub) from user interfaces (spokes)
- Dual-asset accounting balancing liquidity buffers with yield generation
- Dual-oracle pricing using TWAP for share valuation and spot prices for swap validation
- Asynchronous rebalancing that aggregates user deposits for efficient execution
- Buffer-based withdrawals preventing MEV exploitation and forced liquidations
- Unified accounting where users hold vault shares, not chain-specific wrapped tokens
- Curators design sophisticated multi-chain strategies
- Pathfinder executes them transparently
- Users see “deposit → yield → withdraw” in their preferred stablecoin
- Security is built into the design through buffer management and MEV protection