Enable Canisters to Hold ICP

I am not sure. I am pinging the team to answer this.


In the proposal we are working on for enabling canisters to transfer ICP, they’d be able to transfer ICP they already hold too. (I suggest keeping amounts small though, the Internet Computer is still in Beta)


Hey folks, I have updated the main description with the current dates and timelines.


Awesome - so if everything goes well, we could have this implemented on the 20th? Awesome stuff!


Very much so.

I will reveal some context: the “ability for canisters to hold ICP” is basically removing a line of code. Canisters have a restriction that bars holding ICP.

The catch (which you will see in the design doc): is that there are some consequences and risks from removing this restriction which need to be thought out and tested. Team believes they have a handle on these risks (and how to progressively address them) and want to lay out their thinking for community to vote on.

1 Like

I’ve been thinking a good bit about this and I’m concerned about any number of existential threats to canister security. Has just using the ECDSA methodology off having canisters ask the subnet for a key and then using that key with the ledger been considered? Since you all are considering rolling that out presently, perhaps it reduces the attack vectors? Looks like the ledger uses ed25519…is that compatible? I’m not saying we shouldn’t ever have canisters hold ICP natively, but if you’ve really cracked it maybe we don’t have to?

I get that the same tech secures the network, so maybe it is a non-issue. Expert opinions would be welcomed here.

Hey folks, I want to update the thread that the implementation of the project will take a bit more time than I had originally commented. The reason is testing. Security team wants to do more testing to make sure risks are handled if he canister restriction is removed. So I have moved the original deployment time from “week of September 20” to “Week of September 27.” This is, of course, assuming NNS motion proposal passes, of course.

Personal responsibility note: the security team always intended to do more testing week of September 20 so i was wrong to have put the original date. I jumped the gun.


Those are great news!!! Thanks for the update :slight_smile:


Hi everybody! Here’s our plan for enabling all principals to transfer ICP, including canisters. We’ll be happy to receive feedback!

NNS Proposal: Enable all principals to transfer ICP


Enable canisters to transfer ICP.


Currently canisters can receive ICP, since you can send ICP to any address. An address is derived from a principal and an optional subaccount, so each canister automatically has many addresses associated with it just like any other principals.

Canisters are blocked from transferring ICP though. This block is implemented by a check in the ledger that only self-authenticating principals (i.e. allows principals ending in 0x02), and specific whitelisted canisters to transfer ICP. Canisters do not have self-authenticating principals and can therefore not transfer ICP.


Remove the restriction such that any principal is allowed to transfer ICP with the exception of the anonymous principal.

Backwards compatibility

All self-authenticating and whitelisted canisters can continue to transfer ICP, this proposal just permits other principals to transfer ICP too.


Enabling canisters to transfer ICP may put control over significant value in the hands of canisters on application subnets. This is a significant change, previously only whitelisted canisters that all lived on the root subnet could transfer ICP.

A canister holding ICP may for instance be co-located with a canister developed by an attacker, which could try to do a jailbreak and steal ICP. We have therefore been thinking hard about security and will continue to analyze security aspects of enabling all principals, including canisters, to transfer ICP.

Canister smart contracts on the Internet Computer are unique in the sense that they can be easily updated by the controller of the canister. This ability enables developers writing their business logic on smart contracts to continue evolving their applications without having to deploy new contracts. However, this also means that if an end-user were to send ICP to these canister smart contracts they will be trusting the controller of the canister.

This implies a risk of malicious developers trying to do fraud on the Internet Computer. Anybody can deploy a canister. Moreover, the controller of a canister can upgrade the Wasm code running the canister. So users need to be wary of rug pull operations: set up a canister running benign Wasm code and get people to transfer ICP to it, then change the Wasm code to steal the ICP.

We are working on mitigations: sandboxing of canisters (which will take a while); providing guidance on how to check which principal controls a canister and it could potentially be a dummy principal so the canister is immutable; and how to verify the Wasm module corresponds to a piece of source code.

In particular, providing the ability check that a canister is immutable and the ability to verify the code of a canister are necessary features to allow opting in to a similar trust model to existing “smart contracts” that predate the launch of the IC. However, it must be stressed that this is an opt-in. Even with these solutions in place, there is a risk that people will treat mutable canisters as immutable smart contracts and fall victim to a rug pull. We would be interested in feedback whether this is an acceptable risk.

Enabling canisters to trade ICP also enables an additional path to make off-the-record ICP transactions, because canister controllers are not ledgered. Agreeing to this proposal means accepting the lack of traceability.

Another risk is that currently canister developers do not have control over which application subnet their canister is created on. We expect in the future the Internet Computer will offer better control and better means for developers and end users to understand the risks of transacting ICP in each subnet depending on node distribution and other properties.

