Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow CosmWasm contracts to mint new custom sdk.Coin denoms #671

Closed
sunnya97 opened this issue Nov 9, 2021 · 13 comments
Closed

Allow CosmWasm contracts to mint new custom sdk.Coin denoms #671

sunnya97 opened this issue Nov 9, 2021 · 13 comments

Comments

@sunnya97
Copy link
Member

sunnya97 commented Nov 9, 2021

Currently CosmWasm-enabled chains have two token standards existing in tandem, CW20 and sdk.Coins. While CosmWasm contracts currently have an easy mechanism for interacting with sdk.Coins denoms that already exist on the chain, there's not an easy plug and play solution for contracts to mint new sdk.Coins denoms (instead, they tend to use CW20s).

Such a mechanism would be useful for many chains and applications that want to use the CosmWasm framework for writing logic in, but would prefer to only support a single token standard (sdk.Coins) for their asset layer, due to increased integration costs of multiple standards.

For example, in Osmosis, we would like to add a permissioned CosmWasm module to allow developers to build DeFi contracts on top, but if these protocols need to mint a new token, would like them to mint native sdk.Coins rather than CW20. This is because our AMM mechanism, which is written as a native Cosmos SDK module, is built to only support sdk.Coins, and would prefer to avoid the complexity of supporting both standards right now.

In order to make this minting process "permissionless", we would need to namespace minted denoms so that any contract can mint new denoms. Because CosmWasm contracts have unique address, we could just have the generated denoms be cw/{minting_contract_address}. However, because a single contract may want to mint multiple tokens, we should also have an additional namespace per contract. So minted denoms should be cw/{minting_contract_address}/nonce. This nonce can be chosen by the contract when minting new denoms (or just use increasing sequence numbers if that is preferred).

One solution that was proposed was to consider using the cw-ics20 contract with a loopback ibc channel. However, according to the ibc-go README, it seems that loopback ibc channels are not yet fully implemented.

@ethanfrey
Copy link
Member

This is a very nice idea.

I think cw20 is valuable and there are many cases for full cw20 token support that are not available in native tokens (rebasing, whitelisting, transfer taxes, snapshots, etc). However I believe 80%+ of cw20 tokens are just cw20 base more or less. In these cases, being able to use a native token is a great path to interop.

You could even have a reverse-wrapper contract that takes cw20 tokens and "unwraps" them into custom native denoms that could serve as a generic bridge on eg. Osmosis to bring unmodified contracts that run on other chains and bridge them to your DEX.

@ethanfrey
Copy link
Member

One large piece is missing for usability however, and that is the metadata.

CW20 defines a symbol, name, and decimals.
Native tokens have a symbol and there are some standard about decimals (eg. if it starts with u it is 10^-6)
ibctransfer provides a custom denom as a hash, but maintains some metadata in the "denom_trace", minimally the remote denom as a string

I think we need a solution for this to make this usable in real products. And I would generally lean to something like "denom_trace" (which you would have gotten for free if we could use ibctransfer over loopback). But since we would have to build this ourselves, maybe define a custom coin metadata struct based on your experience on Osmosis. Let's design this with the end user in mind.

@sunnya97
Copy link
Member Author

sunnya97 commented Nov 10, 2021

The Cosmos SDK bank module has a type called DenomMetadata that contains that metadata.
https://github.com/cosmos/cosmos-sdk/blob/master/proto/cosmos/bank/v1beta1/bank.proto#L78

This are registerable in the bank module.

Just to confirm, you don't guarantee name collision resistance for CW20 tokens on a chain rn, right? Two CW20 tokens could have the same name or symbol?

@ethanfrey
Copy link
Member

Yes, the cw20 name is not unique, and the only real identifier is the contract address. However, it makes it nicer to show some Metadata.

Terraswap has some whitelists to deal with fake eg. mGoog tokens. I assume any app would have that, but even an unverified name is a nice first step.

@alpe
Copy link
Member

alpe commented Nov 15, 2021

I was very happy to see this feature request 👏 . I had spiked this more than a year ago (#262) but there was no demand from the community. Minting natural coin types can be very powerful but also dangerous when abused to spam the system with random coins, like UX/ performance issues.
Do you have something concrete in mind to limit this to a subset of contracts or should this be a new message type available to all contracts?

@giansalex
Copy link
Contributor

It looks like evmos Intrarelayer ERC20 <-> sdk.Coin

@ethanfrey
Copy link
Member

Thanks for the link.
Yes, it is a very similar concept we are trying to achieve.

I think there are open questions about allowing multiple native denoms per cw-contract.

Also, making this controlled by the contract, not by an external module. There are some tokens (eg. with rebase, transfer tax, etc) that do not map to a native coin and will not want to allow such mapping, or will want to have some control on it.

But this is a great starting point to look at for a cosmwasm-specific design. Thank you for the contribution.

@sunnya97
Copy link
Member Author

sunnya97 commented Dec 16, 2021

I've created a tokenfactory module, that achieves the functionality I outlined above, essentially allowing any ​cosmos sdk address (including a cosmwasm contract) to mint new denoms namespaced by their address and a nonce. The creator of the denom, is set as the admin of the coin, allowing them to mint, burn, and forceTransfer coins at will. They can also transfer ownership of the admin privileges. An account can use either CosmWasm or x/authz to perform more complex delegation of authorities.

osmosis-labs/osmosis#584

I think if we create a CosmWasm Module, or just use CustomMsgs, with this sdk module, this should allow us to create the functionality we want.

@alpe
Copy link
Member

alpe commented Dec 17, 2021

I think if we create a CosmWasm Module, or just use CustomMsgs, with this sdk module, this should allow us to create the functionality we want.

A custom msg and handler would be a quick solution to implement this feature without touching wasmvm messages and play with it today. I had added extension points to make this extension very easy.
The authZ of contracts can then be handled as you like in your handle and/or by calling your "tokenfactory" module.
I want to highlight that when your MsgCreateDenom handling is not restricted then this may cause unwanted side effects for clients reading this data.
evmos intrarelayer relies on a gov process to enable minting for contracts. That addresses the spam risk.

Beside the quick custom msg/handler solution, let's add more ideas how "minting" can be integrated proper into wasmd.

@sunnya97
Copy link
Member Author

I was considering that we might want to add some sort of governance permissioning or fees to the MsgCreateDenom action, but then realized that technically we already do have a non-spam resistant way of creating denoms... ibc

I suppose that's not a good reason to not fix the spam problem here though. One thing was, I wonder if we might want to only allow CosmWasm modules to use the module, not normal SDK addresses. In Osmosis specifically, CosmWasm will be permissioned anyways, so the spam resistance is already happening upstream. Is there a way for the tokenfactory module to know whether the address calling it is a CosmWasm contract or not?

@alpe
Copy link
Member

alpe commented Dec 17, 2021

In Osmosis specifically, CosmWasm will be permissioned anyways

👌

Is there a way for the tokenfactory module to know whether the address calling it is a CosmWasm contract or not?

You can use the HasContractInfo() method to identify if the address belongs to a contract

@faddat
Copy link
Contributor

faddat commented Dec 28, 2021

I hadn't seen this before, and think that this would simplify many things.

@alpe
Copy link
Member

alpe commented Sep 30, 2022

I will close this in favour of #911 .

@alpe alpe closed this as completed Sep 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants