ENSIP-31: Payment Preferences

Send 20 USDC to an ENS name. Which chain?

An ENS name can resolve a receiving address on many chains, so knowing the name is not enough. The sender still has to pick the chain, and the recipient’s answer often depends on the token. Today there is no way to learn that preference from ENS, so wallets guess, or the two sides sort it out over chat.

ENSIP-31 lets the recipient publish an ordered, token-specific list of preferred chains through their ENS name. A wallet can read the list before choosing a chain, then can resolve the receiving address on that chain exactly as it does today.

For example, alice.eth publishes that for USDC they prefer Base first and Ethereum second. A wallet asked to send them 20 USDC reads that record, picks Base, and resolves their Base address as normal.

The preference is stored as an ordinary ENSIP-24 data record with a key like payment-preference[<multichainTokenHash>], so no new resolver methods are needed.

I am especially interested in feedback on how the Multichain Token Registry fingerprints a token. Symbols such as USDC are not canonical. Contract addresses are canonical, but each address identifies a token on only one chain. Once a token exists across multiple chains, there is no single canonical identifier for the multichain token as a whole. ENSIP-31 currently addresses this by hashing an immutable snapshot of its chain-specific token representations. I am very open to other approaches for identifying a multichain token.

The proposal is a draft with the Pull Request open at ensdomains/ensips#87.

I would be appreciative of any feedback from the ENS community, and am, of course, happy to answer any questions.

3 Likes

From the POV of blockchain engineering, there is no such thing as a single token that exists across multiple blockchains. Even USDC deployments on two different chains, sharing the same contract address, are considered two distinct assets.

In practical terms, many people may consider all deployments of USDC to be fungible, because they are all “backed” by the same entity. However, 20 USDC on one chain isn’t guaranteed to always be worth 20 USDC on another chain, as low liquidity or the cost of moving assets between chains can separately impact the value of each.

Therefore, trying to present distinct assets as one unified asset is tricky. Alice might say she prefers Base to Ethereum, but that doesn’t explain the exchange rate between the two, and Alice might need 21 USDC if sent on Ethereum but only 20 USDC if sent on Base.

It seems like payment details comprise 3 data points: which assets are accepted/requested, how much of the asset is required depending on which asset is chosen, and the order of preference between those assets. Publishing just one of these data points seems unhelpful when the other two still need to be conveyed somehow.

I agree that trying to create a canonical token name is problematic. Either we have canonical token names for tokens that are deployed to more than one chain or we don’t.

At the core the preference can be established by a list of 7930 contact addresses. It basically signals, I would like to be paid in USDC first on Base and then if another USDC contract appears in the list, on Ethereum for example.

If it’s just a single list, then it’s not very useful for resolving the values, for a client, because there is a lot of external processing of the data that needs to be done, such as looking up the token contracts against lists of known tokens, and ordering the chain preferences by token, but at least it’s accurately representing the payment preferences, and not introducing new registries and concepts, like a multi-chain token.