sui
sui copied to clipboard
[sui framework] add decimals to TreasuryCap for Coin<T>
This is important info for wallets etc. to know about a fungible token. I'm not sure if TreasuryCap is the best home for this information (e.g., we may want a big registry for this + token name info etc in the future), but it is the only place we have for now.
This change is inspired by user questions about the minimum denomination of SUI.
Please, have a look at book examples as well: https://github.com/MystenLabs/sui/tree/main/doc/book/examples I'll add a CI that makes sure they compile later!
Re approach in general, honestly I wouldn't add decimals to TreasuryCap for a number of reasons:
- It is very common to wrap TreasuryCap making it undiscoverable
- Often we don't know where the TC is, we have to trust an application / user with that
- This is a meta information, and does not affect anything but display right now (since not discoverable onchain)
But I have a counter suggestion: emitting events with currency metadata. Now why would we use events for that?
- From every Coin we have its type, from type we know the module, from module we know when it was published -> we have full path to the transaction that led to coin creation, hence we have access to the metadata (not just decimals).
- It will be easier for explorer / dapps to get all events emitted by Coin module -> discoverability to max
- We can track all Coins ever created with all their metadata and creator address
Events approach addresses discovery problems and metadata collection but gives no information for dapps on how to treat balances and how to match them onchain (ie if I have an oracle BTC => ETH, both have different decimals, would be cool to know that in the module). But putting it to TreasuryCap not helping with either.
Please, have a look at book examples as well: https://github.com/MystenLabs/sui/tree/main/doc/book/examples I'll add a CI that makes sure they compile later!
Re approach in general, honestly I wouldn't add decimals to TreasuryCap for a number of reasons:
- It is very common to wrap TreasuryCap making it undiscoverable
- Often we don't know where the TC is, we have to trust an application / user with that
- This is a meta information, and does not affect anything but display right now (since not discoverable onchain)
But I have a counter suggestion: emitting events with currency metadata. Now why would we use events for that?
- From every Coin we have its type, from type we know the module, from module we know when it was published -> we have full path to the transaction that led to coin creation, hence we have access to the metadata (not just decimals).
- It will be easier for explorer / dapps to get all events emitted by Coin module -> discoverability to max
- We can track all Coins ever created with all their metadata and creator address
Events approach addresses discovery problems and metadata collection but gives no information for dapps on how to treat balances and how to match them onchain (ie if I have an oracle BTC => ETH, both have different decimals, would be cool to know that in the module). But putting it to TreasuryCap not helping with either.
Love the events idea, I think this makes much more sense!
@sblackshear Created this buddy https://github.com/MystenLabs/sui/pull/4558 to implement events approach.
@sblackshear @damirka I imagine we'd need some RPC method that would let us load an event by the struct type + the object, otherwise it'd be annoying to have to iterate through all events to load the decimals any time a token is displayed?
I'm also curious if decimals is similar to other display-only metadata, like a token name and icon. If they're similar, would we also want to solve that with a similar solution (using events)?
I imagine we'd need some RPC method that would let us load an event by the struct type + the object, otherwise it'd be annoying to have to iterate through all events to load the decimals any time a token is displayed?
I'm also curious if decimals is similar to other display-only metadata, like a token name and icon. If they're similar, would we also want to solve that with a similar solution (using events)?
Yes, now we need to figure out a way to get this data off chain, but that is outside of the scope of this PR. Previous solution with decimals inside the TreasuryCap gives almost no way for discovery, since Coin has no information leading to a TreasuryCap and even if it did, there's a high probability that TC object will be wrapped and inaccessible for ID queries.
Re symbol (token name) - I would suggest using a type name (T from Coin<T>). We're not a typical system in that sense.
Re icon - perhaps event could serve this purpose but at the same time many applications (eg bridges where users supply coin types for the system) might not have icons. And forcing everyone to submit an icon on chain as an argument will cause confusion. If we decide to add it, I would encourage making this parameter optional - there might be no icon for a Coin (est 3/5 of times).
Also worth noting that some Coins will not have metadata at all; it will exist only for currencies which were created with a TreasuryCap. Many others (eg LP tokens, regulated coins, implementable coins) cannot be constructed with create_currency hence won’t have any metadata.
Perhaps we should address the last point somehow by exposing some "emit metadata" function but that will lead to possible duplicates, as we can't guarantee that the exposed function was called only once per type.
To summarize I'd convert these points into an issue and start a broader discussion on improving wallet experience. Worth noting that we will have more options once dynamic child loading sees the daylight (for example a 'centralized' coin registry will be possible).
Killing in favor of https://github.com/MystenLabs/sui/pull/4558/