Hi Everyone!

It is my great honor to share with you the CYCLES-TRANSFER-STATION - the CTS. The goal of the CTS is to bring the native CYCLES to the mainstream for use as a stablecoin. As many of you know the native cycles are stable at 1-TCYCLES = 1-XDR. This makes for the perfect stablecoin for the world-computer platform. The CYCLES stablecoin is perfect for services where a value must stay the same, such as an online t-shirt store, a DeFi stablecoin lending contract, storing money without price volatility, and many more services and dapps that need stablecoins. In this post I will share an overview on how the CTS manifests it’s goal.

As many of you know, the native CYCLES must be held by a canister-smart-contract living on the internet-computer blockchain and cannot be held by a key-pair-principal-identity alone. This brings us to the first function of the CTS: a mainstream-user can go into the CTS website UI (without writing any code) and create a personal smart-contract that holds, receives, and transfers the native CYCLES for the user. We call this personal smart-contract a CYCLES-BANK. Each user creates their own CYCLES-BANK to manage their CYCLES. Creating a CYCLES-BANK is a one-time thing, once a user owns a cycles-bank, it can last forever. Through the CTS website UI, the user can burn ICP and mint CYCLES straight into their cycles-bank (without any coding). As of the time of this post, creating a CYCLES-BANK costs 5-XDR one-time-fee and comes with a 1-year lifetime, 10-MiB of storage-space for the cycles-transfer-logs, and 2.0-CTSFuel for the cycles-bank.
For each cycles-transfer or transaction, the internet-computer blockchain network charges some cycles to the cycles-bank-smart-contract. The CTSFuel of the cycles-bank is cycles for the network transaction costs that are kept separate from the main cycles-balance and is labeled as the CTSFuel-balance. The storage-space cycles-cost is paid in advance ahead of time for the lifetime of the cycles-bank and when the lifetime is lengthened, so that the user will not see a dwindling cycles-balance or ctsfuel-balance for the network’s storage charges.
Within the cycles-bank UI, the user can lengthen the lifetime without limit by paying from it’s cycles-balance for the storage-space cost for the lengthened time. The user can grow the storage space (as of the time of this post up to 1-GiB) by paying from it’s cycles-balance for the added storage space costs for the remaining lifetime. The user can topup the ctsfuel-balance by using cycles from the main cycles-balance. Within the cycles-bank UI the user can transfer cycles and see the transfer-logs.

This brings us to the next function of the CTS: The CYCLES-TRANSFER-SPECIFICATION is the method that canister-smart-contracts can use to transfer cycles between themselves. The specification contains a memo field that can be used to identify specific cycles-transfers for payments for services. The cool thing about the cycles-transfer-specification is that businesses and services can create their own custom canister-smart-contracts that implement the cycles-transfer-specification and then be compatible with every cycles-bank to receive and send cycles! Blockchain smart-contracts for the win!

