♻️ERC777 Bridge Vulnerability: Reentrancy Attack in Token Accounting

Cross-chain bridges are often used to facilitate the movement of tokens between different layers, such as Layer 1 (L1) and Layer 2 (L2) blockchains. In some cases, these bridges handle complex tokens like those compliant with the ERC-777 standard, which introduces advanced features like hooks for token transfers. However, these features can also open up potential attack vectors, such as reentrancy vulnerabilities that allow malicious actors to exploit token accounting.

This section will cover the specific reentrancy vulnerability associated with ERC-777 tokens in token bridges, explaining how attackers can exploit the vulnerability, the impact of such attacks, and the recommended mitigation strategies.


Vulnerability Explanation

In a typical TokenBridge contract, users can transfer tokens between L1 and L2 by calling a function like bridgeToken. This function usually calculates the number of tokens to bridge by measuring the difference between the contract's pre-transfer and post-transfer balances. This calculation is essential to support tokens with unusual transfer logic, such as those that deduct a fee on each transfer.

However, this method becomes vulnerable when the contract handles ERC-777 tokens. ERC-777 tokens support callback hooks via the ERC-1820 registry, allowing a token holder to register a contract to receive a callback whenever a transfer is made. This feature introduces the risk of reentrancy attacks, where a malicious contract can manipulate the contract's logic before the original transaction completes.

Attack Scenario:

  1. Setup: The attacker registers a contract as an ERC777TokensSender via the ERC-1820 registry. This contract will receive the tokensToSend callback whenever an ERC-777 transfer is initiated by the TokenBridge contract.

  2. Initial Bridge Call: The attacker calls bridgeToken with 500 tokens. At this point:

    • The contract stores its initial balance (let’s call it balanceBefore), which is 0.

    • The contract then initiates a safeTransferFrom call to transfer 500 tokens from the attacker’s address to the bridge contract.

    • During this transfer, the tokensToSend callback in the attacker’s contract is triggered.

  3. Reentrancy Attack: Inside the tokensToSend callback, the attacker re-enters the bridgeToken function by calling it again, this time transferring an additional 500 tokens. Since the contract logic hasn’t updated its state yet:

    • balanceBefore in the second bridgeToken call is still 0, and the safeTransferFrom function is executed again.

    • After the second transfer, balanceAfter becomes 500.

  4. Original Call Completes: After the second call completes, the original bridgeToken call continues. The balanceAfter in this original call is now 1000 (due to both the original and re-entrant transfers). The contract incorrectly credits the attacker with 1500 tokens on L2, despite only sending 1000 tokens.

  5. Outcome: The attacker is credited with more tokens than they originally transferred. If other users have bridged this token to L2, the attacker can effectively withdraw the stolen tokens, leading to a loss of funds for legitimate users.

Example Code: Vulnerable bridgeToken Function

function bridgeToken(address token, uint256 amount) external {
    uint256 balanceBefore = IERC20(token).balanceOf(address(this));

    // Transfer tokens from msg.sender to the bridge
    IERC20(token).safeTransferFrom(msg.sender, address(this), amount);

    uint256 balanceAfter = IERC20(token).balanceOf(address(this));
    uint256 bridgedAmount = balanceAfter - balanceBefore;

    // Logic to credit bridgedAmount on L2...
}

Vulnerability Breakdown:

  • Reentrancy Attack: During the safeTransferFrom call, the ERC-777 token invokes the tokensToSend callback, allowing the attacker to re-enter the bridgeToken function before the state (e.g., balances) is updated. This can cause incorrect balance calculations and allow the attacker to bridge more tokens than they actually possess.

  • ERC-777 Token Behavior: ERC-777 tokens, unlike standard ERC-20 tokens, support hooks via the ERC-1820 registry, which can trigger malicious reentrancy during token transfers if not properly protected.


Impact

This vulnerability could lead to significant financial losses:

  • Inflation of Token Balance: Attackers can use reentrancy to inflate the token balance credited to them on L2, giving them more tokens than they bridged. This results in a loss of tokens for other users who have also bridged tokens to L2, effectively allowing the attacker to steal funds.

  • Depletion of Liquidity: If the attacker is able to withdraw these inflated tokens on L2, the bridge’s liquidity can be drained, leading to a potential collapse of the bridge and loss of user confidence in the protocol.

Last updated