假设一只池子里放着 10,000 TRX 和 2,000 USDT,看起来每个 TRX 值 0.2 USDT。拿 200 USDT 去换,按这个价应该拿到 1,000 TRX,实际只到手约 909。换成 2,000 USDT,按比例该拿 10,000 TRX,实际只有 5,000。投入翻了十倍,到手只多了五倍半。
钱包没有算错。少拿的那部分主要有两个来源。一是你自己的买入把池子里的价格推高了,叫价格影响。二是从看到报价到交易真正执行的这段时间里,池子被别人动过了,这才是严格意义上的滑点。页面上那个可以调的“滑点容忍度”,两样都管不了,它只决定结果差到什么程度时你还愿意成交。
下面先把这只池子的账算清,再看少拿的币最后落进了谁的口袋,最后说交易失败或结果不对时该怎么查。
池子按库存算价,不看标价
传统交易所用订单簿,买家和卖家各自挂价,系统把能对上的撮合起来。链上兑换常用的是自动做市商,也就是 AMM。它不等另一个人来接你的单,你直接和合约里存着的两种资产做交换。
这些资产由流动性提供者放进去,简称 LP。下一篇会站到 LP 那边看他们怎么算账,这一篇只当买东西的人。
V2 一类的池子最常见的规则叫恒定乘积。意思是两边数量相乘的结果,交易前后要保持不变。开头那只池子,10,000 乘以 2,000 等于 20,000,000。为了看清原理,先忽略手续费。
投入 200 USDT 后,池子里的 USDT 变成 2,200。乘积还得是 20,000,000,所以 TRX 只能剩下 20,000,000 ÷ 2,200 ≈ 9,090.91 个。原来有 10,000 个,你能取走的就是两者之差,约 909.09 TRX。
你的平均买入价是 200 ÷ 909.09 ≈ 0.22 USDT,比起点贵了一成。更要紧的是交易之后,池子里变成 2,200 USDT 对 9,090.91 TRX,下一个人看到的价格已经是 2,200 ÷ 9,090.91 ≈ 0.242 USDT。你买走了便宜的那一段,把价格留在了更高的位置。

这套算法可以化成一个很好记的比例。不计手续费时,你比按起点价少拿的比例,等于你投入的数量除以“池子原有的同种资产加上你投入的数量”。
投入 20 USDT,少拿 20 ÷ 2,020 ≈ 1%,到手约 99.01 TRX。投入 200 USDT,少拿 200 ÷ 2,200 ≈ 9.1%。投入 2,000 USDT,少拿 2,000 ÷ 4,000 = 50%。开头那个“翻十倍只多五倍半”,就是这么来的。
所以决定你吃亏多少的,是你这笔钱和池子深度的比例,不是金额本身。真实的主流池子通常比这只假想池子深得多,200 USDT 可能几乎推不动价格。可同样 200 USDT 放进一只冷门小币的池子,可能就和这里的例子差不多。
生活里的类比是菜市场。你买一斤菜,摊主按标价算。你要买走半个摊子,剩下的菜越来越少,摊主越卖越贵。类比在“越买越贵”上成立。不同的是,池子没有摊主临时起意,涨多少完全由公式和库存决定,事先就能算出来。
少拿的钱要拆成三笔账
刚才算的那 9.1%,在你点确认之前就已经确定了。报价页面拿到池子当前的库存,就能算出这一笔会把价格推多远。Uniswap 的说明也是从交易规模和流动性深度的关系来解释价格影响的。
滑点发生在另一个时间段。报价是按你看到页面那一刻的池子算的,交易被打包执行时,前面可能已经有别人的买卖改过库存。你拿到的是执行那一刻池子给出的结果,和报价之间的差距才叫滑点。
手续费是第三笔。池子会从每笔交易里抽一点交易费,主要分给 LP,界面或服务方可能另收费用,TRON 上执行合约还要消耗能量或燃烧 TRX。拿 SunSwap V2 来说,官方给的交易费是每笔 0.3%。V3 池子则分档收费,有 0.01%、0.05%、0.3%、1% 四档。这些是撰写时的数值,以官方当前参数为准。
按 0.3% 算,200 USDT 里先扣掉 0.6,实际参与计算的是 199.4,到手变成 10,000 × 199.4 ÷ 2,199.4 ≈ 906.61 TRX,比无费时少了约 2.5 个。你用的那只池子收多少,要看它属于哪个版本、哪一档,这里只是演示扣费的位置。
这三笔账在日常讨论里经常被统称为“滑点”,有些界面的叫法也不完全一样。自己对账时最好分开问。报价比起点价格差多少,这是价格影响。成交比报价差多少,这是滑点。费用各收了多少,要按路线一项项看。不然少收了币,很容易全怪到滑点头上,然后去调一个根本管不着它的设置。
滑点容忍度只是一条底线
还是那笔 200 USDT。页面报价 909.09 TRX,你把容忍度设为 0.5%,交易就会带上一个条件,至少收到 909.09 × 99.5% ≈ 904.55 TRX,否则整笔作废。
现在假设在你的交易执行之前,有人先用 100 USDT 买了 TRX。池子变成 2,100 USDT 和 20,000,000 ÷ 2,100 ≈ 9,523.81 TRX。轮到你时,USDT 变成 2,300,TRX 只能剩 20,000,000 ÷ 2,300 ≈ 8,695.65,你能拿到 9,523.81 − 8,695.65 ≈ 828.16 TRX。
828.16 低于 904.55,交易失败,你的 USDT 留在钱包里。如果容忍度设的是 10%,底线就是 818.18,交易照样成交,你拿着比报价少 81 个的 TRX 离开。