type CyclesTransfer = record {
    memo: CyclesTransferMemo;

type CyclesTransferMemo = variant {
    Text: text;
    Nat: nat;
    Int: int;
    Blob: blob;

service cycles-transfer-specification : {
    cycles_transfer(CyclesTransfer) -> ();

A technical point on the specification is that there is no return value. This is because if there was a return value, a malicious smart-contract could for example return an error value indicating the cycles were not accepted while still accepting the cycles in the call which renders the return value useless. Cycles-transfers use the platform’s built in system functions for seeing if the cycles sent in a call were accepted or refunded.

The final function of the CTS is the CYCLES-MARKET. For the native CYCLES to succeed as a stablecoin within the world-computer, there needs to be a way for people to liquidate and trade their cycles into different currencies. The CYCLES-MARKET is the place where people can trade the native cycles for icp and icp for the native cycles in both ways. When trading on the cycles-market, users set the TCYCLES-PER-ICP-RATE for their position. This keeps the cycles stable at the market-value.

One of the current roadmap items of the CTS is making each user’s CYCLES-BANK into a wApp, where the smart-contract is in the user’s solitary controll, so that not even the CTS SNS DAO can change the code of the user’s cycles-bank. Only if the user opts-in to an upgrade can the user’s cycles-bank be updated. This gives the user complete surance for their valuable CYCLES.

Another item on the CTS roadmap is letting the cycles-banks transfer cycles direct from cycles-bank to cycles-bank or canister. Since cycles-banks can transfer cycles to any canister-smart-contract that implements the cycles-transfer-specification including smart-contracts that are not part of the CTS system, and since canister-smart-contracts that are not part of the CTS system can possibly be malicious and hold up a response which would stop the sender cycles-bank from being able to upgrade, currently the cycles-transfers go through a safe-transferrer-canister that makes sure that even if a callee holds up a response, the cycles-bank can still upgrade. Once the canister-safe-upgrades feature ships, user cycles-banks will transfer-cycles direct canister-to-canister without any intermediary.

The CTS is here:!

I welcome your feedback, questions, and comments!

Thanks for reading.




A few questions about assurance:
Is the code opensource (minter and cycles wallet)?
Has it been auditted?
Is the smart contract minter blackholed?
Who are the controllers?


Hi @northman!
The source code of the CTS (minter), CYCLES-BANKS, and of the CYCLES-MARKET will be public soon with a license similar to the license of the IC source code. The plan for the minter is for it to be controlled by a SNS DAO. The plan for the CYCLES-BANKS is for each user to control their own cycles-bank, and for the user to have full control of the upgrades (see here about wApps). As the creator of the CTS, I am the controller while the system gets set for the control by a SNS.
I want as many people as possible to audit the source code for the whole system when it goes public if you know people good for the task, do send them that way.
I suggest starting with small amounts first and see how the system works.


@levi This looks super interesting and I’m glad that you’re definitely taking the ICP approach of making the dapp be controlled by an SNS DAO while also making efforts to make it open-source for public contributions.
Looking forward to more updates!


nice work! @levi . do checkout GitHub - EgoDevs/ego for the wApps framework

1 Like

Very cool!

I’d recommend using GitHub - icdevs/candy_library: Library for Converting Types and Creating Workable Motoko Collections. We have an upcoming bounty to get this and the convenience functions ported to rust. It allows for a much more dynamic data structure to be used in the memo so that dapp developers can send custom payloads and additional standards can be built on top of it(CandySchema has been discussed but not implemented yet.). We are more than open to pull requests and suggestions.

A preview of the bounty can be found at Icdevs_fleeksite/2023-01-09-47-Candy Library - at main · icdevs/Icdevs_fleeksite · GitHub. Perhaps you’d like to implement this as another funding source?

1 Like

Thank you for the info. Looking forward to seeing this blossom.

@northman Thank you :pray:.

@LucidSamuel I will post updates here and on the CTS twitter:

@skilesare The cycles-transfer-specification can be built upon by serializing a custom type into the CyclesTransferMemo Blob variant, or by putting optional fields in the CyclesTransfer record.

@neeboo thanks for the reference! wApps/personal-smart-contracts are awesome!


I just tried CTS. It’s a good start.

Some feedback:

(a) I could create a Cycles Bank with 1.7 ICP… not sure how it meets with 15 XDR
(b) I got 1.59876 CTS Fuel and 10 MiB storage.
(c) The UI needs a LOT of work…starting with Fonts.

I think that some kind of invoice integration is required at the high level. Otherwise how this cycles-bank sending or recieving cycles?

1 Like

Hey @mparikh! Thanks for creating a CYCLES-BANK! Welcome to the CTS!
Yesterday I lowered the cost of creating a cycles-bank to 5-xdr (~1.7 ICP) and starting parameters to 10-Mib-storage and 2.0 CTSFuel, to kickstart the platform. I updated the post above to show the new cost and starting parameters. As always once a cycles-bank is created you can grow the storage and topup the CTSFuel without limit! When updating the cost, another constant needed updating to reflect the new starting CTSFuel value, thanks for the report, Now you should see the CTSFuel correct in your CYCLES-BANK at 1.99876 (starting with 2.0 and it uses ~0.001 CTSFuel during the creation). Can you clarify what you mean by invoice integration? Logs of the cycles-transfers are there on the bottom of the cycles-bank page below the ‘LOAD TRANSFERS’ button. Every cycles-transfer in and out is logged and showed. Clicking the burn-icp-mint-cycles button you can mint yourself some cycles straight into your cycles-bank and you will see a log for that. Let me know if you have more questions, I’m happy to answer!

1 Like

Hi @mparikh, thanks for the feedback on the UI, Check out the new font:

Took me some time to find one that is clearer and fits with the theme. If you have more suggestions for the UI, let me know, the feedback is helpful. Look out for a UI update on the CYCLES-MARKET page coming soon!


I know I’m late to the party but I just wanted to say this is really cool and I’m excited to use it. I’ve always loved the idea of using cycles as a stablecoin.


Thanks @levi for your update. Looking better by the day. I owe you an explanation in context of my cryptic comment about invoices. So here goes…

I view cycles as fiat for IC just as I view USD as fiat for the real world (in which I live in ). Meaning that I can use cycles to buy everything in IC (such as compute, storage etc) just as I use USD to buy food, drink etc in the real world.

With that model in mind, if you think about a corporation operating in IC (as opposed to the real world), really to it, the fiat is Cycles. It uses Cycles both internally as well as externally. By internally I mean in the sense of an inter-departmental use (dev vs sales vs runops) and by externally I mean in the sense of someone/something outside wanting to consume it’s service.

In that context, let’s assume for the moment that the corporation is a service providing an energy-pricing rss feed that consumes some outside feeds (outgoing https calls) to enable valuable trading alerts. Further suppose that the corporation has some customers that wants to pay for this service. Well it must generate an invoice for the customer and the customer pays for this service. Since this corporation wants (needs) to be it’s own bank, the customer pays on the generation of the invoice. How? Through cycles. Then when it comes times to pay for the previous mentioned https calls the runops uses the cycles stored in the bank marking it as an operational expense.

This is the rough outline of the invoices that I had mind. I can elaborate further if needed.

1 Like

This is a genius thought :100: as I can see immediate direction integration in communities. Well put & Brilliant reasoning :+1:t6:

Hey @LightningLad91, Good to see you here! Welcome, The party is starting!

@mparikh Thank you sir, and thanks for bringing up a specific use case, lets clarify how to use the CYCLES in that case.
I suggest the corporation generates an invoice first for the customer before the customer starts using the service with a specific amount of usage (time/reloads etc…) according to the payment and invoice. However, whether the corporation wants to charge the customer first and then let them use the service or if the company wants to first let the customer use the service and then charge the customer later, both scenarios work. In either scenario, when it comes time for the customer to make a payment, the corporation generates a bill for the customer. On the bill, there is a payment link or Q-R-code that the customer uses to pay the bill. This link looks like this:
This link takes the customer to the CYCLES-BANK page of the CTS, and pre-fills the cycles-transfer payment to the corporation. Then the customer clicks transfer/complete and boom! The corporation receives the cycles-transfer-payment, looks up the bill with the cycles-transfer-memo, and marks this bill as paid.
The about page of the CTS mentions this feature. You can try it yourself with your cycles-bank, put your cycles-bank-principal-id as the ‘for’ variable-value in the link and if the memo_type=Blob, make sure the memo is a valid hex string.
Like with every service on the blockchain, make sure you are transferring money to services that are either verifiable - code open source and canister wasm hash matches the reproducible build - or that you trust.

Does this take care of that use case? I’m glad to talk further.


You should consider developing for SNS-1

@memetics What does the SNS-1 community want? I’m happy to consider it.

@levi The SNS-1 community is exploring proposals for different use cases, though the most interesting project is for a BTC collateralized stablecoin as the SNS-1 DAO can utilize ckBTC. The model being considered is similar to that of MakerDao. We are looking for developers and anyone knowledgeable that could provide guidance on creating a proper stablecoin on the IC. I’d be happy to share more details if you’re interested.

@MikeJones I am with the focus on the CYCLES-TRANSFER-STATION and building the foundational systems for the mainstream use of the native $CYCLES as a stable-currency on the world-computer. The native $CYCLES are stable at 1-XDR(1.3-USD)=1-TCYCLES(trillion cycles) without a need to hold collateral.

If you want to talk further on the SNS-1, make a new forum post for those conversations.