Possible security issues with ERC777 and arbitrary call contracts

Recently, while working with one of our clients, we discovered an interesting bug that has the potential to be an attack vector for some DeFi projects. This error is especially related to the well-known ERC777 token standard. Also, it's not just a simple re-entrancy problem common among well-known hackers.

This article provides a comprehensive explanation of ERC777, covering all the necessary details. There are few resources to delve into the specifics of ERC777 tokens, and this article is a valuable detailed guide for anyone interested in learning more about ERC777 tokens.

In the last part of the article, our recent findings will be explained.

A short description of the attack vector

This vulnerability takes advantage of the characteristics of ERC777 and can set a Hook receiving function. By utilizing the ability to make arbitrary calls in the target contract, a malicious caller can call the ERC777 registry contract and assign a specific Hook address to the target contract. Therefore, whenever the target contract receives ERC777 tokens in the future, the attacker's Hook contract will be triggered. This hook can be exploited in various ways: either for reentrancy attacks to steal tokens, or simply to roll back transactions, preventing the target contract from sending or receiving ERC777 tokens.

ERC777 and its Hook

What is ERC777

ERC777 is one of the token standards with transfer Hook. Here is the EIP description: , and here is an ERC777 practice [4] 。

The main motivation for implementing ERC777 tokens is to mimic the behavior of native token transfers. By triggering smart contracts when tokens are received, developers can execute specific logic to enhance functionality and create more dynamic token interactions.

However, these extra calls during the transfer process make ERC777 different from ERC20 tokens. These hooks introduce a new attack vector that could affect smart contracts that were not designed to handle additional calls during token transfers. Such unexpected behavior creates security risks for these contracts.

The following is a list of some ERC777 tokens with some liquidity on the Ethereum mainnet:

Kp6OQ2xMxjKs5X4G5V33hmMqR8TSwawzldCaPOtL.png

When the Hook happens

ERC20 tokens simply update balances during transfers. But ERC777 tokens do this:

  1. Make a Hook call to the address of the token initiator

  2. Update balance

  3. Make a Hook call to the token receiver address

This is well illustrated in the VRA token:

source code:

Now, let's examine the code for these calls:

as you saw:

  1. This function reads a contract called implementer from _ERC1820_REGISTRY
  2. If the function finds an implementer, that implementer is called.

Let's explore this registry and see what implementors are.

Registry and implementors

All ERC777 tokens are related to the Registry's contract:

This address is used by ERC777 tokens to store the set Hook recipients. These Hook receivers are called "interface implementers".

This means Alice can choose Bob as her interface implementer. If Alice receives or sends ERC777 tokens, Bob will receive the Hook.

Alice can manage different Hook types. Therefore, when Alice sends tokens, she can choose Bob as the implementer of the interface, and only when Alice receives tokens, she chooses Tom as the implementer.

She can also choose different interface implementors for different tokens in most cases.

These preferences are stored in this mapped registry:

_interfaceHash is the ID of the interface implementer chosen by Alice for an event.

And anyone can read Alice's interface implementor with this function:

As you can see, this is the function we encountered earlier in the VRA code.

The variable _TOKENS_SENDER_INTERFACE_HASH is used as _interfaceHash, which can be any byte. But the VRA token uses these bytes to identify this type of Hook:

Receive Hook

To set up a Hook receiving function, Alice only needs to call this function on the registry and enter Bob's address as the _implementer parameter.

She must also specify an _interfaceHash. She will get this _TOKENS_SENDER_INTERFACE_HASH from the VRA token code.

There is one more important detail.

After setting up the implementor for the VRA above, Alice will also be aware that even if other ERC777 tokens are transferred, Bob will receive the call. Such as imBTC [5] , imBTC has the same _interfaceHash on sent tokens.

This is due to the fact that all ERC777 tokens share the same registry contract to store Hook preferences. But it's up to ERC777 tokens to assign names to their Hooks, and while sometimes they are similar, not always.

How to find ERC777 tokens

Calling the registry is a feature of all ERC777s. So we can try dune.com [6] to call all smart contracts that call the registry.

We can use this SQL script. In fact, we should have additionally filtered out the token addresses, but at least we had a perfect start and ended up with 78 addresses.

Translator's note: dune traces table [7] Will record the internal call record of the transaction.

Is this registry the only possibility?

Theoretically, no one can guarantee that some token happens to use this 0x1820 contract as a registry. But we can use dune.com [8] Come check.

it returns these addresses

0x1820a4b7618bde71dce8cdc73aab6c95905fad24 0xc0ce3461c92d95b4e1d3abeb5c9d378b1e418030 0x820c4597fc3e4193282576750ea4fcfe34ddf0a7

We checked and 0x1820 is the only registry with valuable ERC777 tokens. The tokens of other registries are not as valuable.

The general situation of Hookable tokens

ERC777 is not only a standard with Hooks. Also ERC223, ERC995 or ERC667. They are not that unusual. You must have heard of the LINK token that implements ERC667 [9] 。

Attack vector using arbitrary call

This is a recently discovered attack vector for one of our customers.

Researchers generally assume that ERC777 tokens make calls to callers and receivers. But in fact, the initiator and receiver can choose any "Bob" as the Hook receiver.

So imagine what happens when combined with those contracts that make arbitrary calls to any address with any data?

There are arbitrary call functions that can be widely used in DEX aggregators, wallets, and multicall contracts.

Translator's Note: The arbitrary call function means that there is a function like this in the contract:

function ute(address target, uint value, string memory signature, bytes memory data, uint eta) public payable;

It can call any other method.

Attack method:

  1. The attacker finds a target contract (Target) that allows arbitrary function calls
  2. The attacker calls on the target:
  3. registy1820.setInterfaceImplementer(Target, hookHash, Attacker)
  4. Now, our Attacker is the implementer of Target
  5. The Attacker will be called with the hookHash used in the ERC777 token.
  6. Whenever the target contract (Target) receives ERC777 tokens, Attacker will receive a Hook call.
  7. The following attacks vary depending on the Target code:
  • Attacker can re-entry when some users execute functions in the target contract
  • Attacker can roll back directly, so that the user's transaction will be restored directly

If the DEX aggregator calculates that the best conversion path is through a DEX trading pair with ERC777 tokens, then it may encounter problems.

Protect

After hours of discussions with customers, we found a solution that doesn't break arbitrary calls.

It is best for the project side to limit the use of Registry1820 as the address of any call. Therefore, no attacker can exploit arbitrary calls to set the interface implementer.

Talking from experience

Projects and auditors must pay attention to the Hook behavior described in ERC777. These tokens make calls not only to receivers and initiators, but also to some other Hook receivers.

In this sense, projects that allow arbitrary calls must take special care and consider another attack vector for ERC777.

View Original
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • Reward
  • Comment
  • Repost
  • Share
Comment
0/400
No comments
Trade Crypto Anywhere Anytime
qrCode
Scan to download Gate App
Community
English
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)