{"apps":[{"app_id":"app_0867cdd4effd","name":"DEX Aggregator V2","version":"1.0.0","intent_type":"","js_code":"// =============================================================================\n// DexAggregatorApp — JS Scoring Module\n//\n// Engine convention: score(plan, state, context)\n//   plan    = execution plan dict (metadata, interactions, calls)\n//   state   = flattened IntentState (_intent_function, order params merged)\n//   context = { simulation: {...}, state: {...}, oracle: {...}, timestamp, ... }\n//\n// Scores DEX swap execution by the RAW delivered output to the receiver — no\n// quote anchor, no gas term, no [0,1] weighting. The validator's adoption rule\n// (relative per-order) compares challenger vs champion on this raw output, read\n// from metadata.raw_output (the engine clamps `score` to [0,1], so `score` is a\n// validity sentinel only). Evaluates:\n//   1. Simulation success\n//   2. Raw output delivered to the receiver (EXACT wei, summed as BigInt)\n//   3. Validity: raw_output >= min (the slippage guard)\n// =============================================================================\n\nvar config = {\n  name: \"DexAggregator\",\n  version: \"2.0.0\",\n  type: \"dex_aggregator\",\n};\n\nfunction runtimeParams(state) {\n  return state.typed_context || state.raw_params || state.rawParams || {};\n}\n\n// Parse a token amount as EXACT integer wei (BigInt). Amounts arrive as decimal\n// strings; a non-integer / garbage amount is SKIPPED (returns null), never thrown\n// — a single bad transfer can't break the score. BigInt is whitelisted in the\n// engine's vm sandbox.\nfunction toBigIntAmount(v) {\n  if (v === null || v === undefined) return null;\n  var s = String(v).trim();\n  if (!/^[0-9]+$/.test(s)) return null; // non-negative integer wei only\n  try {\n    return BigInt(s);\n  } catch (e) {\n    return null;\n  }\n}\n\nvar manifest = {\n  intent_functions: [\n    {\n      name: \"swap\",\n      description:\n        \"Execute a token swap via the best DEX route. User specifies input/output tokens, amount, and minimum output. Solver finds optimal routing across allowed DEX targets.\",\n      params: {\n        input_token: {\n          type: \"address\",\n          description: \"Input token address\",\n          source: \"user\",\n        },\n        output_token: {\n          type: \"address\",\n          description: \"Output token address\",\n          source: \"user\",\n        },\n        input_amount: {\n          type: \"uint256\",\n          description: \"Amount of input tokens to swap\",\n          source: \"user\",\n        },\n        min_output_amount: {\n          type: \"uint256\",\n          description: \"Minimum acceptable output amount\",\n          source: \"quote\",\n          quote_field: \"suggested_min_output\",\n        },\n        receiver: {\n          type: \"address\",\n          description: \"Address to receive output tokens (defaults to submitter)\",\n          source: \"system\",\n        },\n        permit_deadline: {\n          type: \"uint256\",\n          description: \"ERC-2612 permit deadline (0 = use pre-approval)\",\n          source: \"system\",\n        },\n        permit_v: {\n          type: \"uint8\",\n          description: \"ERC-2612 permit signature v\",\n          source: \"system\",\n        },\n        permit_r: {\n          type: \"bytes32\",\n          description: \"ERC-2612 permit signature r\",\n          source: \"system\",\n        },\n        permit_s: {\n          type: \"bytes32\",\n          description: \"ERC-2612 permit signature s\",\n          source: \"system\",\n        },\n        // NOTE: the three params below are appended to intentParams but are\n        // NOT part of the on-chain `swap(address,address,uint256,uint256,address)`\n        // signature, so they set in_signature:false — otherwise they'd change\n        // the computed intent selector and dispatch would revert \"Unknown intent\".\n        platform_fee_wei: {\n          type: \"uint256\",\n          description: \"Protocol fee in wrapped-native wei (validator-computed)\",\n          source: \"quote\",\n          quote_field: \"platform_fee_wei\",\n          in_signature: false,\n        },\n        quoted_output: {\n          type: \"uint256\",\n          description:\n            \"Net output we quoted the user; the CoW-style app-fee reference (validator-set, signed in; the app charges a share of execution ABOVE this)\",\n          source: \"quote\",\n          quote_field: \"estimated_output\",\n          in_signature: false,\n        },\n        unwrap_output: {\n          type: \"bool\",\n          description:\n            \"Deliver native ETH/TAO instead of the wrapped token. Defaults to \" +\n            \"true; harmless for non-native outputs because the contract only \" +\n            \"unwraps when tokenOut == wrappedNative, so the encoder needs no \" +\n            \"token-aware logic.\",\n          source: \"system\",\n          in_signature: false,\n          default: true,\n        },\n      },\n      // Provide ONLY the params the user/system supplies. Do NOT include\n      // source:\"quote\" params (min_output_amount, platform_fee_wei,\n      // quoted_output) — the validator computes those from a live quote and\n      // injects them before execution. Hardcoding them makes the example go\n      // stale and teaches the wrong pattern.\n      example_params: {\n        input_token: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\",\n        output_token: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n        input_amount: \"1000000000000000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\",\n        permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        unwrap_output: true,\n      },\n      scoring_hints: {\n        goal: \"Maximize output tokens received relative to the quote (quotedOutput)\",\n        primary_metric: \"output_ratio (outputAmount / quotedOutput); 1.0 = met the quote, >1.0 = beat it\",\n        secondary_metrics: [\"gas_efficiency\"],\n      },\n    },\n  ],\n  // Benchmark scenarios are chain-aware. Each scenario has an optional\n  // \"chains\" field: if present, the scenario only runs on those chain IDs.\n  // If absent, it runs on all chains (backward compat).\n  //\n  // A scenario provides only the TRADE INPUTS (tokens, amount, fund). Do NOT\n  // hardcode quote-sourced params here — above, min_output_amount declares\n  // source:\"quote\" (quote_field \"suggested_min_output\"), so the validator\n  // computes it from a live quote at benchmark time and injects it before\n  // execution. A hardcoded min_output_amount goes stale as prices move: e.g. a\n  // min set when WETH was ~$2000 reverts EVERY solver with \"Too little\n  // received\" once WETH trades below that, and corrupts scoring (which is\n  // anchored on the quote, not the min). Let the quote supply the rest.\n  benchmark_scenarios: [\n    // ── Ethereum mainnet (chain 1) ──────────────────────────────────\n    {\n      name: \"WETH_to_USDC\",\n      description: \"Standard ETH to stablecoin swap (Ethereum)\",\n      chains: [1, 31337],\n      intent_function: \"swap\",\n      fund: {\n        \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\": \"1000000000000000000\",\n      },\n      params: {\n        input_token: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\",\n        output_token: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n        input_amount: \"1000000000000000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    {\n      name: \"WBTC_to_USDC\",\n      description: \"BTC to stablecoin swap (Ethereum)\",\n      chains: [1, 31337],\n      intent_function: \"swap\",\n      fund: {\n        \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\": \"10000000\",\n      },\n      params: {\n        input_token: \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\",\n        output_token: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n        input_amount: \"10000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    {\n      name: \"WBTC_to_WETH\",\n      description: \"BTC to ETH swap (Ethereum)\",\n      chains: [1, 31337],\n      intent_function: \"swap\",\n      fund: {\n        \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\": \"10000000\",\n      },\n      params: {\n        input_token: \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\",\n        output_token: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\",\n        input_amount: \"10000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    // ── Base mainnet (chain 8453) ───────────────────────────────────\n    // Tiny trades — tests concentrated liquidity efficiency\n    {\n      name: \"WETH_to_USDC_tiny\",\n      description: \"Tiny ETH to USDC swap (0.0005 ETH, Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x4200000000000000000000000000000000000006\": \"500000000000000\",\n      },\n      params: {\n        input_token: \"0x4200000000000000000000000000000000000006\",\n        output_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        input_amount: \"500000000000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    {\n      name: \"USDC_to_WETH_tiny\",\n      description: \"Tiny USDC to ETH swap (2 USDC, Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\": \"2000000\",\n      },\n      params: {\n        input_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        output_token: \"0x4200000000000000000000000000000000000006\",\n        input_amount: \"2000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    // Medium trades — realistic retail size\n    {\n      name: \"WETH_to_USDC_medium\",\n      description: \"0.1 ETH to USDC swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x4200000000000000000000000000000000000006\": \"100000000000000000\",\n      },\n      params: {\n        input_token: \"0x4200000000000000000000000000000000000006\",\n        output_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        input_amount: \"100000000000000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    {\n      name: \"USDC_to_WETH_medium\",\n      description: \"250 USDC to ETH swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\": \"250000000\",\n      },\n      params: {\n        input_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        output_token: \"0x4200000000000000000000000000000000000006\",\n        input_amount: \"250000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    // Large trades — tests deeper liquidity and price impact\n    {\n      name: \"WETH_to_USDC_large\",\n      description: \"1 ETH to USDC swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x4200000000000000000000000000000000000006\": \"1000000000000000000\",\n      },\n      params: {\n        input_token: \"0x4200000000000000000000000000000000000006\",\n        output_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        input_amount: \"1000000000000000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    {\n      name: \"USDC_to_WETH_large\",\n      description: \"2500 USDC to ETH swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\": \"2500000000\",\n      },\n      params: {\n        input_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        output_token: \"0x4200000000000000000000000000000000000006\",\n        input_amount: \"2500000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    // XL trades — stress tests price impact handling\n    {\n      name: \"WETH_to_USDC_xl\",\n      description: \"5 ETH to USDC swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x4200000000000000000000000000000000000006\": \"5000000000000000000\",\n      },\n      params: {\n        input_token: \"0x4200000000000000000000000000000000000006\",\n        output_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        input_amount: \"5000000000000000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    {\n      name: \"USDC_to_WETH_xl\",\n      description: \"10000 USDC to ETH swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\": \"10000000000\",\n      },\n      params: {\n        input_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        output_token: \"0x4200000000000000000000000000000000000006\",\n        input_amount: \"10000000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    // Cross-pair: DAI ↔ WETH — tests routing through less common pairs\n    {\n      name: \"WETH_to_DAI\",\n      description: \"0.5 ETH to DAI swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x4200000000000000000000000000000000000006\": \"500000000000000000\",\n      },\n      params: {\n        input_token: \"0x4200000000000000000000000000000000000006\",\n        output_token: \"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb\",\n        input_amount: \"500000000000000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    {\n      name: \"DAI_to_USDC\",\n      description: \"1000 DAI to USDC stablecoin swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb\": \"1000000000000000000000\",\n      },\n      params: {\n        input_token: \"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb\",\n        output_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        input_amount: \"1000000000000000000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    // cbBTC pair — Bitcoin on Base\n    {\n      name: \"cbBTC_to_USDC\",\n      description: \"0.01 cbBTC to USDC swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf\": \"1000000\",\n      },\n      params: {\n        input_token: \"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf\",\n        output_token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        input_amount: \"1000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n    {\n      name: \"cbBTC_to_WETH\",\n      description: \"0.01 cbBTC to ETH swap (Base)\",\n      chains: [8453],\n      intent_function: \"swap\",\n      fund: {\n        \"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf\": \"1000000\",\n      },\n      params: {\n        input_token: \"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf\",\n        output_token: \"0x4200000000000000000000000000000000000006\",\n        input_amount: \"1000000\",\n        receiver: \"0x0000000000000000000000000000000000000001\",\n        permit_deadline: \"0\", permit_v: \"0\",\n        permit_r: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        permit_s: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n      },\n    },\n  ],\n};\n\nfunction score(plan, state, context) {\n  var sim = context.simulation || {};\n\n  // 1. Check simulation success\n  if (!sim.success) {\n    return {\n      score: 0,\n      valid: false,\n      reason: \"Simulation failed: \" + (sim.error || \"unknown\"),\n    };\n  }\n\n  // 2. Extract order params from state (snake_case primary, camelCase fallback)\n  var params = runtimeParams(state);\n  var minAmountOut = params.min_output_amount || params.min_amount_out || params.minAmountOut || \"0\";\n  var tokenOut = (params.output_token || params.token_out || params.tokenOut || \"\").toLowerCase();\n  var receiver = (params.receiver || params.submitted_by || \"\").toLowerCase();\n  var appAddr = (state.contract_address || \"\").toLowerCase();\n\n  // 3. Analyze token transfers from simulation\n  var transfers = sim.token_transfers || sim.tokenTransfers || [];\n  var gasUsed = sim.gas_used || sim.gasUsed || 0;\n\n  if (transfers.length === 0) {\n    return { score: 0, valid: false, reason: \"No token transfers detected\" };\n  }\n\n  // Sum the output-token transfers delivered to the receiver (or the app, which\n  // delivers in _checkIntent) as EXACT integer wei (BigInt) — amounts above 2^53\n  // are not rounded by IEEE-754. A garbage/non-integer amount is skipped.\n  var total = BigInt(0);\n  for (var i = 0; i < transfers.length; i++) {\n    var t = transfers[i];\n    var toAddr = (t.to_addr || t.to || \"\").toLowerCase();\n    var tokenAddr = (t.token || t.token_address || \"\").toLowerCase();\n    // Output goes to receiver or app (app delivers in _checkIntent)\n    if (tokenAddr === tokenOut && (toAddr === receiver || toAddr === appAddr)) {\n      var amt = toBigIntAmount(t.amount !== undefined && t.amount !== null ? t.amount : t.value);\n      if (amt !== null) {\n        total += amt;\n      }\n    }\n  }\n\n  if (total === BigInt(0)) {\n    return {\n      score: 0,\n      valid: false,\n      reason: \"No output tokens received by receiver\",\n      metadata: { raw_output: \"0\" },\n    };\n  }\n\n  // 4. Validity guard: the swap must clear the slippage-guard min if one is set\n  //    (BigInt, no float). min is ONLY the execution guard — there is no scoring\n  //    anchor. (A swap that reverted on-chain would have no transfers.)\n  var minOut = toBigIntAmount(minAmountOut);\n  if (minOut === null) minOut = BigInt(0);\n  if (minOut > BigInt(0) && total < minOut) {\n    return {\n      score: 0,\n      valid: false,\n      reason: \"Output below minimum: \" + total.toString() + \" < \" + minOut.toString(),\n      metadata: { raw_output: \"0\", output_amount: total.toString(), min_amount_out: minOut.toString() },\n    };\n  }\n\n  // 5. The score carrier is metadata.raw_output, the RAW delivered output as an\n  //    EXACT DECIMAL WEI STRING — no quote anchor, no gas term, no weighting.\n  //    `score` is only a validity sentinel (1) because the engine clamps it to\n  //    [0, 1]; the adoption rule reads metadata.raw_output.\n  return {\n    score: 1,\n    valid: true,\n    reason: \"Raw output delivered: \" + total.toString() + \" (min=\" + minOut.toString() + \" gas=\" + gasUsed + \")\",\n    breakdown: {\n      min_amount_out: minOut.toString(),\n      gas_used: gasUsed,\n      num_transfers: transfers.length,\n    },\n    metadata: {\n      raw_output: total.toString(),\n      output_amount: total.toString(),\n      min_amount_out: minOut.toString(),\n    },\n  };\n}\n\nfunction validate(plan, state, context) {\n  // Structural validation before scoring\n  if (!plan || !plan.calls || plan.calls.length === 0) {\n    return { score: 0, valid: false, reason: \"Empty execution plan\" };\n  }\n\n  var params = runtimeParams(state);\n  var tokenIn = params.input_token || params.tokenIn || params.token_in || \"\";\n  var tokenOut = params.output_token || params.tokenOut || params.token_out || \"\";\n  if (!tokenIn || !tokenOut) {\n    return {\n      score: 0,\n      valid: false,\n      reason: \"Missing input_token or output_token in state\",\n    };\n  }\n  if (tokenIn.toLowerCase() === tokenOut.toLowerCase()) {\n    return { score: 0, valid: false, reason: \"input_token == output_token\" };\n  }\n\n  return { score: 0, valid: true, reason: \"Validation passed\" };\n}\n\nmodule.exports = {\n  config: config,\n  manifest: manifest,\n  score: score,\n  validate: validate,\n  get_manifest: function () {\n    return manifest;\n  },\n};","solidity_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\nimport \"minotaur_contracts/src/AppIntentBaseV2.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\";\n\n/// @title DexAggregatorAppV2 - Gas-optimized DexAggregatorApp\n/// @notice Identical swap/bridge/fee/scoring semantics to DexAggregatorApp.\n///         Differences (each marked `V2:`):\n///\n///         1. Inherits AppIntentBaseV2 (per-order executor clones, transient\n///            snapshots/guard, lean replay protection).\n///\n///         2. APP-mode protocol fee is paid from a WETH float held BY THIS\n///            CONTRACT (safeTransfer) instead of pulled from an external\n///            paymaster (safeTransferFrom). Same consolidated,\n///            direction-independent settlement as V1's\n///            `_settleAppProtocolFee` — never skimmed from the user's\n///            output, identical fee incidence for every order — and the\n///            base still verifies the collector balance delta, so the fee\n///            stays mandatory. What's saved is the per-swap allowance\n///            bookkeeping. Operators fund the app directly instead of\n///            approving from a paymaster address; `withdrawFloat` lets the\n///            relayer recover the float.\ncontract DexAggregatorAppV2 is AppIntentBaseV2 {\n    using SafeERC20 for IERC20;\n\n    // ── Constants ──────────────────────────────────────────────────────────\n\n    bytes4 public constant SWAP_SELECTOR = bytes4(keccak256(\n        \"swap(address,address,uint256,uint256,address)\"\n    ));\n\n    bytes4 public constant BRIDGE_SELECTOR = bytes4(keccak256(\n        \"bridge(address,uint256,uint256,address)\"\n    ));\n\n    // ── State ──────────────────────────────────────────────────────────────\n\n    uint256 public feeBps;\n\n    /// @notice The app developer/owner. May recover the WETH fee float\n    ///         independently of the relayer (their money, their exit) — the\n    ///         float model must not make developers custodially dependent on\n    ///         the relayer for a version migration. NOT a constructor arg so\n    ///         V2 stays argument-compatible with existing deploy tooling:\n    ///         the relayer bootstraps it once via setAppOwner, after which\n    ///         the owner can rotate it without the relayer.\n    address public appOwner;\n    uint256 public volumeCapBps;\n    uint256 public constant DEFAULT_VOLUME_CAP_BPS = 98;\n    address public feeCollector;\n\n    // ── Events ─────────────────────────────────────────────────────────────\n\n    event SwapExecuted(\n        bytes32 indexed orderId,\n        address indexed user,\n        address tokenIn,\n        address tokenOut,\n        uint256 amountIn,\n        uint256 amountOut,\n        uint256 fee\n    );\n\n    event FeeCollectorUpdated(address indexed newCollector);\n    event FeeBpsUpdated(uint256 newFeeBps);\n    event VolumeCapBpsUpdated(uint256 newVolumeCapBps);\n    event FloatWithdrawn(address indexed to, uint256 amount);\n    event AppOwnerUpdated(address indexed newOwner);\n\n    // ── Constructor ────────────────────────────────────────────────────────\n\n    constructor(\n        address _relayer,\n        address _validatorRegistry,\n        uint256 _scoreThreshold,\n        address _wrappedNativeToken,\n        address _platformFeeCollector,\n        uint256 _minPlatformFeeWei,\n        uint256 _maxPlatformFeeWei,\n        AppIntentBaseV2.FeeMode _feeMode,\n        address _appPaymaster,\n        address _appRegistry,\n        address _feeCollector,\n        uint256 _feeBps\n    ) AppIntentBaseV2(\n        _relayer,\n        _validatorRegistry,\n        _scoreThreshold,\n        _wrappedNativeToken,\n        _platformFeeCollector,\n        _minPlatformFeeWei,\n        _maxPlatformFeeWei,\n        _feeMode,\n        _appPaymaster == address(0) ? _feeCollector : _appPaymaster,\n        _appRegistry\n    ) {\n        require(_feeCollector != address(0), \"Invalid fee collector\");\n        require(_feeBps <= 10000, \"Fee too high\");\n        feeCollector = _feeCollector;\n        feeBps = _feeBps;\n        volumeCapBps = DEFAULT_VOLUME_CAP_BPS;\n        registeredIntents[SWAP_SELECTOR] = true;\n        registeredIntents[BRIDGE_SELECTOR] = true;\n    }\n\n    // ── Admin ──────────────────────────────────────────────────────────────\n\n    modifier onlyRelayerOrAppOwner() {\n        require(\n            msg.sender == relayer\n                || (appOwner != address(0) && msg.sender == appOwner),\n            \"Not relayer or app owner\"\n        );\n        _;\n    }\n\n    /// @notice Bootstrap or rotate the app owner. Relayer sets it initially\n    ///         (constructor compatibility — see appOwner docs); afterwards\n    ///         the owner can hand it over themselves.\n    function setAppOwner(address _appOwner) external onlyRelayerOrAppOwner {\n        require(_appOwner != address(0), \"Invalid app owner\");\n        appOwner = _appOwner;\n        emit AppOwnerUpdated(_appOwner);\n    }\n\n    function setFeeCollector(address _feeCollector) external onlyRelayer {\n        require(_feeCollector != address(0), \"Invalid fee collector\");\n        feeCollector = _feeCollector;\n        emit FeeCollectorUpdated(_feeCollector);\n    }\n\n    function setFeeBps(uint256 _feeBps) external onlyRelayer {\n        require(_feeBps <= 10000, \"Fee too high\");\n        feeBps = _feeBps;\n        emit FeeBpsUpdated(_feeBps);\n    }\n\n    function setVolumeCapBps(uint256 _volumeCapBps) external onlyRelayer {\n        require(_volumeCapBps <= 10000, \"Cap too high\");\n        volumeCapBps = _volumeCapBps;\n        emit VolumeCapBpsUpdated(_volumeCapBps);\n    }\n\n    /// @notice V2: recover WETH float parked on this contract for protocol\n    ///         fees. Safe to call between orders — mid-order the base's fee\n    ///         verification would revert the swap if the float goes missing.\n    ///         Callable by the relayer OR the app owner: the float is the\n    ///         app funder's money, and migrating to a new contract version\n    ///         must not require the relayer's cooperation to exit.\n    function withdrawFloat(address to, uint256 amount) external onlyRelayerOrAppOwner {\n        require(to != address(0), \"Invalid recipient\");\n        wrappedNativeToken.safeTransfer(to, amount);\n        emit FloatWithdrawn(to, amount);\n    }\n\n    // ── Fee calculation override ──────────────────────────────────────────\n\n    function _calculateProtocolFee(\n        IntentOrder calldata order\n    ) internal view override returns (uint256) {\n        if (order.intentSelector == SWAP_SELECTOR) {\n            bytes calldata p = order.intentParams;\n            if (p.length < 96) return 0;\n            return abi.decode(p[p.length - 96:p.length - 64], (uint256));\n        }\n        return _decodePlatformFee(order.intentParams);\n    }\n\n    // ── Protocol fee settlement (APP mode) ─────────────────────────────────\n\n    /// @notice Settle the APP-mode protocol fee — direction-independent,\n    ///         shared by `_swap` and `_bridge` (mirrors V1's\n    ///         `_settleAppProtocolFee`).\n    /// @dev V2: paid via safeTransfer from the WETH float held by THIS\n    ///      contract, not safeTransferFrom an external paymaster — drops the\n    ///      per-swap allowance read/write. Never sourced from the user or\n    ///      skimmed from the swap output, so fee incidence is identical for\n    ///      every order regardless of trade direction.\n    ///\n    ///      USER mode is settled by AppIntentBaseV2 before `_handleIntent`\n    ///      runs, and the native-input path (`msg.value > 0`) is settled\n    ///      there too — both are no-ops here. The base's\n    ///      `_verifyFeeSettlementPost` confirms `platformFeeCollector` grew\n    ///      by `feeOwed`, so a silent skip reverts the whole order.\n    function _settleAppProtocolFee(IntentOrder calldata order) internal {\n        if (feeMode != AppIntentBaseV2.FeeMode.APP || msg.value != 0) return;\n        uint256 raw = _calculateProtocolFee(order);\n        if (raw == 0) return;\n        uint256 platformFee = _clampFee(raw);\n        if (platformFee == 0) return;\n        IERC20(address(wrappedNativeToken)).safeTransfer(platformFeeCollector, platformFee);\n    }\n\n    // ── Intent dispatch ────────────────────────────────────────────────────\n\n    function _handleIntent(\n        IntentOrder calldata order,\n        ExecutionPlan calldata plan\n    ) internal override returns (uint256 score, bool valid) {\n        if (order.intentSelector == SWAP_SELECTOR) {\n            return _swap(order, plan);\n        }\n        if (order.intentSelector == BRIDGE_SELECTOR) {\n            return _bridge(order, plan);\n        }\n        revert(\"Unknown intent\");\n    }\n\n    // ── Intent functions ────────────────────────────────────────────────────\n\n    function _swap(\n        IntentOrder calldata order,\n        ExecutionPlan calldata plan\n    ) internal returns (uint256 score, bool valid) {\n        (\n            address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, address receiver,\n            uint256 permitDeadline, uint8 permitV, bytes32 permitR, bytes32 permitS,\n            , // platformFeeWei — read + settled via _settleAppProtocolFee/_calculateProtocolFee\n            uint256 quotedOutput,\n            bool unwrapOutput\n        ) = abi.decode(order.intentParams, (address, address, uint256, uint256, address, uint256, uint8, bytes32, bytes32, uint256, uint256, bool));\n\n        require(tokenIn != tokenOut, \"Same token\");\n\n        // 1. Collect user tokens and execute plan.\n        _snapshot(tokenOut);\n        _tryPermit(tokenIn, order.submittedBy, amountIn, permitDeadline, permitV, permitR, permitS);\n        _fundAndExecute(order, plan, tokenIn, order.submittedBy, amountIn);\n\n        // 2. Check invariant: did user get expected output?\n        uint256 gained = _gained(tokenOut);\n        if (gained < minAmountOut) return (0, false);\n\n        // 3. Deliver the protocol fee in WETH from the app's float (APP mode).\n        //    Direction-independent and shared with _bridge — never skimmed\n        //    from the user's output, even when tokenOut == WETH. The base\n        //    verifies the collector balance grew by ≥ feeOwed after\n        //    _handleIntent returns; a silent skip reverts the order.\n        _settleAppProtocolFee(order);\n\n        // 4. Capture price improvement over the quoted output (unchanged).\n        uint256 fee = 0;\n        if (quotedOutput > 0 && gained > quotedOutput) {\n            fee = ((gained - quotedOutput) * feeBps) / 10000;\n            uint256 cap = (gained * volumeCapBps) / 10000;\n            if (fee > cap) fee = cap;\n            uint256 surplusOverMin = gained - minAmountOut;\n            if (fee > surplusOverMin) fee = surplusOverMin;\n        }\n        uint256 userAmount = gained - fee;\n\n        if (unwrapOutput && tokenOut == address(wrappedNativeToken) && userAmount > 0) {\n            IWETH(address(wrappedNativeToken)).withdraw(userAmount);\n            (bool sent,) = payable(receiver).call{value: userAmount}(\"\");\n            require(sent, \"ETH delivery failed\");\n        } else {\n            IERC20(tokenOut).safeTransfer(receiver, userAmount);\n        }\n        if (fee > 0) IERC20(tokenOut).safeTransfer(feeCollector, fee);\n\n        score = _scoreSwap(gained, minAmountOut, quotedOutput);\n        valid = true;\n\n        emit SwapExecuted(order.orderId, order.submittedBy, tokenIn, tokenOut, amountIn, gained, fee);\n    }\n\n    uint256 private constant PAR_SCORE = 7500;\n\n    function _scoreSwap(\n        uint256 gained,\n        uint256 minOut,\n        uint256 quote\n    ) private pure returns (uint256) {\n        if (gained <= minOut) return 5000;\n        if (quote > minOut && gained <= quote) {\n            return 5000 + ((gained - minOut) * (PAR_SCORE - 5000)) / (quote - minOut);\n        }\n        uint256 par      = quote > minOut ? quote : minOut;\n        uint256 parScore = quote > minOut ? PAR_SCORE : 5000;\n        uint256 decay = ((10000 - parScore) * par) / gained;\n        if (decay == 0) decay = 1;\n        return 10000 - decay;\n    }\n\n    // ── Bridge intent ─────────────────────────────────────────────────────────\n\n    event BridgeExecuted(\n        bytes32 indexed orderId,\n        address indexed user,\n        address tokenIn,\n        uint256 amountBridged\n    );\n\n    function _bridge(\n        IntentOrder calldata order,\n        ExecutionPlan calldata plan\n    ) internal returns (uint256 score, bool valid) {\n        (\n            address tokenIn,\n            uint256 amountIn,\n            uint256 minBridged,\n            address receiver,\n            /* uint256 platformFeeWei — consumed via _calculateProtocolFee() */\n        ) = abi.decode(order.intentParams, (address, uint256, uint256, address, uint256));\n\n        address proxy = _deployProxy(order);\n        IERC20(tokenIn).safeTransferFrom(order.submittedBy, proxy, amountIn);\n        _runPlan(proxy, plan);\n\n        uint256 remaining = IERC20(tokenIn).balanceOf(proxy);\n        uint256 bridged = amountIn - remaining;\n        if (bridged < minBridged) return (0, false);\n\n        // 3. App-mode protocol fee from the app's own WETH float (same\n        //    consolidated path as _swap).\n        _settleAppProtocolFee(order);\n\n        score = _scoreLinear(bridged, minBridged);\n        valid = true;\n\n        emit BridgeExecuted(order.orderId, order.submittedBy, tokenIn, bridged);\n    }\n\n    // ── Helpers ──────────────────────────────────────────────────────────────\n\n    function _tryPermit(\n        address token, address owner, uint256 amount,\n        uint256 deadline, uint8 v, bytes32 r, bytes32 s\n    ) internal {\n        if (deadline > 0) {\n            try IERC20Permit(token).permit(owner, address(this), amount, deadline, v, r, s) {} catch {}\n        }\n    }\n}","config":{"supported_chains":[8453,1,964],"score_threshold":0.5,"on_chain_threshold":5000,"trigger_type":"user_triggered","max_gas":500000,"policy_tier":"hybrid","supported_policy_tiers":["strict","hybrid","expert"],"manifest_version":"v1","fee_mode":""},"deployer":"0x7dC30109A32764f808823095C576A0355b7978d6","description":"","manifest":{"intent_functions":[{"name":"swap","description":"Execute a token swap via the best DEX route. User specifies input/output tokens, amount, and minimum output. Solver finds optimal routing across allowed DEX targets.","params":{"input_token":{"type":"address","description":"Input token address","source":"user"},"output_token":{"type":"address","description":"Output token address","source":"user"},"input_amount":{"type":"uint256","description":"Amount of input tokens to swap","source":"user"},"min_output_amount":{"type":"uint256","description":"Minimum acceptable output amount","source":"quote","quote_field":"suggested_min_output"},"receiver":{"type":"address","description":"Address to receive output tokens (defaults to submitter)","source":"system"},"permit_deadline":{"type":"uint256","description":"ERC-2612 permit deadline (0 = use pre-approval)","source":"system"},"permit_v":{"type":"uint8","description":"ERC-2612 permit signature v","source":"system"},"permit_r":{"type":"bytes32","description":"ERC-2612 permit signature r","source":"system"},"permit_s":{"type":"bytes32","description":"ERC-2612 permit signature s","source":"system"},"platform_fee_wei":{"type":"uint256","description":"Protocol fee in wrapped-native wei (validator-computed)","source":"quote","quote_field":"platform_fee_wei","in_signature":false},"quoted_output":{"type":"uint256","description":"Net output we quoted the user; the CoW-style app-fee reference (validator-set, signed in; the app charges a share of execution ABOVE this)","source":"quote","quote_field":"estimated_output","in_signature":false},"unwrap_output":{"type":"bool","description":"Deliver native ETH/TAO instead of the wrapped token. Defaults to true; harmless for non-native outputs because the contract only unwraps when tokenOut == wrappedNative, so the encoder needs no token-aware logic.","source":"system","in_signature":false,"default":true}},"example_params":{"input_token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","output_token":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","input_amount":"1000000000000000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000","unwrap_output":true},"scoring_hints":{"goal":"Maximize output tokens received relative to the quote (quotedOutput)","primary_metric":"output_ratio (outputAmount / quotedOutput); 1.0 = met the quote, >1.0 = beat it","secondary_metrics":["gas_efficiency"]}}],"benchmark_scenarios":[{"name":"WETH_to_USDC","description":"Standard ETH to stablecoin swap (Ethereum)","chains":[1,31337],"intent_function":"swap","fund":{"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2":"1000000000000000000"},"params":{"input_token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","output_token":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","input_amount":"1000000000000000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"WBTC_to_USDC","description":"BTC to stablecoin swap (Ethereum)","chains":[1,31337],"intent_function":"swap","fund":{"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599":"10000000"},"params":{"input_token":"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599","output_token":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","input_amount":"10000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"WBTC_to_WETH","description":"BTC to ETH swap (Ethereum)","chains":[1,31337],"intent_function":"swap","fund":{"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599":"10000000"},"params":{"input_token":"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599","output_token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","input_amount":"10000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"WETH_to_USDC_tiny","description":"Tiny ETH to USDC swap (0.0005 ETH, Base)","chains":[8453],"intent_function":"swap","fund":{"0x4200000000000000000000000000000000000006":"500000000000000"},"params":{"input_token":"0x4200000000000000000000000000000000000006","output_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","input_amount":"500000000000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"USDC_to_WETH_tiny","description":"Tiny USDC to ETH swap (2 USDC, Base)","chains":[8453],"intent_function":"swap","fund":{"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913":"2000000"},"params":{"input_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","output_token":"0x4200000000000000000000000000000000000006","input_amount":"2000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"WETH_to_USDC_medium","description":"0.1 ETH to USDC swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0x4200000000000000000000000000000000000006":"100000000000000000"},"params":{"input_token":"0x4200000000000000000000000000000000000006","output_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","input_amount":"100000000000000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"USDC_to_WETH_medium","description":"250 USDC to ETH swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913":"250000000"},"params":{"input_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","output_token":"0x4200000000000000000000000000000000000006","input_amount":"250000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"WETH_to_USDC_large","description":"1 ETH to USDC swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0x4200000000000000000000000000000000000006":"1000000000000000000"},"params":{"input_token":"0x4200000000000000000000000000000000000006","output_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","input_amount":"1000000000000000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"USDC_to_WETH_large","description":"2500 USDC to ETH swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913":"2500000000"},"params":{"input_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","output_token":"0x4200000000000000000000000000000000000006","input_amount":"2500000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"WETH_to_USDC_xl","description":"5 ETH to USDC swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0x4200000000000000000000000000000000000006":"5000000000000000000"},"params":{"input_token":"0x4200000000000000000000000000000000000006","output_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","input_amount":"5000000000000000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"USDC_to_WETH_xl","description":"10000 USDC to ETH swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913":"10000000000"},"params":{"input_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","output_token":"0x4200000000000000000000000000000000000006","input_amount":"10000000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"WETH_to_DAI","description":"0.5 ETH to DAI swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0x4200000000000000000000000000000000000006":"500000000000000000"},"params":{"input_token":"0x4200000000000000000000000000000000000006","output_token":"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb","input_amount":"500000000000000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"DAI_to_USDC","description":"1000 DAI to USDC stablecoin swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb":"1000000000000000000000"},"params":{"input_token":"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb","output_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","input_amount":"1000000000000000000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"cbBTC_to_USDC","description":"0.01 cbBTC to USDC swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf":"1000000"},"params":{"input_token":"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf","output_token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","input_amount":"1000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"name":"cbBTC_to_WETH","description":"0.01 cbBTC to ETH swap (Base)","chains":[8453],"intent_function":"swap","fund":{"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf":"1000000"},"params":{"input_token":"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf","output_token":"0x4200000000000000000000000000000000000006","input_amount":"1000000","receiver":"0x0000000000000000000000000000000000000001","permit_deadline":"0","permit_v":"0","permit_r":"0x0000000000000000000000000000000000000000000000000000000000000000","permit_s":"0x0000000000000000000000000000000000000000000000000000000000000000"}}]},"constructor_args":[["address","0xD4cF78059243fAED77350f2dD7e73d5300465D70"],["uint256","5000"]],"schema_id":"","policy_metadata":{"registration":{"approved_by":"admin"}},"contract_version":"v2","registration_status":"approved","status":"solved","deployments":{"1":{"status":"solved","contract_address":"0x01CC8304249A77C206028ec940476B4ed96a770c"},"8453":{"status":"solved","contract_address":"0x694257bE3a38Fff6f657468Ae3eC7D38C8Ea0E59"}}}],"total":1,"catalog_fingerprint":"c97cc76b86858a6208b2cbddc74cfd36242613f63b481d4f70cdb0598492746f"}