AI 辅助 DeFi 策略生成:从自然语言描述到可安全部署合约的完整链路

AI 辅助 DeFi 策略生成:从自然语言描述到可安全部署合约的完整链路

一、把交易想法变成可部署合约,中间的断层比想象中大

DeFi 策略的描述可能只是一句"当 ETH 价格低于 2000 时,用 USDC 市价买入 1 ETH,同时挂一个 2100 的限价卖单"。这个描述到链上可执行合约之间,隔着参数解析、交易路径计算、滑点保护、授权管理、Gas 估算、错误回滚和链上最终验证。

如果每一步都由人工完成,从需求到部署可能需要数小时——其中大部分时间不是在写逻辑,而是在处理跨协议适配(这个 DEX 用swapExactTokensForTokens,那个用exactInput)、精度换算(某些 token 是 6 位小数,某些是 18 位)和边缘情况(链重组时订单状态怎么办)。

AI 辅助的 DeFi 策略生成不是让大模型直接输出 Solidity 代码部署上链,而是建立一条从自然语言 → 结构化策略描述 → 代码生成 → 静态验证 → 模拟执行 → 安全约束检查 → 最终部署的完整管线。

二、管线架构:每次转换都有可验证的中间产物

flowchart TD A["自然语言策略<br/>当ETH低于2000买1ETH"] --> B[策略解析器<br/>提取: 条件/资产/金额/动作] B --> C[结构化策略定义<br/>JSON Schema] C --> D[AI 代码生成<br/>策略 → Solidity 合约] D --> E[静态分析<br/>Slither + Gas 估算] E --> F[Fork 模拟执行<br/>Hardhat/Foundry Fork] F --> G[安全约束检查<br/>滑点/最大授权/重入] G --> H{通过所有检查?} H -->|否| I[AI 修正建议 → 回 D] H -->|是| J[生成部署脚本 + 安全检查清单] J --> K[用户签名确认部署]

每步都有明确的输入输出格式,中间产物可以独立审查。关键设计是"每一步都有可验证的输出"——策略解析器输出 JSON Schema,AI 生成的代码必须通过 Slither 的零警告检查,Fork 模拟的输出必须包含 Gas 报告和预期盈亏。

三、生产级实现:四阶段管线

阶段一:策略解析器——把自然语言变成结构化定义

from dataclasses import dataclass from typing import Optional, Literal from enum import Enum import json class ActionType(Enum): SWAP = "swap" LIMIT_ORDER = "limit_order" STAKE = "stake" PROVIDE_LIQUIDITY = "provide_liquidity" class ConditionType(Enum): PRICE_BELOW = "price_below" PRICE_ABOVE = "price_above" TIME_AFTER = "time_after" @dataclass class DeFiStrategy: """ 结构化策略定义——管线的第一个中间产物 设计决策: - 所有金额用最小单位(wei)避免小数精度问题 - chainId 必填,防止跨链误操作 - 可选条件为空列表表示无条件执行 """ chain_id: int conditions: list[dict] # 触发条件列表 actions: list[dict] # 执行动作列表(有序) max_slippage_bps: int # 最大滑点(基点,100 = 1%) gas_limit: int # Gas 上限 deadline_minutes: int # 交易过期时间(分钟) is_one_shot: bool # 一次性还是持续监控 def parse_natural_language_to_strategy(nl: str) -> DeFiStrategy: """ 策略解析器 设计决策: - 使用结构化 prompt 而非开放式——输出格式必须可控 - 解析失败返回空策略 + 错误原因,不做 silent fallback - 解析到的所有金额都做安全上限检查 """ system_prompt = """ 你是 DeFi 策略解析器。将用户的自然语言策略描述转换为以下 JSON 格式: { "chain_id": 1, // 1=Ethereum, 42161=Arbitrum, 10=Optimism "conditions": [ {"type": "price_below", "asset": "ETH", "price_usd": 2000} ], "actions": [ {"type": "swap", "from": "USDC", "to": "ETH", "amount": "1000000000", "dex": "uniswap_v3"} ], "max_slippage_bps": 100, "gas_limit": 500000, "deadline_minutes": 20, "is_one_shot": true } 约束: - 金额使用最小单位(USDC 6 位小数,ETH 18 位小数) - chainId 必须从 [1, 42161, 10, 137, 8453] 中选 - max_slippage_bps 默认 100(1%),最高 500 - 安全:如果描述中含"无限授权"或"unlimited approval",标记为不安全策略 如果策略包含不安全操作,在 response 中设置 `unsafe: true` 和 `safety_concern` 字段。 """ # 实际实现用 LLM API 调用,这里展示结构化 prompt 设计 # response = llm.chat(system_prompt, nl) # return DeFiStrategy(**response) pass