两种设置下,池子都一样浅,前面那个人都一样买过。改动容忍度没有让价格变好一分,它只是决定了这个更差的结果你要不要接。像跟店员说“贵一点也行”,店员并不会因此给你打折。
反过来,容忍度设得极小也有代价。池子稍有变动交易就会失败,而在 TRON 上,已经上链执行的合约调用即使失败,状态会回滚,消耗掉的资源却不退。TRON 开发者文档把失败分成两类。像“到手数量不够”这种由合约主动中止的失败,只扣到中止那一步为止用掉的能量。能量耗尽之类的异常,则会把这笔交易允许用的能量全部算作消耗,上限由 fee_limit 决定。不管哪一类,交易本身占用的带宽也照样要付。合适的数值要看池子深浅、币价波动和自己能接受的范围,没有可以从教程里抄的万能百分比。
实际界面可能有自己的取整和计算方式,最终保护到哪个数量,以页面列出的“最低收到”为准。兑换参数说明里还区分了固定输入和固定输出。固定输入时,你定好花多少,条件管的是最少收到多少。固定输出时,你定好要多少,条件管的是最多愿意花多少。两种下单方式的数字不能直接放在一起比。
被推高的价格,会被套利拉回来
回到你那笔 200 USDT 的买入。交易后池子里 TRX 的价格是 0.242 USDT。假设别处的市场价格仍是 0.2,同一个币就出现了两个价钱。
套利者会在便宜的地方买 TRX,卖进这只池子。要让池子回到 0.2 的比例,乘积仍为 20,000,000,两边数量就得回到 10,000 TRX 和 2,000 USDT。也就是说,他要往池子里卖 909.09 TRX,取走 200 USDT。这些 TRX 在外面按 0.2 买,成本约 181.82 USDT,账面差额约 18.18 USDT。
这 18.18 是谁付的,对一下就清楚了。你花 200 USDT 买到的 909.09 TRX,按外面的价格只值 181.82 USDT。你多付的那部分,正好是套利者的账面差额。在不计手续费、外部价格不变的简化模型里,两边严丝合缝。

