IS20 - Token Standard - Decentralised and Interoperable

Hello everyone,

I’d like to introduce the v1 of the IS20 token standard. We believe that the standard goes the next step in bringing an interoperable and decentralised standard to the IC, and solves a number of issues still present in existing standards. Our mission at InfinitySwap is to advance DeFi on the IC.

Our repo is here:

Highlights:

  1. Using canister_inspect_message to avoid DOS/ cycles draining.
  2. Decentralised market-place for topping up the cycles of a canister
  3. Intended compatibility with ERC20/DIP20 and Ledger Canister
  4. Bug fixes -
    – fixes transfer fee bug where fee levels are changed during the operation of a transfer call
    – Uses an alternative to the ic_cdk storage, which eliminates the following issue Heap corruption in storage · Issue #73 · dfinity/cdk-rs · GitHub

More information can be found here:

Thoughts comments suggestions are all welcome. Thanks guys!
Let’s buidl together.

5 Likes

This is really exciting stuff. A lot of work has clearly been put in.


High-level comments & questions:

  • The auction idea is really interesting. The core issue is that transaction fees are collected in the native token, but canisters run on cycles. Auctions are a really smart way to exchange native tokens for cycles. The way you set up the auction (i.e. your cut of the fees depends on your cycle bid relative to others) means that there is theoretically no upper bound to the # of cycles that a token canister can collect in an auction. It does, however, still depend on how much the community values the token. People will not bid more than they think the token (or their estimated cut) is worth.

  • Do you expect token owners to blackhole their canister from day one? How will future extensions be handled? For example, I imagine there are many variations of auctions that can be run, and the current proposed auction may turn out to not be the version that wins in the end. If I blackhole my token canister, then I wouldn’t be able to upgrade my canister to take advantage of a better auction variation. In that case, do I just create a new token and migrate the old token balances to the new token canister?

  • You mention that IS20 will support both an ERC20-like approve / transferFrom flow as well as an ICP ledger-like transfer / notify flow. Which flow will the InfinitySwap DEX use to swap its users’ tokens? What are the security tradeoffs between using one flow or another, or are they used for different purposes? One example is that for transfer / notify the recipient canister may be offline or out-of-cycles when notify is called; but it’s possible the sender already transferred the tokens.


Low-level comments & questions:

  • inspect_message only works on update calls, not queries. That’s fine for now, as queries don’t consume cycles. However, this apparently will change in the future, so hopefully inspect_message can be updated to support queries as well (if that is even technically possible).

  • Why do you give owners the power to setMinCycles? Can’t the minimum # of cycles needed to run the auction be estimated algorithmically?

  • If a token canister has extra cycles left over from the previous auction, can it choose to skip the current auction and accumulate those fees for use during future periods of “famine”?

  • Will InfinitySwap run its own factory canister?

  • Transaction history seems to be stored on a single canister right now. While it is saved to stable memory between upgrades and stable memory is capped at 300 GB, that full 300 GB can’t be used currently because it is also loaded into wasm memory post-upgrade, and wasm memory remains capped at 4 GB. That might not be enough to store a token’s entire transaction history. Do you have plans on a BigMap-like storage solution where transaction history is sharded across multiple canisters? I believe the ICP ledger canister currently does that. Another solution is to have the token canister read and write directly to stable memory to utilize the full 300 GB, but that will incur performance overhead.

  • Balance queries (and other sensitive queries) should ideally use certified variables to ensure that users are getting the right data. Is that on the roadmap? The ICP ledger canister also does this.

6 Likes

Wow guys really great work on this standard, really hope DFINITY is in close talks with you about this, they should have eyes on. I love the cycle marketplace idea to top up the canister. I believe harris0n from Psychedelic stated you guys were going to use their DIP20 standard, but this is much more ambitious.

3 Likes

Thanks,

These thoughts and contributions are very much valued.

High level comments

  • “Do you expect token owners to blackhole their canister from day one?” One alternative would be to make the factory canister the owner, which would then enable the owner to take advantage of a subset of features, like changing the parameters of the token, but perhaps not others like increasing the token supply.

  • Our DEX will be able to use both, it is at the user’s discretion. This enables one to avoid using an intermediary liked wicp.

Low - Level

  • This is a great question, and I think if query calls are to be billed, the foundation should have an answer about how we can stop a user from draining cycles, otherwise this change could create drain-attacks.

  • "Why do you give owners the power to setMinCycles ? Can’t the minimum # of cycles needed to run the auction be estimated algorithmically?"To some extent this is. A lot of this is run algorithmically but we can make tweaks to the interface.

  • "If a token canister has extra cycles left over from the previous auction, can it choose to skip the current auction and accumulate those fees for use during future periods of “famine”? So the amount of tokens that are sold at auction is adjusted algorithmically, depending on the amount of cycles a canister has been given. This follows an exponential pattern, so if the number of cycles is twice as great, the amount of tokens offered should be halved.

  • InfinitySwap will run its own factory canister.

  • Thank you for your comments on the transaction history and certified variables, we will certainly follow up with the team on this.

3 Likes

I don’t think that transaction data needs to be stored on chain, if there are easier way of implementing scalable storage. IMO, the transaction data can be certified by BLS signatures and can be kept off-chain, while we wait for scalable storage to be implemented by Dfinity.

1 Like

Thank you! Our interface conforms to the DIP20 on the ETH side.

1 Like

inspect_message itself is at least as expensive as a query, so there is nothing to be gained by moving access checks from the query to such a pre-query.

I expect that the system will have to implement generic DoS protection for queries (a bit like Cloudflare), because once it hits the canister, it’s a bit late already.

1 Like

IMO, the transaction data can be certified by BLS signatures and can be kept off-chain, while we wait for scalable storage to be implemented by Dfinity.

Hmm, this basically sounds like off-chain certified variables… Not sure if that’s even possible.

For example, transaction data may run in the hundreds of GBs. It’s too big to sign the whole thing. So users request “slices”, i.e. specific transactions they’re interested in. Now, signatures need to be created on-the-fly for those slices. If you query an off-chain node, that node won’t be able to generate those signatures; only IC subnets can generate threshold signatures. Based on this, I don’t think it’s possible to keep it off-chain.

I do hope scalable storage on the IC is soon available. There are a couple of projects in flight, I think:

  • 64-bit wasm memory (currently stuck at 4 GB)
  • full 300 GB stable memory (currently stuck at 8 GB)
  • storage subnets for cheaper and more plentiful storage

BigMap was also open-sourced, but a multi-canister approach like that is pretty complex and not developer-friendly, especially with inter-canister queries not possible.

1 Like
  • “Do you expect token owners to blackhole their canister from day one?” One alternative would be to make the factory canister the owner, which would then enable the owner to take advantage of a subset of features, like changing the parameters of the token, but perhaps not others like increasing the token supply.

Interesting, but will the factory canister be blackholed then? If not, then it runs into the same problem of the factory canister controller deploying new code to the factory canister that gives it the ability to maliciously update its token canisters.

Since the IC provides upgradable smart contracts (something not possible on Ethereum), I wonder if it’s possible to provide strong guarantees about a smart contract without actually blackhole-ing it (which is the default on Ethereum). Need to think more about this…

We could sign the hash of a block of transaction data. The IC subnet would sign the hash of a bundle of transactions before it is put into off-chain storage.

1 Like