阶段二:AI 代码生成——约束驱动的合约编写

def generate_strategy_contract(strategy: DeFiStrategy) -> str: """ 从结构化策略生成 Solidity 合约 设计决策: - 不使用单次 GPT 输出直接部署的方式——必须分步 - 先生成合约骨架(接口定义),再填充逻辑 - 每一步都注入安全约束模板 """ # 安全约束模板——每次代码生成必经的约束注入 safety_template = f""" 生成的合约必须满足以下安全约束: 1. 使用 OpenZeppelin ReentrancyGuard(所有外部调用函数) 2. 滑点保护:{strategy.max_slippage_bps} bps - 买入时 amountOutMin = 期望输出 × (10000 - 滑点) / 10000 - 卖出时 amountInMax = 期望输入 × (10000 + 滑点) / 10000 3. 批准额度:只批准本次交易所需额度,不使用 type(uint256).max 4. Gas 上限:{strategy.gas_limit},超过此值不执行 5. 过期保护:交易{strategy.deadline_minutes}分钟后自动失效 6. Token 安全: - 使用 safeTransfer/safeTransferFrom(处理 USDT 等不返 bool 的 token) - 使用 safeApprove,先 approve(0) 再 approve(amount) 7. 重入防护:所有函数使用 nonReentrant modifier 8. 任何人可调用:execute() 函数应为 external 且任何人可调用 - 利润归 msg.sender 作为执行激励 """ contract_prompt = f""" 基于以下策略生成智能合约: 策略定义:{json.dumps(strategy.__dict__, indent=2)} {safety_template} 要求: - 版本 pragma ^0.8.24 - 继承 ReentrancyGuard - 所有函数有完整 Natspec 注释 - 事件日志完整(策略执行前后的状态变化) """ # 实际实现调用 LLM # return llm.generate(contract_prompt) pass

阶段三:Fork 模拟执行

// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "forge-std/Test.sol"; /** * @notice 策略模拟测试 * * 设计决策: * - 使用 Foundry fork 模式,在 Ethereum 主网状态上模拟 * - fork_block_number 固定到具体区块,保证测试可复现 * - 测试覆盖:正常路径、价格边界、滑点边界、过期路径 */ contract StrategyForkTest is Test { uint256 constant FORK_BLOCK = 20000000; function setUp() public { // Fork Ethereum 主网到固定区块 vm.createSelectFork("mainnet", FORK_BLOCK); } function testExecuteStrategy_NormalPath() public { // 部署策略合约 GeneratedStrategy strategy = new GeneratedStrategy(); // 给测试地址充 USDC(从 Binance 地址借——fork 模式特性) address usdcWhale = 0x28C6c06298d514Db089934071355E5743bf21d60; address usdc = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; vm.startPrank(usdcWhale); IERC20(usdc).transfer(address(this), 1000 * 1e6); vm.stopPrank(); // 执行策略 uint256 gasBefore = gasleft(); strategy.execute(); uint256 gasUsed = gasBefore - gasleft(); // 验证 gas 不超过上限 assertLe(gasUsed, 500_000, "Gas exceeds limit"); // 验证余额变化(至少收到了 ETH) assertGt(address(this).balance, 0, "No ETH received"); // 验证无剩余授权(安全:执行完必须 revoke) assertEq(IERC20(usdc).allowance(address(strategy), address(this)), 0, "Allowance not revoked"); } function testExecuteStrategy_Expired() public { GeneratedStrategy strategy = new GeneratedStrategy(); // 快进到过期之后 vm.warp(block.timestamp + 30 minutes); vm.expectRevert("Expired"); strategy.execute(); } }

