带税代币怎么查:买入税、卖出税和到账变少的原因
到账比报价少或卖出失败,代币转账扣费是需要排查的一项。先查当前买入税、卖出税,再核对自己的交易记录与费率修改权限;这些结果能帮助你判断差额来自哪里。

在 DEX 上买一个陌生代币,到手数量比报价少了一截,第一个要排查的是这个代币的合约有没有自己扣一笔。圈里叫它“税”,官方文档叫 token fee,或者 fee on transfer。它跟报税没有关系,也不是 DEX 收的兑换手续费,更不是 gas。
这笔钱扣多少,先读代币警告和合约的当前费率;已经成交的,再核对那笔交易的转账记录。日志能完整对应池子与钱包时,才用转出量和实收量倒算。这两种查法下面分别讲,卖不出去和滑点报错也一起查。
买币到账比报价少,是谁扣的
如果确认少掉的数量来自代币税,扣费发生在代币的转账逻辑里,费率和分配方式由合约规则决定。仅凭“到账少了”,还不能排除报价变化或其他费用。
Uniswap 帮助中心的 What is a token fee? 把这笔钱定义为代币在买入、卖出或转账时收取的费用,并说明由代币发行方设定和收取,该平台不参与分成。本文所用官方说明查阅于 2026 年 10 月;警告标签与界面提示以页面实时显示为准。
要追这笔差额,得先确认币从池子转出后经过哪些地址,再查合约在哪一步扣费。DEX 的报价、成交记录和代币的转账记录要放在一起看。
截走的部分去了哪,每个合约写法不同,得看它自己的代码。PancakeSwap 文档举过一个例子:某代币每笔交易收 10%,其中 5% 分给全体持有人,5% 拿去加流动性。这只说明“可以这样设计”,换一个合约,钱可能直接进发行方指定的地址。
该帮助页也说明,合约要求的买入费或卖出费未支付时,兑换就不能发生。由此可见,只换一个下单界面不能保证免税;合约若对某些地址或池子设有豁免,实际扣费才可能不同,仍要回到代码确认。
代币税、兑换手续费、gas:三笔钱别算混
一笔链上兑换里,你可能同时付三种钱。算损耗之前把它们分开,不然倒算出来的数字没有意义。
| 扣的是什么 | 谁定的 | 钱给谁 | 去哪里看 |
|---|---|---|---|
| 代币税(token fee) | 代币发行方,写在代币合约里 | 按代币合约代码分配 | 界面的代币警告、合约源码、自己那笔交易的转账记录 |
| DEX 兑换手续费 | DEX 协议与池子的设置 | 按该 DEX 的规则分配,查它的文档 | 该 DEX 的官方文档 |
| gas(网络费) | 链的网络状况 | 付给网络,用链的原生币结算 | 钱包的确认弹窗、区块浏览器的交易详情 |
gas 通常另用 ETH、BNB、SOL 等原生币支付;钱包或聚合器若提供代付并另收服务费,还要核对它列出的费用。DEX 兑换费可能已经计入报价。“报价 1000、到手 950”只说明数量有差异,不能直接把这 50 枚全算成代币税。
报价之后价格变了、订单本身推动了池子价格,也会影响实收。排除这些因素后,再查转账扣费。
买之前,去哪里查买入税和卖出税
以太坊和它的 Layer 2:先看 Uniswap 的代币警告
在这个界面里选中一个代币,如果它被标了费用相关的警告,界面可能给出提示。What are token warnings? 一页的标签表里,和税直接相关的有两条:“High Buy or Sell fee”(买入或卖出收取高额费用)和“100% Sell Fee Detected”(检测到 100% 卖出费)。另有一条“Honeypot”,写的是被 Blockaid 标记为疑似蜜罐。
使用这个警告时,有三件事要知道:
- 覆盖范围是以太坊 ERC-20 和受支持的 Layer 2 代币。
- 数据来源是第三方 Blockaid,平台声明不保证其准确性,也不独立核实。
- 较新或冷门的代币可能没有数据。
第三条最要紧。如果你碰到的陌生币正好属于“较新或冷门”那一类,没有警告就不等于没有税。该页也没有写“高”的门槛是多少,单凭 High Buy or Sell fee 这个标签得不到一个数字。界面上如果另外标出了买入、卖出费率,先记下来,再用下面的办法对一遍。
EVM 链通用:读合约源码
ERC-20 标准(EIP-20)列出的九个方法里,没有统一的费率查询方法;其中 name、symbol、decimals 还是可选的。转账扣费需要合约另写逻辑,变量名、计费单位、买卖是否分别收费,都得看具体实现。
所以没有一个固定的格子能让你直接读到“卖出税 = X%”。能做的是:
- 确认你手里的合约地址是对的,名字谁都能起,核对方法在 同名代币怎么认合约地址。
- 在区块浏览器打开合约,查看源码验证状态。这家浏览器未验证,不代表源码从未公开;可以再核其他验证服务,但要确认源码与当前链上代码匹配。仍找不到对应源码时,先把源码查费率这一步记为未确认,见 合约源码验证怎么看。
- 在源码里搜 fee、tax 这类关键词,找到转账函数里做减法的那一段,看被减掉的比例来自哪个变量。搜不到这类词不等于没有扣费,名字是发行方自己起的。
- 在合约页的读取功能(Etherscan 上的 Read Contract)找公开的费率查询项,确认单位和分母再读数。若是代理合约,先确认当前实现,再通过代理地址的 Read as Proxy 读取当前状态,不能拿实现地址自身的存储值当代币当前值。没有公开查询项就记“费率未读出”。
读不懂代码也别硬猜。把“源码已验证,但费率没读出来”记下来,比凭变量名猜一个数字强。
Solana:读 mint 账户的 TransferFeeConfig 扩展
Solana 的 Token-2022 则有专门的配置。Solana 文档 Transfer Fees说明,mint(代币铸造账户)的 TransferFeeConfig 扩展可以让每笔转账按配置扣费,扣下的部分记录在收款代币账户上,由获授权的一方提取。
先在支持 Token-2022 扩展显示的区块浏览器打开完整 mint 地址,找到 TransferFeeConfig。页面没显示扩展,不能直接认定它不存在;无法读出就记未确认。配置里的 olderTransferFee 和 newerTransferFee 各有 epoch、transferFeeBasisPoints、maximumFee,分别表示生效期、基点费率和费用上限;100 个基点等于 1%。两组都要看,不能只抄百分比、漏掉上限。
已经买了:用自己那笔交易倒算被扣了多少
下面只算一种容易核清的情况:同一代币在你的钱包和一个已确认的池子之间直接转账,日志完整,没有路由中转、分拆成交、退款或余额重算。遇到那些情况,不能照抄这个公式把所有差额都叫税。
EIP-20 要求转账触发 Transfer 事件。打开交易详情的 Logs,先按代币合约地址筛出事件,再按该代币的 decimals 把原始整数换算成同一单位。事件由合约自己发出;若记录不完整、与余额变动对不上,就不能只靠它倒算。
买入时,把该笔买入中从池子发出的同一代币数量相加,得到转出总量;把钱包收到的数量减去钱包在同一笔中转出的数量,得到实收。还要在源码或明确的费用记录中确认差额确实对应代币扣费。池子地址的核对方法见 流动性池锁仓怎么查。
假设这笔直接转账里,池子转出 100,000 枚,钱包实收 95,000 枚,差额全部是已核明的代币扣费:
- 差额:100,000 − 95,000 = 5,000 枚
- 买入实际扣除比例:5,000 ÷ 100,000 = 5%
卖出同样限于上述直接转账。钱包减少的代币总量是分母;池子从你钱包实际收到的同一代币数量是实收。池子从其他地址收到的币不能混进来,有退款或路由中转就先停止套公式。
继续假设:你把这 95,000 枚全部卖出,池子实收 87,400 枚。
- 差额:95,000 − 87,400 = 7,600 枚
- 卖出实际扣除比例:7,600 ÷ 95,000 = 8%
在买卖价格相同、且暂不计 DEX 兑换费、gas 和价格影响的假设下,两次扣费后剩下的比例是 0.95 × 0.92 = 0.874,数量损耗为 12.6%,不是把 5% 与 8% 直接相加。只补回这两次代币税,需要卖出单价约为买入单价的 1 ÷ 0.874 ≈ 1.144 倍,即上涨约 14.4%;算上其他成本,要求还会变。
若日志只写了一条池子到钱包的净额,分母就不够可靠:差额为 0 可能是没扣,也可能是费用没单列。报价会变化,不能拿旧报价补成扣费证据。回源码仍核不出就记未确认;只买过没卖过时,也不要用买入税推算卖出税。
带税代币为什么要调高滑点,几种报错各是什么意思
先看报价是否已包含代币扣费。若没计入,假设滑点容忍度为 1%,实收却比报价少 10%,就可能触发最低接收数量限制。能否成交还取决于所用路由是否支持这个代币,以及是否有其他交易限制;把滑点调高不保证成功。
PancakeSwap 文档 Troubleshooting Errors 一页举的例子就是这个关系:

