{
  "apiVersion": "1",
  "generatedAt": "2026-06-15",
  "description": "Reference strategy corpus for the Lucidly Pro decomposer agent. Each entry captures a real working strategy from lucidlylabs/strats — not a placeholder. The agent uses these as nearest-neighbour examples when mapping a free-text strategy idea to a concrete leaf sequence on the live policy catalog. New archetypes can be added by following the same shape.",
  "archetypeFamilies": {
    "leveraged_carry": "Borrow against yield-bearing collateral, deploy borrowed asset for additional yield. PnL = (collateral yield × leverage) − borrow cost. Reverts hurt: any leg failure unwinds the full multicall.",
    "lp_hedge": "Provide concentrated liquidity in a volatile pair, hedge impermanent loss by borrowing the volatile leg against the other. PnL = LP fees − IL − borrow cost − rebalance friction.",
    "yield_basket": "Allocate a single asset across N yield venues with a weight function (APY, risk, capacity). Rebalance when allocator drift exceeds threshold. PnL = weighted average venue yield − reallocation cost.",
    "delta_neutral": "Long a synthetic/structured asset (LP token, PT, yield-bearing token) on one venue, short the same underlying via a perp on another. PnL = funding + carry, with cross-chain bridge cost amortised over hold period.",
    "_extension_note": "The decomposer is not limited to these four. They are illustrative archetypes. Any DeFi strategy with onchain or hybrid (onchain + venue API) execution is in scope as long as the leaves exist in the live policy catalog."
  },
  "topologyNote": "Lucidly factory chains [1, 8453, 42161, 10] are where vault SHARES are minted, not where capital can be deployed. Capital can flow to any EVM chain with bridge support (CCTP / LayerZero / CCIP) and Merkle leaves for the destination protocols. Each strategy declares its topology explicitly.",
  "strategies": [
    {
      "id": "leveraged_carry.eth_wsteth_morpho_syusd",
      "displayName": "ETH carry — wstETH collateral on Morpho, USDC borrow into syUSD",
      "archetype": "leveraged_carry",
      "summary": "Take WETH, swap to wstETH (yield-bearing ETH staking derivative via Lido), supply as collateral on Morpho Blue's wstETH/USDC market, borrow USDC at target LTV (~65%), deposit the borrowed USDC into syUSD (yield-bearing USD vault). PnL = wstETH staking yield × (1 + leverage) + syUSD yield − Morpho USDC borrow rate. Strategy is single-chain (Ethereum mainnet) with no bridge legs.",
      "thesis": "wstETH yield (~3-4% APY) compounds on the supplied collateral; the borrowed USDC earns syUSD yield (~8-15% APY in normal markets); the borrow cost on Morpho USDC stays below the syUSD yield as long as Morpho's wstETH/USDC market isn't over-utilised. Net carry = wstETH_apy + (syusd_apy − morpho_borrow_apy) × ltv. Reverses to loss if borrow APY spikes above syUSD APY.",
      "assets": {
        "depositInputs": ["WETH"],
        "exitOutputs": ["WETH"],
        "intermediateAssets": ["wstETH", "USDC", "syUSD"]
      },
      "topology": {
        "homeChain": 1,
        "positionChains": [1],
        "bridgeEdges": []
      },
      "legs": [
        {
          "chain": 1,
          "chainName": "ethereum",
          "kind": "onchain",
          "purpose": "open_position",
          "leafFamilies": [
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "WETH", "spender": "Magpie router", "rationale": "Allow swap router to pull WETH." },
            { "protocol": "Magpie", "selector": "swapWithBackendSignature(bytes)", "target": "Magpie router", "rationale": "Aggregated DEX swap WETH → wstETH at best market price with signed backend quote (slippage cap inside the calldata)." },
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "wstETH", "spender": "Morpho Blue", "rationale": "Allow Morpho to pull wstETH on supplyCollateral." },
            { "protocol": "Morpho Blue", "selector": "supplyCollateral((address,address,address,address,uint256),uint256,address,bytes)", "target": "Morpho Blue", "rationale": "Deposit wstETH as collateral on the wstETH/USDC market. Position belongs to the boring vault." },
            { "protocol": "Morpho Blue", "selector": "borrow((address,address,address,address,uint256),uint256,uint256,address,address)", "target": "Morpho Blue", "rationale": "Borrow USDC against wstETH collateral. Borrow amount sized to keep LTV at target (typically 65%, lltv on the market is ~86%, giving ~25% buffer). Borrowed funds go to the boring vault directly." },
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "USDC", "spender": "syUSD teller", "rationale": "Approve syUSD vault's teller to pull the borrowed USDC." },
            { "protocol": "syUSD", "selector": "deposit(uint256,uint256,address)", "target": "syUSD teller", "rationale": "Mint syUSD shares 1:1 (modulo current rate). syUSD held in the boring vault accrues the syUSD yield." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/ethcarry_mainnet_morpho/utils/actions.py::open_position",
          "rationale": "Single-chain leveraged carry. Every leaf executes atomically in one manager.manage() multicall on mainnet — if any leg reverts, all prior legs revert too. This atomicity matters: a partial open leaves the vault with un-hedged collateral or un-deployed borrow."
        },
        {
          "chain": 1,
          "chainName": "ethereum",
          "kind": "onchain",
          "purpose": "close_position",
          "leafFamilies": [
            { "protocol": "syUSD", "selector": "requestWithdraw(...)", "target": "syUSD queue", "rationale": "Queue a withdrawal from syUSD (atomic queue model: deposits are instant, withdrawals are FIFO-queued and solved by the official solver)." },
            { "protocol": "syUSD", "selector": "selfSolveWithdraw(...)", "target": "syUSD queue", "rationale": "Self-solve the queue request to convert syUSD shares back to USDC immediately (vault holds enough buffer for this; otherwise wait for the next solver round)." },
            { "protocol": "Morpho Blue", "selector": "repay(...)", "target": "Morpho Blue", "rationale": "Repay the USDC borrow on Morpho. Receipt-amount is principal + accrued interest." },
            { "protocol": "Morpho Blue", "selector": "withdrawCollateral(...)", "target": "Morpho Blue", "rationale": "Withdraw the wstETH collateral after the borrow is fully repaid (Morpho enforces this ordering)." },
            { "protocol": "Magpie", "selector": "swapWithBackendSignature(bytes)", "target": "Magpie router", "rationale": "Swap wstETH → WETH so the vault holds the deposit asset for the next user redemption." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/ethcarry_mainnet_morpho/utils/actions.py::close_position",
          "rationale": "Unwind ordering is the reverse of open: redeem the yield asset first to free USDC, repay borrow, withdraw collateral, swap back. Morpho's repay/withdraw ordering is enforced by the protocol (must repay before withdrawing collateral that would leave LTV > lltv)."
        },
        {
          "chain": 1,
          "chainName": "ethereum",
          "kind": "onchain",
          "purpose": "flash_deleverage",
          "leafFamilies": [
            { "protocol": "Morpho flashloan adapter", "selector": "flashLoan(...)", "target": "MorphoFlashloanAdapter", "rationale": "Used when the vault doesn't have enough liquid USDC to repay the borrow naturally (e.g., during emergency unwind). Flash USDC, repay Morpho, withdraw collateral, swap collateral to USDC, repay flash. One-shot deleverage." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/ethcarry_mainnet_morpho/utils/actions.py::flash_deleverage",
          "rationale": "Emergency unwind path. Triggered when LTV approaches lltv or when the user wants immediate exit but syUSD doesn't have queue capacity."
        }
      ],
      "decisions": [
        { "trigger": "open_position", "condition": "Idle WETH in vault AND LTV target reachable on Morpho market", "action": "Run the open_position leg above" },
        { "trigger": "rebalance_ltv", "condition": "LTV drifts from target by > 2% (price move) OR Morpho lltv changes", "action": "Add/remove collateral, or repay-portion-of-borrow to restore target LTV" },
        { "trigger": "emergency_unwind", "condition": "Morpho market lltv approached OR syUSD vault paused OR Morpho oracle staleness > 30 min", "action": "flash_deleverage path" }
      ],
      "riskFactors": {
        "leverage": "Yes — 65% LTV against Morpho lltv ~86%. Liquidation if wstETH/USDC drops > ~24%.",
        "oracle": "Morpho uses Chainlink for wstETH/USDC pricing. Stale oracle could mis-price collateral and either liquidate or freeze actions.",
        "custody": "All assets held by the boring vault. Manager has the Merkle root; can only call whitelisted leaves.",
        "bridge": "None — single chain.",
        "smartContract": "Morpho Blue (audited, large TVL), wstETH (Lido, audited), syUSD (Lucidly product, audited), Magpie router (aggregator)."
      },
      "referenceSource": {
        "repo": "lucidlylabs/strats",
        "branch": "master",
        "path": "merkle_tree_generation/strategies/ethcarry_mainnet_morpho/",
        "leafFile": "leafs/ethereum/ETHUSDCarryClusterStrategyLeafs.json"
      }
    },
    {
      "id": "lp_hedge.aerodrome_weth_cbbtc_aave",
      "displayName": "Aerodrome WETH/cbBTC concentrated LP, IL-hedged via Aave V3",
      "archetype": "lp_hedge",
      "summary": "Provide concentrated liquidity in Aerodrome Slipstream's WETH/cbBTC pool on Base. Borrow WETH on Aave V3 against cbBTC collateral to neutralize impermanent loss exposure. Tick width is driven by a real-time multi-feed volatility tracker (Binance, Chainlink, Deribit, Hyperliquid, gas, ToD). PnL = LP fees − IL − Aave borrow cost − rebalance friction. Single-chain (Base 8453).",
      "thesis": "Concentrated LP earns more fees per unit of capital when the price stays in range. IL exposure on cbBTC/WETH is dominated by the volatile leg (WETH moves more than cbBTC against USD); borrowing WETH on Aave creates a synthetic short that offsets that leg. Tick width adapts to volatility: narrow ticks in calm markets (max fees), wide ticks in turbulent ones (avoid frequent rebalance). Hysteresis prevents thrashing on borderline vol readings.",
      "assets": {
        "depositInputs": ["USDC"],
        "exitOutputs": ["USDC"],
        "intermediateAssets": ["WETH", "cbBTC", "aWETH", "vDebtWETH"]
      },
      "topology": {
        "homeChain": 8453,
        "positionChains": [8453],
        "bridgeEdges": []
      },
      "legs": [
        {
          "chain": 8453,
          "chainName": "base",
          "kind": "onchain",
          "purpose": "open_position",
          "leafFamilies": [
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "USDC", "spender": "Magpie router", "rationale": "Approve aggregator for the initial USDC → asset swap." },
            { "protocol": "Magpie", "selector": "swapWithBackendSignature(bytes)", "target": "Magpie router", "rationale": "Split USDC into cbBTC + WETH at the desired ratio for the LP position (tick-aware sizing)." },
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "cbBTC", "spender": "Aave V3 Pool", "rationale": "Approve Aave to supply cbBTC as collateral." },
            { "protocol": "Aave V3", "selector": "supply(address,uint256,address,uint16)", "target": "Aave V3 Pool", "rationale": "Supply cbBTC as collateral. Receive aCBBTC." },
            { "protocol": "Aave V3", "selector": "borrow(address,uint256,uint256,uint16,address)", "target": "Aave V3 Pool", "rationale": "Borrow WETH at target LTV (~60%) against cbBTC. The borrowed WETH is the IL hedge." },
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "WETH", "spender": "Aerodrome NFT manager", "rationale": "Approve LP token mint to pull WETH." },
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "cbBTC", "spender": "Aerodrome NFT manager", "rationale": "Approve LP token mint to pull cbBTC." },
            { "protocol": "Aerodrome Slipstream", "selector": "mint((address,address,int24,int24,int24,uint256,uint256,uint256,uint256,address,uint256,uint160))", "target": "Aerodrome NFT manager", "rationale": "Mint the concentrated LP position with tick range sized from current volatility (100 / 150 / 250 / 400 ticks depending on σ)." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/lp_hedge/actions/",
          "rationale": "The whole sequence runs as one atomic multicall. If borrow fails (insufficient cbBTC collateral) or LP mint fails (slippage), the entire open reverts and the vault sits in idle USDC."
        },
        {
          "chain": 8453,
          "chainName": "base",
          "kind": "onchain",
          "purpose": "rebalance_lp",
          "leafFamilies": [
            { "protocol": "Aerodrome Slipstream", "selector": "decreaseLiquidity((uint256,uint128,uint256,uint256,uint256))", "target": "Aerodrome NFT manager", "rationale": "Remove the existing LP position." },
            { "protocol": "Aerodrome Slipstream", "selector": "collect((uint256,address,uint128,uint128))", "target": "Aerodrome NFT manager", "rationale": "Collect any accrued fees + the underlying tokens." },
            { "protocol": "Aerodrome Slipstream", "selector": "burn(uint256)", "target": "Aerodrome NFT manager", "rationale": "Burn the empty position NFT." },
            { "protocol": "Magpie", "selector": "swapWithBackendSignature(bytes)", "target": "Magpie router", "rationale": "Re-balance the underlying token ratio for the new tick range." },
            { "protocol": "Aerodrome Slipstream", "selector": "mint(...)", "target": "Aerodrome NFT manager", "rationale": "Mint a fresh LP position with the new (vol-driven) tick range centered on current price." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/lp_hedge/strategy.py::rebalance_decision",
          "rationale": "Triggered by: (1) pool price exits current LP range (Swap event listener), (2) Chainlink oracle price diverges from pool price by > 3% (oracle-triggered), (3) hysteresis debounce — wait 5 min before re-acting on a borderline signal."
        }
      ],
      "decisions": [
        { "trigger": "open_position", "condition": "Vault has idle USDC AND volatility tracker reports a valid σ AND kill switch is OFF", "action": "Run open_position with tick width derived from current σ" },
        { "trigger": "rebalance_lp", "condition": "(Pool price out of range) OR (oracle drift > 3%) AND (last rebalance > 5 min ago)", "action": "Run rebalance_lp leg" },
        { "trigger": "hedge_adjust", "condition": "Aave LTV drifts from 60% by > 5% (WETH price moved)", "action": "Either supply/withdraw cbBTC OR borrow/repay WETH to restore target LTV" },
        { "trigger": "kill_switch", "condition": "10 consecutive reverts on any action", "action": "Unwind LP, repay full Aave debt, withdraw collateral, swap everything to USDC, halt" }
      ],
      "riskFactors": {
        "leverage": "Yes — 60% LTV on Aave. Liquidation if cbBTC/WETH ratio drops > ~25%.",
        "oracle": "Aave Chainlink feed for cbBTC. Aerodrome pool price for LP. Divergence between them is itself a rebalance trigger.",
        "custody": "Boring vault.",
        "bridge": "None — single chain.",
        "smartContract": "Aerodrome Slipstream (audited, Uniswap V3 fork), Aave V3 (audited), Magpie (aggregator).",
        "executionRisk": "Volatility feed staleness or feed disagreement. Kill switch after 10 reverts is the operational safety net."
      },
      "referenceSource": {
        "repo": "lucidlylabs/strats",
        "branch": "feat/aerodrome-btcethmm-strat",
        "path": "merkle_tree_generation/strategies/lp_hedge/",
        "leafFile": "leafs/base/AeroLpStrateigstLeaf.json"
      }
    },
    {
      "id": "yield_basket.usdc_morpho_cluster",
      "displayName": "High-yield USDC lending cluster — basket allocator across Morpho markets",
      "archetype": "yield_basket",
      "summary": "Allocate USDC across N curated Morpho Blue markets (cbBTC, AAFalconX USDC, MF One USDC, Steakhouse Royal USDC, fxSAVE) using a weighted allocator (APY × risk-scaled). Rebalance when allocator drift exceeds threshold. Single-chain (Ethereum mainnet). PnL = weighted average market lending APY − reallocation friction.",
      "thesis": "Single-venue concentration risk is mitigated by spreading USDC across multiple curated Morpho markets with different underlying collateral. The allocator weights each market by score = apy / risk^β, where risk is operator-tuned (1-10) per market and β controls how aggressively risk shrinks weight. Reallocation costs (gas + Morpho withdraw + supply) are amortised against the APY uplift from the optimal split.",
      "assets": {
        "depositInputs": ["USDC"],
        "exitOutputs": ["USDC"],
        "intermediateAssets": ["Morpho USDC supply positions"]
      },
      "topology": {
        "homeChain": 1,
        "positionChains": [1],
        "bridgeEdges": []
      },
      "legs": [
        {
          "chain": 1,
          "chainName": "ethereum",
          "kind": "onchain",
          "purpose": "allocate",
          "leafFamilies": [
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "USDC", "spender": "Morpho Blue", "rationale": "One-time max approve so per-market supply calls don't need a fresh approve each time." },
            { "protocol": "Morpho Blue", "selector": "supply((address,address,address,address,uint256),uint256,uint256,address,bytes)", "target": "Morpho Blue", "rationale": "Supply USDC into market N. One leaf per (market, action) combination. The allocator decides amount per market; the manager executes one supply call per non-zero allocation." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/high_yield_usdc_lending_cluster/allocator.py",
          "rationale": "The allocator runs offchain (Python) and computes target weights from live market APYs (read via TVL adapters) and operator-set risk scores. The manager.manage() call posts one supply leaf per market that needs more capital. Markets that need less get a withdraw leaf in the same multicall."
        },
        {
          "chain": 1,
          "chainName": "ethereum",
          "kind": "onchain",
          "purpose": "rebalance",
          "leafFamilies": [
            { "protocol": "Morpho Blue", "selector": "withdraw(...)", "target": "Morpho Blue", "rationale": "Withdraw USDC from over-allocated markets back to the vault." },
            { "protocol": "Morpho Blue", "selector": "supply(...)", "target": "Morpho Blue", "rationale": "Re-supply to under-allocated markets. Same multicall." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/high_yield_usdc_lending_cluster/allocator.py::plan_rebalance",
          "rationale": "All withdraw+supply leaves run in one atomic multicall — no risk of the vault sitting half-rebalanced."
        }
      ],
      "decisions": [
        { "trigger": "allocate_idle", "condition": "Vault idle USDC > min_size (e.g., 10k)", "action": "Run allocate leg with allocator-computed splits" },
        { "trigger": "rebalance", "condition": "max(|target_weight − actual_weight|) > drift_threshold (default 5%) OR any market APY changed > 30% since last tick", "action": "Run rebalance leg" },
        { "trigger": "exit_market", "condition": "Market risk score raised past operator cap (manual override) OR Morpho oracle staleness on that market", "action": "Withdraw full position from that market, redistribute to remaining markets" }
      ],
      "riskFactors": {
        "leverage": "None — pure supply position on each market.",
        "oracle": "Each market has its own oracle (Chainlink-backed via Morpho's IRM). Per-market oracle drift only affects that market's borrow side, not lender position.",
        "custody": "Boring vault.",
        "bridge": "None — single chain.",
        "smartContract": "Morpho Blue per-market isolation: a hack on one market doesn't touch the others.",
        "concentrationRisk": "Reduced by 5-market basket vs single Morpho market. Allocator risk-score β tunes how aggressively basket shifts away from one bad market."
      },
      "referenceSource": {
        "repo": "lucidlylabs/strats",
        "branch": "high_yield_usdc_lending_cluster",
        "path": "merkle_tree_generation/strategies/high_yield_usdc_lending_cluster/",
        "leafFile": "leafs/ethereum/HighYieldUsdcLendingClusterStrategistLeafs.json"
      }
    },
    {
      "id": "delta_neutral.pendle_pt_sena_hyperliquid_short",
      "displayName": "Delta-neutral PT-sENA — long PT on Pendle (mainnet), short ENA perp on Hyperliquid",
      "archetype": "delta_neutral",
      "summary": "TRUE CROSS-CHAIN reference. Long leg: USDC → ENA → sENA → PT-sENA on Pendle (Ethereum mainnet). Hedge leg: bridge a fraction of USDC via CCIP to a HyperEVM hedge vault, then short ENA perp on Hyperliquid via CoreWriter. PnL = (PT-sENA implied yield + sENA staking yield) − ENA funding rate − CCIP bridge cost − slippage chunks. The strategy uses TWO boring vaults — one on each chain — coordinated by the offchain engine.",
      "thesis": "PT-sENA captures sENA's yield + Pendle's implied yield at a fixed price-to-maturity. The directional risk is that ENA itself moves; shorting ENA perp on Hyperliquid neutralises that. Funding on the short adds to (or subtracts from) carry depending on rate direction. The PT trade is single-shot at maturity; the perp short is rebalanced as PT delta drifts.",
      "assets": {
        "depositInputs": ["USDC"],
        "exitOutputs": ["USDC"],
        "intermediateAssets": ["ENA", "sENA", "PT-sENA", "Hyperliquid USDC margin"]
      },
      "topology": {
        "homeChain": 1,
        "positionChains": [1, 999],
        "_positionChainNames": { "1": "ethereum", "999": "hyperevm" },
        "bridgeEdges": [
          {
            "from": 1,
            "to": 999,
            "rail": "CCIP",
            "asset": "USDC",
            "rationale": "User USDC arrives on the mainnet boring vault. A fraction is bridged via Chainlink CCIP to the HyperEVM boring vault to fund the perp margin. CCIP_MIN_BRIDGE_USDC = 100 (smaller bridges aren't economic given fees)."
          },
          {
            "from": 999,
            "to": 998,
            "rail": "HL_CORE_BRIDGE",
            "asset": "USDC",
            "rationale": "Within the Hyperliquid stack, USDC on HyperEVM (chain 999) bridges to Hyperliquid Core (chain 998 — the L1 where perp positions live) via CORE_DEPOSIT_CONTRACT (0x6b9e773128f453f5c2c60935ee2de2cbc5390a24). This is the official intra-Hyperliquid bridge — instant in practice."
          }
        ]
      },
      "legs": [
        {
          "chain": 1,
          "chainName": "ethereum",
          "kind": "onchain",
          "purpose": "bridge_hedge_margin",
          "leafFamilies": [
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "USDC", "spender": "CCIP router", "rationale": "Approve CCIP to pull bridging USDC." },
            { "protocol": "CCIP", "selector": "ccipSend(uint64,(bytes,bytes,...))", "target": "CCIP router", "rationale": "Send USDC + a small message to the HyperEVM destination chain. Receiver is the HL boring vault address. Fee paid in CCIP_FEE_TOKEN (often LINK or native). README says 'bridge first, confirm HyperEVM margin, then enter PT'." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/dn_pt_sena/utils/actions.py::bridge_usdc_to_hyperevm",
          "rationale": "Bridge MUST happen first. If the PT leg is taken before the hedge margin arrives on HL, the strategy is naked-long ENA until CCIP finalises (10-15 min). The offchain engine awaits CCIP confirmation before submitting the long leg."
        },
        {
          "chain": 1,
          "chainName": "ethereum",
          "kind": "onchain",
          "purpose": "open_long_pt",
          "leafFamilies": [
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "USDC", "spender": "Magpie router", "rationale": "Approve aggregator for USDC → ENA swap." },
            { "protocol": "Magpie", "selector": "swapWithBackendSignature(bytes)", "target": "Magpie router", "rationale": "USDC → ENA. Chunked into MAX_CHUNK_SIZE_USDC pieces (default 20k) with CHUNK_DELAY_SECONDS between to limit price impact." },
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "ENA", "spender": "sENA contract", "rationale": "Approve sENA staking contract." },
            { "protocol": "sENA", "selector": "deposit(uint256,address)", "target": "sENA contract", "rationale": "Stake ENA → sENA (1:1 minus current rate). sENA yields staking rewards." },
            { "protocol": "ERC20", "selector": "approve(address,uint256)", "target": "sENA", "spender": "Pendle router", "rationale": "Approve Pendle to pull sENA for PT minting." },
            { "protocol": "Pendle", "selector": "swapExactTokenForPt((address,uint256,address,...))", "target": "Pendle router", "rationale": "Swap sENA for PT-sENA on the Pendle market. PT-sENA matures at a fixed date and at maturity 1 PT redeems to 1 sENA (assuming no underlying default)." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/dn_pt_sena/utils/actions.py::open_long",
          "rationale": "Long leg on mainnet. Chunked to keep slippage on ENA (mid-cap volatile token) under MAX_PRICE_DEV (default 5%)."
        },
        {
          "chain": 999,
          "chainName": "hyperevm",
          "kind": "onchain",
          "purpose": "fund_hl_margin",
          "leafFamilies": [
            { "protocol": "HL CORE", "selector": "depositForCore(uint64,uint256)", "target": "CORE_DEPOSIT_CONTRACT (0x6b9e...)", "rationale": "Move bridged USDC from the HyperEVM boring vault into the Hyperliquid Core perp account. This is the intra-HL bridge — instant." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/dn_pt_sena/utils/actions.py::deposit_hl_margin",
          "rationale": "After CCIP delivers USDC to HyperEVM, the vault has to move it into Core to be usable as perp margin. The CORE_DEPOSIT_CONTRACT is the entry point. From there the CoreWriter (0x3333333333333333333333333333333333333333) is the action surface."
        },
        {
          "chain": 999,
          "chainName": "hyperevm",
          "kind": "onchain",
          "purpose": "open_short_perp",
          "leafFamilies": [
            { "protocol": "HL CoreWriter", "selector": "writeAction(uint8,bytes)", "target": "CORE_WRITER (0x3333...)", "rationale": "Set leverage on ENA perp (HL_LEVERAGE = 1 means no leverage; the SHORT is funded 1:1 by the bridged USDC)." },
            { "protocol": "HL CoreWriter", "selector": "writeAction(uint8,bytes)", "target": "CORE_WRITER (0x3333...)", "rationale": "Submit limit order on ENA-PERP, side=ASK (short), chunked under HL_MAX_IMPACT (default 0.1% per chunk) with HL_CHUNK_DELAY_SECONDS." }
          ],
          "sourcePath": "merkle_tree_generation/strategies/dn_pt_sena/engine/",
          "rationale": "Short opened only after fund_hl_margin lands. Chunking on the short keeps HL impact under 0.1% per fill — important on mid-cap perps where the book is thin."
        }
      ],
      "decisions": [
        { "trigger": "open_full_position", "condition": "Vault has new USDC AND bridge route healthy AND ENA price within MAX_PRICE_DEV of HL mark", "action": "Run bridge_hedge_margin → wait for CCIP confirm → fund_hl_margin → open_short_perp in parallel with open_long_pt (mainnet leg starts after bridge confirm)" },
        { "trigger": "rebalance_hedge", "condition": "PT-sENA delta drifts from short notional by > HEDGE_DRIFT_THRESHOLD (default 5%) due to ENA price move", "action": "Add or remove HL short notional to restore delta-neutral" },
        { "trigger": "close_at_maturity", "condition": "PT-sENA matures OR strategy unwound by operator", "action": "Redeem PT → sENA → unstake to ENA → swap to USDC on mainnet; close HL short, withdraw margin from Core to HyperEVM, bridge USDC back via CCIP" }
      ],
      "riskFactors": {
        "leverage": "Default 1× on HL perp (no perp leverage). Underlying PT-sENA has no leverage. Total is unlevered.",
        "oracle": "Pendle implied price (market-driven), HL mark price for funding, Chainlink for CCIP fees.",
        "custody": "TWO boring vaults — one on mainnet, one on HyperEVM. Both have their own Merkle root and manager.",
        "bridge": "CCIP (mainnet ↔ HyperEVM): 10-15 min finality, retry on inactivity timeout (CCIP_CONFIRM_TIMEOUT_SECONDS = 3600). HL Core deposit (HyperEVM → HL L1): instant. CCIP failure during bridge would leave the strategy half-positioned; the engine has a 'bridge-first, confirm-before-long' ordering rule to handle this safely.",
        "smartContract": "Pendle (large audited TVL), sENA (Ethena, audited), HL Core (Hyperliquid's L1 perp engine — not EVM-audited in the same way but battle-tested in production)."
      },
      "referenceSource": {
        "repo": "lucidlylabs/strats",
        "branch": "pr-13 (PR #13: feat(dn_pt_sena): add two-vault bridge scaffold)",
        "path": "merkle_tree_generation/strategies/dn_pt_sena/",
        "leafFile": "leafs/ethereum/DnPtSenaLeafs.json (mainnet) + leafs/hyperevm/DnPtSenaHedgeLeafs.json (HL)"
      }
    }
  ]
}