阶段四:安全约束检查与部署

def safety_check_and_deploy(strategy: DeFiStrategy, contract_code: str) -> dict: """ 部署前最终安全检查 任何一项不通过都不允许部署——没有"警告后可忽略" """ checks = [] # 1. Slither 静态分析 slither_result = run_slither(contract_code) if slither_result.warnings: checks.append({ "check": "Slither", "passed": False, "detail": [str(w) for w in slither_result.warnings] }) # 2. 禁止高危模式检查 high_risk_patterns = { "unlimited_approval": r"type\(uint256\)\.max", "unchecked_call": r"\.call\{value:", "tx_origin": r"tx\.origin", "block_timestamp_dependency": r"block\.timestamp\s*[<>=]", "selfdestruct": r"selfdestruct", } for name, pattern in high_risk_patterns.items(): if re.search(pattern, contract_code): checks.append({ "check": f"Forbidden pattern: {name}", "passed": False, "detail": f"Contract contains {name}, which must be manually reviewed" }) # 3. Fork 模拟通过 fork_result = run_fork_simulation(contract_code) if not fork_result.all_tests_passed: checks.append({ "check": "Fork simulation", "passed": False, "detail": fork_result.failures }) # 4. Gas 上限检查 if fork_result.gas_used > strategy.gas_limit: checks.append({ "check": "Gas limit", "passed": False, "detail": f"Gas used {fork_result.gas_used} > limit {strategy.gas_limit}" }) all_passed = all(c["passed"] for c in checks) if checks else True return { "can_deploy": all_passed, "checks": checks, "deployment_script": generate_deploy_script(contract_code) if all_passed else None }

四、边界分析:管线不是无人值守的自动提款机

管线能保证什么:

  • 策略的语法安全:无重入、无无限授权、无过期风险
  • Gas 可预测:Fork 模拟给出实际 Gas 消耗,不会上线后才发现跑不动
  • 可审计:中间产物(结构化策略、生成代码、模拟报告)可独立审查

管线不能保证什么:

  • 策略的经济合理性:管线不判断"ETH 低于 2000 买入"是否是好策略。经济风险由用户自行承担
  • 市场流动性:Fork 模拟使用历史区块的快照,不代表未来市场流动性。策略可能因流动性不足而失败
  • 多策略竞争:两个用户的策略可能在同一区块内竞争(如抢同一个限价单),管线不处理 MEV 博弈

禁用场景:

  • 涉及闪电贷的策略——Fork 模拟无法准确复现闪电贷的三明治攻击向量
  • 跨链策略——不同链的区块时间、最终化时间、桥延迟使"同时执行"难以保证
  • 超高频策略(毫秒级)——区块确认时间(12 秒)是硬瓶颈

管线还有一个隐蔽限制:AI 生成的代码可能包含针对静态分析和 Fork 模拟的"过拟合"优化——看起来通过了检查,但利用了测试环境的特点。防御策略是让 Slither 规则、安全检查和 Fork 测试参数定期轮换,防止管线被刻意优化适应。

策略版本化管理:

管线产出的合约是策略的一次性快照,而非持续运行的服务。每次策略调整都需要重新走完整管线,生成新合约地址。这意味着用户不能"修改"一个已有的策略合约——只能撤回旧合约的资产,部署新合约。这带来两个问题:一是旧合约的遗留授权(allowance)需要用户手动 revoke;二是策略迭代的 Gas 成本(部署 + 授权)叠加。一个更好的方案是策略合约设计为"路由器"模式:策略参数存在链下,路由器合约每次查询最新参数后执行。但这又引入了参数更新权限和链下依赖的新信任假设。

五、总结

AI 辅助 DeFi 策略生成的关键不是让模型直接输出可部署代码,而是建立一条四阶段管线:策略解析(NL → 结构化 JSON)、约束驱动代码生成、Fork 模拟执行、安全约束检查。

每步都有可验证的中间产物,任何检查不通过都阻塞部署。管线能保证语法安全和 Gas 可预测,但不能保证经济合理性。涉及闪电贷、跨链和超高频的策略需要人工分析。安全检查规则应定期轮换,防止管线被刻意过拟合。