aptos-core icon indicating copy to clipboard operation
aptos-core copied to clipboard

Coin metadata considered harmful

Open the-fool opened this issue 1 year ago • 4 comments

The Coin standard should be slimmed down to only include decimals and supply in its metadata. The fields name and symbol should be removed.

Justification

Metadata should be a separate concern from the primal interface for coins. Here are some reasons why coupling metadata to the coin standard may not be an optimal design decision:

  1. Not all coins have a name or symbol. Sometimes coins are implementation details for internal bookkeeping, and not meant for public discovery.
  2. Some people will not find it intuitive that a coin has both a name & a symbol.
  3. Some people will want richer metadata (such as logo URLs or longform description). 3a. A versioned metadata standard is better suited to this kind of evolving feature. 3b. Given that developers will use an additional on-chain metadata registry anyway to store logo URLs (etc), it is cleaner to shift all non-essential metadata to a built-to-purpose coin registry.
  4. The name and symbol of coins should be upgradeable. For example, a project may change its branding but wants to retain the same coin type. If the coin standard has name & symbol, then it should provide an interface to alter them -- but this growing complexity is creeping beyond the scope of the standard.
  5. The standard does not enforce uniqueness of name nor symbol. This is a possible source of confusion & debate, and best to be avoided when designing this fundamental interface.
  6. The extra metadata requires extra storage. This is not likely a huge issue, but it is still best to be parsimonious with basic interfaces.
  7. The datatype for name & symbol may not be future proof. Its type was already changed once (to String). It would be better to have this kind of coupling to datatypes done with a versioned metadata program.
  8. The attributes name and symbol have a different quality than decimals. The decimals attribute is practically required in all cases to know the value of a coin. But most programs can (and should!) effectively ignore name and symbol. There are no constraints nor uniqueness guarantees for name and symbol, so they cannot be used to index coin types. These arbitrary strings are more akin to "tags", and when viewed as such, it is strange to have only 2 of them.

Suggestion

Create a versioned metadata registry that can store coin information on-chain. Owners of coins may opt-in to publishing their metadata. In the inevitable event that the metadata standard requires an update, a new on-chain version can run in parallel to the old.

This registry will take on the complexity of updates to coin metadata, enforcing constraints, and making the data available.

Counter-arguments

  1. Justification item 1 is wrong -- all coins do have a name & symbol.
  2. A separate coin registry is extra work.
  3. With a separate registry module, creating a coin & posting its metadata will take 2 transactions instead of 1.
  4. Changing this now will cause a lot of developer headache.

the-fool avatar Aug 31 '22 01:08 the-fool

Hey,

I appreciate you summarized it all in one place.

What I can add there is I saw already several times how developers are trying to use coin symbols as some ID in their code, like:

let symbol = coin::symbol<T>();
if (symbol == b"USDT") { do something };

As the symbol and name are not unique, it's an easy way to make a mistake in a smart contract which will eventually lead to security issues.

borispovod avatar Aug 31 '22 04:08 borispovod

Yikes. Yes, I can imagine that the symbol attribute can be a source of confusion for people.

The funny thing is that name and symbol almost certainly should be ignored by on-chain programs, since there are no guarantees as to their value's uniqueness nor their meaning.

Which indicates that name & symbol are mostly a matter of "off-chain" concern.

the-fool avatar Aug 31 '22 13:08 the-fool

Thanks for this issue!

I'm not going to argue about the notion of name and symbol, I don't follow the logic where they might not have one or the other or it might be unintuitive to not have both. You also argued with yourself :smile: .

While we can leave this issue open, we won't be changing it for myriad reasons:

  • We have entered a point in contracts where we can no longer change the ABI.
  • Someone could just as well use string::utf8(type_info::struct_name(type_info::type_of<T>()) to get some other name
  • The use of on-chain metadata for what the coin is intended to represent is valuable. My only regret is that we didn't put a URL in there for folks to identify it... maybe we need to add a CoinInfo v2 -- never too late :)
  • A central registry is not something that I think we should be building at the start, it becomes a land grab exercise and requires attention. I would love to see the community come together to build this.

If we notice that there are practical (not theoretical) security concerns around name and symbol, we can minimally abort on those functions and prevent further use of them.

This is a decentralized framework. NFTs also can have the same name and collection name. Individuals can easily be confused if they ignore the TokenId and just use collection name or name alone.

I reckon there is no right or wrong way here. My perspective is we should have richer data on chain in ChainInfo. I wish we had added a field for URL as well. :slightly_frowning_face: ... I think ultimately the longer term solution is to have an on-chain registry.

Also it is worth noting that we can easily update CoinInfo to CoinInfov2 with more fields. We would then check the existence of v2 first and then v1 if it didn't exist. We could also add migration capability... so in the event that we want to revamp the coin standard.. there's infinite possibility, but let's iterate a bit and see what other things we overlooked.

davidiw avatar Sep 08 '22 05:09 davidiw

Thanks for the discussion & keeping the issue alive.

One way to boil down the argument is to ask: when should an on-chain program make use of the name or symbol? I can't come up with an example. Since neither of these can uniquely identify a coin, and any filter based on symbol/name can fall victim to spoofing, these fields are almost certainly red herrings for on-chain logic.

A corollary is that metadata around a coin is only for off chain concerns. And that's why a URL makes so much sense! Solana adopted this pattern - where the on-chain coin type only had the barest metadata (decimal precision, owner).

Now, it's certainly nice to have on-chain storage for coin metadata, since that storage can be a single source of truth. But once we go down that route, then we need to have logic for administering it. And that can get pretty hairy for 1 module, especially a primitive module like Coin.

As for the "landgrab" quality of a registry, I'd suggest that the semantics should never guarantee uniqueness for URL/name/symbol or anything besides the primary key for a coin (which is its "type"). The only ownership we can check on-chain is whether the signer has the same address and the type, and so there's no practical way to regulate that this coin is the real USDT, anyway.

It's not really important that the registry is "centralized" -- just that coin metadata administration is a separate concern, warranting a separate module. This way, as the coin metadata gets richer, the raw CoinInfo would stay the same. People can just opt in to storing their metadata on chain.

the-fool avatar Sep 13 '22 17:09 the-fool

Great arguments. I can see we are arguing on opposite ends of the spectrum. In one case, you prefer more off-chain, but I feel very much like that's way too centralized and leads open to questions of what am I looking at. You are right in that we currently don't have any admin functionality around coins, but we could theoretically add it at some point in time for future coins.

davidiw avatar Sep 25 '22 19:09 davidiw