账面差额离到手利润还隔着几道成本。两边的交易费、网络执行成本、自己卖进池子时造成的价格影响,都要从这 18.18 里扣。扣完若不剩什么,这笔套利就不值得做,池子的价格也会停在离 0.2 还差一点的位置。
如果两边在不同链或不同平台,资金转过去要时间,到了那边价格可能已经变了。同一条链上,有些操作可以组合进一笔交易,条件不满足就整体作废,但失败了照样要付执行资源。越容易看到的价差,越多程序在抢,普通用户截图里的差价,很少能原样变成到账收益。
这件事对普通用户的意义在于,池子并不知道外面的新闻和行情,是套利者的买卖把外部价格一点点搬进来的。也正因如此,你在浅池子里推高的那段价格,很快会被别人以利润的形式取走。
有人专挑宽松的底线下手
套利是在你的交易之后捡差价。还有一种手法是夹在你前后,常被叫作三明治交易。
还是用这只池子。攻击者看到你要拿 200 USDT 买 TRX,抢在你前面用 100 USDT 买入,拿到约 476.19 TRX。你按更差的价格成交,只拿到 828.16 TRX。紧接着他把 476.19 TRX 卖回池子,此时池子是 2,300 USDT 和 8,695.65 TRX,卖完后 TRX 变成 9,171.84,USDT 剩 20,000,000 ÷ 9,171.84 ≈ 2,180.59,他取走约 119.41 USDT。
一进一出,他花 100 拿回 119.41,不计费用多出约 19.41 USDT。这笔钱的来源,就是你那笔交易被挤到了更差的价格上,比报价少拿了 81 个 TRX。
这里能看出滑点容忍度的另一层作用。攻击者把你的价格往下压,最多只能压到你的“最低收到”。你设 0.5%,底线是 904.55,他前面那 100 USDT 一买,你的交易就失败了,他还得自己承担买卖成本。你设 10%,就等于告诉对方还有大约 90 个 TRX 的空间可以挤。
这种手法能不能做成,取决于攻击者能不能提前看到你的交易,并把自己的交易排到你前后。不同链的交易可见性和排序规则不同,不能把 Ethereum 上的经验原样套到 TRON。
TRON 上也有人反馈过被抢跑。2024 年 9 月,孙宇晨回应说超级代表节点没有实现任何 MEV 机制,没人能靠操纵价格之类的手段让自己的交易优先,也不能重排或插入区块里的交易,社区指认的那些交易里有大量是机器人碰运气失败的尝试。他同时也承认,抢跑机器人每条链上都有,TRON 不例外。对普通用户来说,结论还是一样,别给机器人留出能挤的空间。成交不理想也可能只是正常行情变化,不能看到结果差就认定被某个地址攻击了。
研究者在对 Uniswap 滑点成本的研究中把正常的市场变化和对抗性因素分开讨论过。上面的数字只是用假想池子演示机制,不代表任何真实攻击的金额。
普通用户能做的,是别在很浅的池子里做相对很大的交易,别随手把底线放得很宽。如果某个服务提供“防夹”之类的保护,先弄清它保护的是哪一步,别把一个盾牌图标当成绝对承诺。
池子看着大,不等于你用得上
既然吃亏多少取决于池子深度,挑池子和路线就很重要。这里 V2 和 V3 的差别会直接影响结果。
V2 池子里,LP 的资金按恒定乘积铺在从零到无穷大的所有价格上。不管价格走到哪里,都有一点流动性,但每个价位分到的都很薄。前面那套无费演算适合理解原理,真实合约还要把交易费计入储备,不能原样拿来对每一笔交易的数字。
V3 引入了集中流动性,LP 可以只在自己选的一段价格区间里提供资金。同样一笔本金挤在较窄的区间里,当前价格落在这段区间时,池子就像深了很多,你的同一笔交易推动的价格更少。SUN 的 V3 文档讲了这种区间安排。
代价是,价格一旦走出大多数 LP 选的区间,那里可能没多少钱可用。这时一笔较大的兑换在 V3 上照样很贵,甚至比 V2 更贵。所以 V3 不保证任何时候都更划算。
这也说明池子的总资金量不能直接说明报价好坏。有些钱放在离当前价格很远的区间,轮不到你这笔交易。像一座商场有一百家店,卖你要的那件东西的只有两家,别的店面积再大也帮不上忙。
路由器会替你比较几个池子,有时把一笔交易拆开走不同路线,或者先换成中间资产再换成目标币。多一跳不一定更差,但每一跳都有自己的手续费和深度,要看最后的到手数量,而不是路径长短。
想练习看报价,可以输入一个小金额先不提交,记下预计到手、最低收到、交易费和网络费用。再把金额加大几倍,看单位价格怎么变,你会直接看到前面那个比例公式在起作用。比较不同路线时,要在同一时间、同样的输入和输出、同一个代币合约之间比,别拿这个页面的预计数量去比另一个页面的最低数量。名字相同的代币也可能是不同合约。
交易失败了,先别急着调大滑点
还是那笔报价 909.09 TRX、底线 904.55 的交易。执行时只能拿到 828.16,交易因为不满足最低输出而失败。这说明保护起了作用,不是界面在和你作对。
这时候先去钱包或区块浏览器看失败原因。如果是最低输出没满足,就重新获取报价,看现在的价格自己还接不接受。接受就按新报价提交,不接受就等一等或换条路线。如果失败原因是授权不够或能量不足,就去处理那一项,把滑点调大放宽的只是成交条件,变不出能量来。
诊断时记下原交易的编号。页面卡住和链上失败是两回事,页面转圈时反复点确认,可能已经提交了好几笔交易。先用第三篇讲的方法在浏览器里查清原交易的结果,再决定要不要重发。同理,报价有截止时间,等太久旧报价就会作废,重新提交前也要先确认上一笔到底有没有执行,免得同一个购买意图执行两次。
每次失败都可能已经扣掉了能量或燃烧了 TRX。合约状态回滚了,执行时消耗的资源一般不会退。连点五次试试,可能就是为同一个问题交五次费用。
有人会想把大单拆成几笔。拆单有时能等到套利者把价格拉回来再买下一笔,从而改善结果。可如果外部价格和池子都没变,连续拆开的同方向小单,后一笔面对的仍是前一笔推高后的库存,总价格影响并不会消失,还要多付几笔手续费和网络费用。拆单有没有用,要看两笔之间价格有没有被拉回。
成交以后,按数量对一遍账
交易成功后,用链上回执核对实际付出了多少、收到了多少,网络费用单独记。钱包首页显示的总资产美元变化,可能用了不同时间的参考价,先把币的数量记准,再按同一个价格去比。
还有一种情况容易被忽略。授权成功但兑换失败,那个授权可能仍然有效。没买到东西不代表什么都没发生,需要时按第六篇的方法查一下额度,弄清失败原因再决定是否继续。
回到开头那只池子。200 USDT 少拿的 90 多个 TRX,在你点确认之前就已经由池子的深度决定了,事后它会被套利者以利润的形式取走。执行前后多出来的差距,要么来自正常的市场变化,要么来自有人插队,能挤进来多少,取决于你给的底线有多宽。
所以每次兑换,真正要盯的是两个数量。发送前看最低收到多少,完成后看实际收到多少。中间差出来的部分,再去拆价格影响、滑点和手续费。下一篇换到柜台里面,看看提供这些库存的 LP 怎样算账。