Token-0x

First Flight #54
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Severity: high
Valid

Self-transfer doubles user balance allowing infinite token minting

Root + Impact

Description

  • In a standard ERC20, transferring tokens to oneself should leave the balance unchanged.

  • In Token-0x, when from == to, the balance is doubled instead of remaining constant, allowing any user to mint infinite tokens.

// src/helpers/ERC20Internals.sol#L106-L127
function _transfer(address from, address to, uint256 value) internal returns (bool success) {
assembly ("memory-safe") {
// ...
let ptr := mload(0x40)
let baseSlot := _balances.slot
mstore(ptr, from)
mstore(add(ptr, 0x20), baseSlot)
@> let fromSlot := keccak256(ptr, 0x40) // When from == to, fromSlot == toSlot
let fromAmount := sload(fromSlot)
mstore(ptr, to)
mstore(add(ptr, 0x20), baseSlot)
@> let toSlot := keccak256(ptr, 0x40) // Same slot as fromSlot!
let toAmount := sload(toSlot)
// ...
@> sstore(fromSlot, sub(fromAmount, value)) // 100 - 50 = 50
@> sstore(toSlot, add(toAmount, value)) // 100 + 50 = 150 (overwrites!)
}
}

Risk

Likelihood:

  • Any user can call transfer(msg.sender, amount) at any time

  • No special conditions or permissions required

Impact:

  • Users can mint unlimited tokens by repeatedly self-transferring

  • Total supply becomes meaningless

  • Complete destruction of token economics

Proof of Concept

function test_SelfTransfer() public {
token.mint(alice, 100e18);
uint256 balanceBefore = token.balanceOf(alice);
vm.prank(alice);
token.transfer(alice, 50e18);
// Expected: 100e18, Actual: 150e18
assertEq(token.balanceOf(alice), balanceBefore); // FAILS
}

Recommended Mitigation

function _transfer(address from, address to, uint256 value) internal returns (bool success) {
assembly ("memory-safe") {
+ // Handle self-transfer: no state change needed
+ if eq(from, to) {
+ mstore(0x00, value)
+ log3(0x00, 0x20, 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, from, to)
+ success := 1
+ leave
+ }
// ... rest of function
}
}
Updates

Lead Judging Commences

gaurangbrdv Lead Judge 19 days ago
Submission Judgement Published
Validated
Assigned finding tags:

transfer outstanding

transfer related exploit that can make huge impact to protocol.

Support

FAQs

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

Give us feedback!