kadena-io / KIPs

Kadena Improvement Proposals
16 stars 18 forks source link

Total supply (current chain and all chains) for fungible-v2 tokens #21

Open kitty-kad opened 2 years ago

kitty-kad commented 2 years ago
KIP Title Author Status Type Category Create
14 Total supply (current chain and all chains) for fungible-v2 tokens kitty-kad Draft Standard Interfaces 2021-12-09

Abstract

This proposal adds the ability to get the total supply of tokens on the chain and across all chains to the current fungible-v2 interface. This will help other tools (such as exchanges, coin trackers and Dapps) track supply and market cap over time and help tokens launched on Kadena be integrated into such systems in the future.

Specification

Two new methods are proposed.

1. total-local-supply

This returns the available supply on the current chain.

   (defun total-local-supply: decimal
     ()
     @doc " Returns all the available supply for the\
          \ current chain"
     )

2. total-global-supply

This returns the total supply across all the chains

   (defun total-global-supply: decimal
     ()
     @doc " Returns all the available supply across\
          \ all the chains"
     )

References

ghost commented 2 years ago

In my opinion, standards should be kept minimal (i.e. transfer-create is superfluous). It's unclear if some excessively granular design is always beneficial, but it helps when everything isn't all or nothing (progressive upgrades / wide compatibility / ...). Metadata standards seem to compromise between interoperability and flexibility. DEX devs are probably the ones who will have a final say when it comes to adoption. It's not pretty, but what about something like

(interface poly-metadata-v0

  (defschema entry key:string value:string)

  ; negative values => unavailable
  (defschema token-details
    id:string ; (= ticker)
    entries:[object{entry}] ; non-abbreviated name, descriptions, links, icons, etc
    local-supply:decimal
    supply:decimal
    exact-supply:bool ; indicates if supply is an estimation or actual
    genesis:time)

  (defun token:object{token-details} ( token:string ))

  ; this is slow, but useful outside Tx context? (could be paginated)
  ; (defun tokens:[object{token-details}] ())
)

Or alternatively if there is no use case for these within other modules (front-end only)

(interface poly-metadata-v0

  ; numeric values encoded as string
  (defschema entry key:string value:string)
  (defun token-details:[object{entry}] ( token:string )))

maybe name can be confused with NFT's immutable metadata, such that some clear distinction is needed

kitty-kad commented 2 years ago

Having a separate interface is a good idea. Just to clarify - were you thinking to have this implemented on a contract alongside the fungible-v2 token interface or on a separate class that stores metadata for tokens?

In particular asking because I'm not sure why there is a need to take token:string as an input if its on a single smart contract.

ghost commented 2 years ago

I think the team wrote at some point fungible and poly-fungibles interfaces will be merged (which is good, but maybe I misread so don't take my words for it). If this is the case, metadata standards should be designed around it. Module references with multiple interfaces are something like (defschema awa token:module{poly-fungible-v1 metadata-v0}). Also we can consider having some generic metadata querying mechanism, but as previously mentioned, it's unclear how to balance flexibility and interops, such that other modules who accepts modrefs as parameters might need some guarantee that their data requirements are met. I can't see any use case for those data directly within modules though, unless maybe some immutable archive tool, but it's not really relevant. I don't know what the industry use (GraphQL?), but the basic form is like

(interface metadata-v0
  (defun query:[string] ( path:[string] )
    @doc "return result, or list supported inputs following path (view on depth n+1)" ))
  (defun queries:[[string]] ( path:[string] for:[string] )
    @doc "same as above, view on depth n+1->n+2" ))
; e.g.
(awa.query ["tokens"]) ; -> ["AWA"]
(awa.query ["tokens" "AWA"]) ; -> ["ticker" "supply-estimation" "supply-estimation-error" "genesis" "local-supply" ...] 
(awa.queries ["tokens" "AWA"] ["supply-estimation" "notfound"]) ; -> [["666.66"] []]
; since database reads are cached, this should be fine

not sure but once we have dapps interacting with lots of random modules, such things will be required for decent UX. Then it would need to be curated to mitigate "undesirable content", but this is better solved separately

Just to clarify - were you thinking to have this implemented on a contract alongside the fungible-v2 token interface or on a separate class that stores metadata for tokens?

Both, it's not mutually exclusive. DEX contracts can accept tokens without metadata, since it would be just a front-end thing. but other dapps can be more restrictive

kitty-kad commented 2 years ago

The main benefit I think is to help Dapps scale. For Kadena it is theoretical as there isn't a DEX live outside of beta, but it seems like other ecosystems use this metadata.

For example ERC-20 defines total supply and optionally the name and symbol. Having this provides a much nicer UX for Dapps like uniswap/pancake swap then if it wasn't available (particularly name + symbol). In general - there was a proposal to have token registries on Ethereum in ERC #22, this particular comment stood out

it will be ideal together with the token standard as it would allow any contract to use any asset as opposed to a single one. It will also simplify the creation of apis as they only need to worry about the token names as opposed the contract addresses.

Also, having this data to be purely stored to DEXs or other sources, even if via an interface implemented on the DEX creates issues around

  1. Who should be the one providing that metadata to DEX's
  2. It bloats the DEX un-necessarily (i.e. every dex would have to duplicate the data)
  3. How to handle conflicts where multiple tokens share the same sticker? This would lead to a horrible UX regardless, but at least it wouldn't cause a fundamental issue, where as (defun token-details:[object{entry}] ( token:string ))) would fail in this scenario (unless it takes the token address as the input?)
ghost commented 2 years ago
  1. If metadata is directly provided by concerned modules, this solves headaches around finding who's the authoritative source of infos for each ones, or having to maintain a curated database through reputation systems of some sort. Fungible devs would write their tokens implementing both interfaces. I think this is important enough, considering other services like wallets will also need it.
  2. To be clear I wasn't saying this should be implemented on DEXs, but either directly on the fungible modules, or on some kind of wrapper at worse
  3. Now that you mention it, I think it's a bad idea to enforce uniqueness across tickers, since there is only 17576 three latin letter names (46656 if we include digits, but bigger issues are probably hoarding and front-running). So tokens can be accessed by uuid arbitrarily chosen for each projects scope.

also pagination can be solved by either having metadata standards for unchanging chunks (easy to cache) or interval queries (start / limit). i don't really know

kitty-kad commented 2 years ago

What about this as an alteration to the proposal? I like the idea of having a separate interface, and this seems to address the points discussed above

(interface poly-metadata-v0
  @doc " Interface to allow tokens to expose metadata"
  (defun total-local-supply:decimal ())
  (defun total-global-supply:decimal ())
  (defun symbol:string ())
  (defun name:string ())
)
kitty-kad commented 2 years ago

One thing - is that I'm not sure about the naming as poly-metadata, is Kadena moving towards an ERC-1155 standard which combines NFT + non NFT tokens into one? If so then could be quite good.

Though right now as there's a difference between the two, could be good to keep them separate