【免费下载链接】Decepticon
Autonomous Hacking Agent for Red Team
本篇以 Decepticon 开源仓库中 contracts/mev-sandwich 技能文档 为骨架,完整讲解 MEV 三明治攻击(Sandwich Attack)从 mempool 交易流监控、可获利性判定、Flashbots 捆绑包构造,到 JIT 流动性捕获、多区块 MEV 与防御对抗的完整链路,并深入当前仓库的 Skill 系统源码,说明这份技能如何被 Agent 按需加载、校验与约束。读完你将掌握:在测试网络或自持目标上复现三明治攻击的完整技术流程、盈利性数学判断,以及如何从攻击者与防御者双重视角评估 DEX 交易的安全性。
技能定位:一份可被 Agent 按需加载的 MEV 战术手册
在 Decepticon 中,mev-sandwich是contracts(智能合约审计)车道下的一份独立技能,存放在packages/decepticon/decepticon/skills/standard/contracts/mev-sandwich/SKILL.md。其 frontmatter 定义了这份技能的元数据,是整个 Skill 系统路由与校验的入口:
--- name: contracts-mev-sandwich description: "MEV sandwich attacks — front-run + back-run a victim swap on Uniswap V2/V3, Curve, Balancer; mempool monitoring via Flashbots / private RPC, slippage tolerance exploitation, JIT liquidity sandwich, multi-block MEV." allowed-tools: Bash Read Write metadata: when_to_use: "mev sandwich front-run back-run uniswap v2 v3 curve balancer slippage flashbots private mempool jit liquidity searcher" subdomain: contracts tags: defi, mev, front-running, dex mitre_attack: T1565.002 ---这些字段并非摆设,它们直接驱动着 Skill 系统的行为:
when_to_use:Agent 在做目标匹配时的触发关键词。当任务中出现mev、sandwich、front-run、back-run、uniswap、slippage、flashbots、jit liquidity等词时,技能目录会把这份技能列为匹配项。mitre_attack: T1565.002:MITRE ATT&CK 技术编号(数据操纵—传输数据操纵),技能目录展示时会内联显示,让 Agent 具备 ATT&CK 感知能力。allowed-tools: Bash Read Write:声明执行本技能允许使用的工具面。
在 middleware/skills.py 中,_format_skills_list会按subdomain分组渲染技能目录:每条技能展示「描述 + MITRE 标签 + 触发关键词 +load_skill(...)路径」。也就是说,这份三明治技能会以如下形态出现在 Agent 的系统提示词中:
- **contracts-mev-sandwich**: MEV sandwich attacks — ... [T1565.002] triggers: mev sandwich front-run back-run uniswap v2 v3 curve balancer slippage flashbots private mempool jit liquidity searcher `load_skill("/skills/standard/contracts/mev-sandwich/SKILL.md")`而 tools/skills.py 中的load_skill工具负责真正读取文件:它接受精确的/skills/.../*.md路径、相对路径或唯一 slug(如mev-sandwich),剥离 frontmatter 后返回完整正文(不受行数限制),并附带同目录references/索引。这正是「技能优先」原则的落地——当任务命中触发词时,Agent 必须先加载技能再行动,而不是凭记忆操作。
第一步:识别可被三明治的受害者交易
三明治攻击的前提是「看到」一笔受害者交易。技能文档给出的核心思路是:先流式监控待确认交易(pending transactions),再过滤出 DEX 换币交易并评估其滑点容忍度。
# Stream pending transactions from web3 import Web3 w3 = Web3(Web3.HTTPProvider("https://eth.merkle.io")) # Or: subscribe to alchemy/blocknative streams # Filter for Uniswap V2 swapExactTokensForTokens or V3 exactInputSingle # Look at the swap amount + slippage tolerance (deadline + minAmountOut) # Sandwichable when: swap_amount * slippage > sandwich_gas_cost * 2关键点在于过滤条件与判定逻辑:
- 交易类型过滤:关注 Uniswap V2 的
swapExactTokensForTokens、V3 的exactInputSingle这类「给定输入、按路径输出」的换币调用。它们暴露了明确的输入金额,便于推算价格影响。 - 滑点容忍度读取:V2 的
amountOutMin+deadline、V3 的minAmountOut直接决定了受害者的价格保护强度。 - 可获利判定:文档给出经验公式——当
swap_amount * slippage > sandwich_gas_cost * 2时,这笔交易具备被三明治的空间。背后的数学很简单:受害者滑点容忍度必须覆盖你的 Gas 成本,否则你「推高价格→让他以更差价格成交→高位卖出」的三步操作无利可图。
技能文档同时给出典型阈值参考:ETH/USDC 这类主流池,受害者单笔 swap 超过 1 万美元且滑点超过 1% 时,通常才值得下手。这个阈值随 Gas 价格、池子深度动态变化,实操中应将其作为起点再结合实时 Gas 校准。
第二步:构建三明治捆绑包(Sandwich Bundle)
三明治的核心是同区块内的三笔有序交易:
// Bundle: 3 tx in same block, in order // 1. attacker_tx_1: swap baseToken -> token (push price UP) // 2. victim_tx: swap baseToken -> token (worse price now) // 3. attacker_tx_2: swap token -> baseToken (sell back at higher price)- 第 1 笔(front-run):先用 baseToken 买入 token,把池内价格推高;
- 第 2 笔(victim):受害者按此时更差的价格完成 swap,承受滑点损失;
- 第 3 笔(back-run):立即卖出 token 换回 baseToken,赚取价格差。
关键在于三笔交易必须在同一区块内、严格按序打包,普通广播不可能保证这一点。技能文档给出的做法是走 Flashbots 私信中继(private relay),把三笔交易打包成一个 bundle 提交:
// Flashbots bundle (Ethereum mainnet — others have similar private RPCs) const ethers = require("ethers"); const { FlashbotsBundleProvider } = require("@flashbots/ethers-provider-bundle"); const provider = new ethers.providers.JsonRpcProvider(process.env.RPC); const wallet = new ethers.Wallet(process.env.PK, provider); const fb = await FlashbotsBundleProvider.create(provider, wallet, "https://relay.flashbots.net"); const blockNumber = await provider.getBlockNumber(); const bundle = [ { signer: wallet, transaction: attackerTx1 }, // front-run { signedTransaction: rawVictimTx }, // victim from mempool { signer: wallet, transaction: attackerTx2 }, // back-run ]; const signedBundle = await fb.signBundle(bundle); await fb.sendRawBundle(signedBundle, blockNumber + 1);需要特别注意的是 bundle 数组的组成:
attackerTx1与attackerTx2使用你自己的signer签名;- 中间的
rawVictimTx是从 mempool 抓到的受害者原始已签名交易,直接原样塞入 bundle——你无法也不应该修改它,只能利用它; sendRawBundle提交到blockNumber + 1,即下一个区块,由 Flashbots 中继负责在区块内保证三笔交易的顺序与原子性。
这也解释了「三明治攻击为什么依赖私密交易通道」:如果 bundle 本身公开广播,其他搜索者(searcher)会在看到你的 front-run 后再插一笔,把你的三明治「三明治」掉(sandwich-of-sandwich)。
JIT(Just-In-Time)流动性三明治:不承担价格冲击的纯手续费捕获
技能文档指出,Uniswap V3 的集中流动性(concentrated liquidity)衍生出一种变体——JIT 流动性三明治:在受害者交易前的一瞬间,在一个极窄的价格区间内提供流动性,吃下受害者 swap 产生的 100% 手续费,随后立即撤出:
// 1. Just before victim's swap: mint a position concentrated at victim's price // 2. Victim swaps — your liquidity earns 100% of the fee // 3. Just after: burn the position // No price-impact risk; pure fee capture.与经典三明治的区别在于收益来源:经典三明治赚的是价格差(推高价格后卖出),需要承担持仓期间的价格波动与无常损失;JIT 三明治赚的是手续费,流动性只在单区块内存在,理论上没有价格影响风险。可行性条件也很直接——当受害者的 swap 规模足够大,使得其产生的手续费超过「Gas + 资本占用成本」时,JIT 就有利可图。实践中这通常需要受害者交易量足够大(手续费绝对值可观),因此大额清算、大额换币是 JIT 的主要目标。
多区块 MEV:跨区块的三明治
技能文档描述了一种跨区块变体,适用于验证者(validator)同时扮演搜索者、或与搜索者合谋的场景:
Block N: attacker front-run TX Block N+1: victim's TX (separate user, expects same price) Block N+2: attacker back-run TX即 front-run 与 back-run 不在同一区块内:攻击者在区块 N 推高价格,受害者的交易在区块 N+1 才落地(受害者以为还是原价),攻击者在区块 N+2 平仓。文档同时给出重要的事实边界:这要求构建者/搜索者之间的合作(builder/searcher cooperation);以太坊上的 PBS(proposer-builder separation,提议者-构建者分离)机制会显著加大这种攻击的难度,但在仍由单一区块验证者主导的链上依旧可行。
防御视角:什么会打破三明治
技能文档明确把防御面当作「寻找更难目标」的侦察清单。站在防守方角度,以下机制可以有效阻断三明治:
- 私密 mempool:受害者走 Flashbots Protect、MEV-Blocker、bloXroute Private Tx 等私密通道提交交易,交易不进入公开 mempool,攻击者根本看不到、无法前插;
- 紧滑点保护:合约设置很紧的
minAmountOut(如 0.1% 滑点),三明治的价格推高幅度超出其容忍度时交易直接 revert,攻击者赔 Gas; - Commit-reveal 机制(少见):受害者先提交承诺、后揭示内容,交易意图在揭示前不可见;
- 阈值加密 mempool(如 Shutter 等):交易内容加密,只有在区块打包时才解密,攻击者无法在打包前读取并前插。
这份清单对红队/审计同样有反向价值:评估一个 DEX 集成是否安全,可以检查其是否具备上述任意一种防 front-running 机制——如果都没有,它就是「易于三明治的目标」。
常见陷阱:别让你的三明治被三明治
技能文档用「sandwich-of-sandwich(三明治之三明治)」点出新手最容易犯的错误:
- 不要把三明治捆绑包公开广播——始终使用 Flashbots / 私密中继。公开的 front-run 交易会被其他搜索者看到并抢先插入;
- 其他搜索者也看得到受害者——竞争不可避免,需要通过更高的 Gas 价格 + priority fee(优先费)出价竞标,把别人的交易挤出区块位置;
- 不要从同一个地址三明治你自己的用户交易——交易归属(attribution)太明显,很容易被链上分析标记,是典型的 OPSEC 失误。
工具链:侦察与检测视角
技能文档推荐的工具既服务于攻击侧,也服务于防守/研究侧:
mev-inspect-py(Flashbots 出品):历史三明治检测工具,用于防守方与逆向研究——从历史区块中找出已发生的三明治攻击模式;mev-share:部分订单流(partial-order-flow)生态,关注订单流如何被选择性披露与利用;searcher-sage:开源的三明治机器人模式参考;Eigenphi:MEV 分析仪表盘,用于侦察已知搜索者的模式。
注意文档引用的行业文献(如 Daian 等人的 "Flash Boys 2.0"、Flashbots 文档、"MEV Wiki"、EthCC/Devcon 相关演讲)属于背景资料,在仓库中仅以引用形式存在,研究时可自行检索原文,此处不再展开外部链接。
OPSEC、伦理与法律边界:只对测试网络或你拥有的目标操作
技能文档在最后给出了明确的合规边界,这也是 Decepticon 技能体系的通用原则:
- 三明治攻击是对公开 mempool 的掠夺行为,在法律上通常属于灰色地带(generally legal but ethically grey);
- 在漏洞赏金(bounty)语境下:只能在测试网络(test networks)或你自持的目标上测试——这是不可逾越的红线;
- 用于研究/检测目的时,用
mev-inspect-py分析历史区块没有危害,属于防守方/研究侧用法; - 不同链的 MEV 架构不同(例如 Solana / Jito 就有独立的 MEV 体系),跨链操作必须调整策略。
这条 OPSEC 约束在仓库层面并非空话:在 contracts 目录总览 中,整个智能合约车道声明了capability_contract——scope: isolated-lab(隔离实验室),环境限定为anvil与forked-chain(分叉链),要求forge、slither等工具,证据形式为foundry-poc、evm-trace。也就是说,在 Decepticon 的架构约束下,这类攻击技能被设计为只能在本地起链或分叉环境中执行,与「只在测试网络或自持目标上测试」的原则严格对齐。
技能质量保障:skill_audit 与 Capability Contract
mev-sandwich 这份技能能进入目录,经过了 skill_audit/rules.py 的机器校验。从源码看,每条 SKILL.md 都要通过若干稳定规则:
- R-missing-required:顶层必须存在非空的
name与description;metadata必须是 YAML mapping 且必须含subdomain与when_to_use(见 rules.py 的_check_required); - R-bad-subdomain:
subdomain必须是规范值或其别名(contracts属于规范子域); - R-bad-mitre-format:
mitre_attack条目必须符合可识别的 MITRE 编号格式(T1565.002合法); - R-no-attribution:对进攻性技能(offensive path),必须声明
mitre_attack、aatmf_tactic或upstream_ref至少其一——mev-sandwich 通过mitre_attack: T1565.002满足该要求(见 rules.py 的_check_attribution)。
可选的capability_contract则由 capabilities/contracts.py 中的CapabilityContract模型严格校验:lane(web / web3 / reverse-engineering / active-directory / windows-internals / game-security)、scope(仅允许authorized-target与isolated-lab两类)、environment、required_tools、evidence、verification、negative_control、scorecard、benchmark均为必填且条目必须唯一非空。这保证了「攻击技能」与「可被自动化测试的运营边界」绑定在一起——技能可以加载,但只能在声明好的隔离环境中执行。
另外,tests/unit/agents/standard/test_specialist_skill_sources.py 用参数化测试锁死了契约:contract_auditor智能体必须把/skills/standard/contracts/声明为技能来源,且该目录必须真实存在并包含非空的 SKILL.md 文件——从测试层面防止「技能目录存在但内容为空」这类静默失效。
关联技能与进一步阅读
三明治攻击不是孤立的:它是 DeFi 攻击链上的一环。在 contracts 车道目录 中,同车道的技能还包括:
- oracle-manipulation(预言机操纵):三明治的盈利前提——「推高价格让受害者以更差价格成交」——本质上依赖 AMM 现货价格可被单区块内操纵,这与 oracle-manipulation/SKILL.md 中「现货价格预言机可操纵」的洞察直接同源;
- flash-loan(闪电贷):大额推价往往需要闪电贷放大资金;
- reentrancy、access-control、upgradeable-proxy、signature-replay:合约审计车道的其余常规武器。
实践建议:在 Decepticon 中加载本技能时,直接调用load_skill("/skills/standard/contracts/mev-sandwich/SKILL.md")(或 slugmev-sandwich);研究侧可以先跑mev-inspect-py复盘历史三明治,再在 anvil/forked-chain 环境里用 Foundry 构造 PoC 验证价格影响与盈利数学——整个过程保持在隔离实验室范围内,与技能声明的isolated-lab契约一致。
【免费下载链接】Decepticon
Autonomous Hacking Agent for Red Team
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考