这段举例说明,转账扣费会让购买后实收少于预期。不能把截图中的设置直接搬到另一个代币上。
同一页还列了几种报错,对着文本就能判断方向:
PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT:可能是滑点容忍度太低或流动性不足。先刷新报价、检查交易量和最低接收数量;调高容忍度会放宽你接受的最差成交结果。Pancake: K:文档把自带费用的代币列为一种原因,并给出改填 To 数量、让 From 成为估算值的办法。这是该文档针对相应路由的排障提示,操作前仍要检查更新后的报价。Pancake: TRANSFER_FAILED:可能与 Restorative Rebase 类代币的设计有关,也可能是发行方暂停交易或只允许选定地址卖出。后两种不能靠提高滑点解决。
Uniswap 这边另有一个限制。它的 v3 开发者文档 Token Integration Issues 写:“Fee-on-transfer tokens will not function with our router contracts.”——转账收费的代币无法在 v3 的路由合约上正常运作。
滑点容忍度限制的是总偏差,不能把其中某一截专门留给税。用一个简化算式看:假设报价未计入 10% 代币税、只扣一次税,设 12% 滑点后,价格下移可占的比例是 1 − 0.88 ÷ 0.90 ≈ 2.22%;若设成 25%,就变成 1 − 0.75 ÷ 0.90 ≈ 16.67%。实际报价若已计税,就不能再这样相减。我建议先看最低接收数量能不能接受;失败原因未查明时,别靠一次次加滑点来试。
卖出税 100% 是什么情况,费率以后还能不能改
前述警告表把 “100% Sell Fee Detected” 用于被标记为收取 100% 卖出费的代币。按它说明的情形卖出,全部价值会归代币创建者,卖方拿不到价值。
这个警告值得立即停下来核查,不必为了验证标签再花钱试卖。标签本身也受前面提到的数据准确性限制。
比 100% 标签更难防的是“现在不高,以后能改”。你今天倒算出买 5% 卖 8%,只说明那两笔交易发生时是这个数。
EVM 链上要看费率修改函数、调用权限和可升级性。当前实现把费率写成常量,只能说明这份实现没有直接改该常量的入口;若代理能升级,实现仍可能换掉。费率存成变量时,要查谁能改、上限怎样约束,也要查看角色或外部配置,不只搜 owner。方法见 代币合约权限怎么看。LP 凭证由谁持有,则另查池子能不能被撤走。
Solana 配置中的 transferFeeConfigAuthority 管理费率修改,withdrawWithheldAuthority 管理已扣费用的提取。官方文档说明,SetTransferFee 更新 newerTransferFee,从两个 epoch 之后开始生效。判断当前用哪组,比较当前 epoch 与 newerTransferFee.epoch:达到生效期用 newer,否则看 older。两组不同不等于新费率已生效;两组相同也不能证明从未更新过配置。
查不出来的几种情况,记成“未确认”
下面这些情况,你得不到一个可靠的费率数字,记录里就写“未确认”,不要填一个猜的数:
- 找不到与当前链上代码对应的源码,费用读取项又不明确,无法确认扣费规则。
- 代币很新,界面没有任何警告。警告页自己说了新币可能没有数据,空白不能当作“无税”。
- 代币不在以太坊或受支持的 Layer 2 上,那套警告本来就不覆盖。
- 当前费率能读出,但谁能改、允许改到多少还没查明;当前值照记,未来条件另记未确认。
- 只买过没卖过,卖出税没有实测数字,源码也没读出来。
- 交易日志里这个代币只有一条转账记录、差额算出来是 0,源码也没读出扣费逻辑。
“未确认”要写到具体项目上。能读出当前买入税,就保留这个值;卖出税和修改权限没查清,分别留空。看不到退出时会扣多少,就先别把买入页面上的报价当作能换回来的金额。
关于代币税,还有几个具体问题
换一个 DEX 或者聚合器买,能避开代币税吗?
只换界面不能保证避开。费用在代币转账逻辑里执行;换池子或交易路径是否改变收费,取决于合约有没有针对地址或路径的不同规则。
不经过 DEX,只是把带税代币从一个钱包转到另一个钱包,也会被扣吗?
可能会。前文提到的 token fee 定义包括买入、卖出和转账时代币收取的数额。Solana 的 TransferFeeConfig 扩展则是对该 mint 的每一笔转账收费。EVM 链上具体扣不扣、扣多少,要看那个合约自己的代码。
Solana 上的代币税改了以后,是马上生效吗?
不是。Solana 文档说明,SetTransferFee 更新 newerTransferFee,从两个 epoch 之后开始生效。当前 epoch 达到 newerTransferFee.epoch 时用 newer,否则看 older;两组相同也不能据此判断更新历史。