Some of the mitigations, e.g., sandboxing of canisters will take time to develop and will not be ready before this proposal. We do not consider the mitigations and additional security features as blocking the proposal. But we consider the ability for canisters to transfer ICP to be in an experimental phase. We encourage experimentation with small amounts of ICP but discourage large amounts of ICP.

Rollout plan

The main change is just a few lines of code in the ledger to enable all principals, except the anonymous principal, to send ICP. We will make this an NNS proposal.

At the same time, we communicate widely that we view this proposal as being in an experimental phase. As long as the Internet Computer is in Beta, we strongly discourage sending large amounts of ICP to a canister.

Once we have rolled this proposal out, it is hard to take back since many canisters will rely on being able to transfer ICP. In the worst case, while rollback is hard it would be possible to blacklist some principals just like the anonymous principal is blacklisted, but we prefer not to go there. We therefore do not call this an experimental feature, but we want to start with an experimental phase.


I’m curious what the security risks are here, and besides people trusting a canister with a malicious controller (which will always be an issue, and is an issue now with Ethereum smart contracts, as anyone can code any logic into the contract), I’m wondering if it simply boils down to the replication factor of the subnet?

Why are application subnets less secure than the system subnet? Wouldn’t the only reason be the replication factor? 34 nodes is harder to corrupt than 7 nodes.

Are there other security risks here?

How could a malicious canister on the same subnet “jailbreak” another canister?

And I want to push a few points here again:

  1. Please create a bug bounty program and start to crowd-source security testing of the IC. Get the best abd brightest white hats to put this thing through the ringer
  2. Please consider node shuffling so that we can further prevent node operator collusion

Security is of the utmost importance not only to this feature, but to every feature and application of the IC. Once large amounts of value start flowing through canisters, the security may be tested even more and end up breaking in production.


‘How to verify the WASM module corresponds to a piece of source code seems to be especially non-trivial.

1 Like

Could you elaborate a bit more on this? When you say jailbreak do you mean somehow escape the WASM runtime?

Personally, I think this is acceptable. However, I think foundation should be providing tools for investors to use in order to weigh the risks → “This canister can be updated”. With a solid foundation I think the community will a good job keeping one another safe and identifying clear scams. Ultimately scammer will always find a way IMHO.


I, too, accept this risk.


Whoa….what? Why? The transactions don’t go into the ledger? Being able to get transaction ids out of the ledger is actually a huge use case that apply to a wide number of potential applications.

This is yet another reason to not let canisters hold ICP and to instead let them ask the subnet to sign a transaction with an ephemeral key.

Maybe I’m misunderstanding? If canister A pays canister B I 100% expect there to be a record of it in the ledger canister so that other apps can verify the transaction and react to it.


I believe the other day I heard someone say ‘the challenge with the Internet computer is that because the compiled byte code is WASM, because there are multiple languages - currently, two major ones supported right now they compile to web assembly -it’s a bit trickier to verify the exact hash of the source code so you could potentially take the same source code compile it with different compiler flags on different architectures at different times of the day and you can get different output and so what we need here is a replicated system that everybody runs. For example that could be a docker image where it contains all the available binaries and libraries that you need to compile source code that then could be distributed out to different community members that they independently run and return the compiled byte code. And so that has not been built out yet there’s quite a bit of bits and pieces that need to be built first for that to happen but I’m sure it will happen at some point in the future.’

1 Like

I think this is a good point.


Norton say that this is about the controller transfers not being traceable. Fair enough. But from a dev standpoint it may be a best practice to be able to have custodial accounts for users that keep icp from being slushed together. This is especially important if regulators come calling. You could have business logic in your canister that keeps track of who owns what, but a schema that keeps users balances on ledger with documented delegation of custodianship would be safer, more auditable, and more trustworthy for the users.

This is admittedly probably an app by app decision, but some nice standard and best practices would be great to have before we start some Wild West defi shenanigans.

It’s a bit late tonight to think through it all at the moment, but perhaps the crypto experts could weigh in with a good scheme for assigning incoming icp to revocable custodial accounts for canisters operators. IE I’ll let you hold some icp in my name but I can revoke your right to move it around at my discretion. And it is traceable on the ledger.


It needs cooperation from the developer, of course, but then it’s not rocket science. See Verifying the code of the Internet Identity service – Blog – Joachim Breitner's Homepage for one way of doing it.


@skilesare - I interpreted this as “Canister A” is holding 100ICP. I give you controller access to “Canister A”, and remove myself. Effectively, I just made an “off the record” transaction. However, I don’t see how this would be different than me adding your device to my internet identity anchor, removing all my old devices, and having you generate a new seed recovery phrase. Or, if I just gave someone my key-pair. I don’t think we can ever 100% fully prevent this, and I hesitate to suggest we try.

Oops sorry, didn’t see your second reply. Leaving my post here anyways.


Needless to say, I will let @JensGroth address most questions. He has much better command of the intent, design, limitations, and trade-offs so we can all iterate publicly on the design.