Token-0x

First Flight #54
Beginner FriendlyDeFi
100 EXP
Submission Details
Impact: low
Likelihood: low

Token0x Does Not Support Fee-On-Transfer / Rebasing Tokens

Author Revealed upon completion

Root + Impact

Description

  • Token0x assumes standard ERC20 behavior. Balances must move 1:1 during transfer.

  • Many tokens (rebasing, fee-on-transfer, tax tokens) do not follow this model.

  • This causes mis-accounting when interacting with external non-standard tokens.

// No indication of incompatibility with rebasing or transfer-fee tokens
@> // standard arithmetic assumes exact transfers

Risk

Likelihood:

  • Occurs when interacting with non-standard tokens in integrations, wrappers, or external tooling.

Impact:

  • Incorrect balance calculations.

Broken assumptions in downstream integrations.

Proof of Concept

Not a code exploit — integration mismatch:

  1. A fee-on-transfer token sends 100 tokens, but receiver only gets 95.

  2. Token0x accounting expects 100.

  3. System breaks due to mismatch.

contract PoC {
FeeToken feeToken;
Token0x token0x;
function run() external {
feeToken = new FeeToken();
token0x = new Token0x();
// Give user some fee tokens
feeToken.transfer(address(this), 100 ether);
// User thinks they are depositing 100 tokens into Token0x
feeToken.approve(address(token0x), 100 ether);
// Call transfer (token0x expects full 100 tokens)
token0x.transfer(address(token0x), 100 ether);
// Check final balance
uint256 balanceReceived = feeToken.balanceOf(address(token0x));
// === Debug Output ===
// balanceReceived will be 95 ether due to 5% fee
require(balanceReceived == 95 ether, "Break: unexpected");
// Token0x still internally thinks it received 100
// => Accounting mismatch begins
}
}

Recommended Mitigation

  • No documentation present.

  • Add explicit documentation warning (strong business-level mitigation).

- remove this code
+ add this code
+ /**
+ * @notice IMPORTANT: Token0x is designed for standard ERC20 tokens only.
+ * It does NOT support:
+ * - fee-on-transfer tokens (taxed tokens)
+ * - rebasing or elastic supply assets
+ * - reflection/deflationary tokens
+ * - tokens whose transfer amount differs from the requested amount
+ *
+ * Integrating such tokens will cause:
+ * - incorrect balance accounting
+ * - mismatched transfer assumptions
+ * - unexpected supply behavior
+ *
+ * Only use Token0x with well-behaved ERC20 tokens.
+ */
- token.transferFrom(msg.sender, address(this), amount);
+ uint256 beforeBal = token.balanceOf(address(this));
+ token.transferFrom(msg.sender, address(this), amount);
+ uint256 afterBal = token.balanceOf(address(this));
+
+ require(
+ afterBal - beforeBal == amount,
+ "Non-standard ERC20 token detected: transfer mismatch"
+ );
+ bool public allowNonStandardTokens;
+
+ function setNonStandardTokenSupport(bool allowed) external onlyOwner {
+ allowNonStandardTokens = allowed;
+ }
+ if (!allowNonStandardTokens) {
+ require(
+ afterBal - beforeBal == amount,
+ "Unsupported token type (fee/rebase token)"
+ );
+ }

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!