Enable Canisters to Hold ICP


Expanding support for all Canister types to be able to hold and transfer ICP tokens. Currently, for security reasons, only NNS Canisters and users may hold ICP tokens


Discussing and working on a design proposal

What you can do to help

  • Ask questions
  • Propose ideas

Key people involved**

@JensGroth @roman-kashitsyn @bogwar Lomesh Dutta ( @ld-dfn1 )


  • 1-pager posted on the forum for review: September 10, 2021
  • NNS Motion Proposal (to approve design + project) submission: September 14,15:00 UTC September 15,15:00 UTC
  • NNS Motion Proposal (to approve design + project) expiration: September 16, 2021, 15:00 UTC
  • (If NNS proposal passes) implementation + testing would take around 1-2 weeks. NNS Proposal to upgrade the code with experimental feature: Week of September 27, 2021

Relevant Background

Due to security concerns we currently only allow whitelisted canisters (i.e., canisters on the NNS) to transfer ICPs. This feature expands the ability to transfer ICP to other canisters.

What we need:

  • IC Interface Spec includes the calls a canister must make to query for its ICP balance and to transfer ICP. Optional: specification of how to stake/dissolve/vote with neurons.
  • Removal of whitelist barrier so all canisters can hold ICP (unless we for security reasons decide to restrict access)
  • Testing (in particular so to ensure no NNS shielding blocks transfer of ICP)
  • Security review (including malicious subnets, where it ought to be the case a corrupt subnet can only act on behalf of canisters it hosts; the controller cannot be faked.
  • Stakeholders and plan for rolling out: developers such as Fleek? phased roll-out by first labeling it as an experimental feature (potentially limiting each canister to a few ICP), later offer e.g. fiduciary subnets with higher guarantees

Open question:

  • Consult SRE team for any operational concerns that may arise

Not necessarily in scope: staking and voting (P2), security level of canisters (developers and users may want assurance it is a high-security subnet the deploy on but we will leave the specification of e.g. fiduciary subnets to a different feature and just recommend not putting much ICP on a canister), CDK tooling to handle ICP on canisters.


Is this a dependency of enable canisters to control neurons? If not, can we have a separate topic for that?


Great question. I am not sure, tbh.

Let me ping the team to see if the right person (who is working on this) can comment publicly.


:snake: :oil_drum:

The design for the Internet Computer services was always that they don’t distinguish “outside users” from “canister users”, and that their APIs are accessible from other canisters without issue. The fact that our maybe most important canister doesn’t do that is somewhat embarrassing, and I hope we can drop this code soon.

(Fun fact: With the current ledger code, canisters can hold ICPs. They just cannot use them, as the canister-banning-check is on send().)


It would be great if we could get some official timeline on this.

1 Like

I just updated the Summary at the top

1 Like

Good point, @Hazel will try to get something that’s helpful.

1 Like

Unfortunately, the Jira, Notion, and Google Docs links are not public :frowning:

Hmm, they should be. let me look into that

ICP has so far been a feature that is not reflected in the Interface Spec, which describes only lower-level aspects. After all, in most ways ICP is “just” data in one particular canister, and is technically no different than data in other canisters.

I don’t think this needs to change, or that any change in the Interface Spec is needed. If there is documentation of the ledger cansiter (is there? hint hint), then that needs to change.

Removed them, those were outdated links.

This may be an uninformed question, but can someone expand on why ICP storage should be expanded beyond canisters in the NNS? The description above states that it wasn’t initially allowed for security reasons, but doesn’t really provide any information about the value of expanding to other canisters. I’m just curious if the value of storing ICP in any canister justifies the effort and security risks of doing so.


Without, you can’t really do any DEFI solutions on ICP. Example a DEX or liquidity pools would all need a way to hold ICP and other tokens. No issue with other tokens, but no way to do it with ICP. This is why DEFI is currently stalled on ICP… in my book it should be the number 1 priority, but I am biased in the fact that I’m building/waiting to deploy DEFI solutions.


Agreed; We’ve built a PoC marketplace back in June and the ICPts are held by the canisters but can’t be “claimed” – I hope they won’t be frozen forever if ICP moon :slight_smile:



Enabling canisters to hold ICP is very high up on our agenda. We are having discussions with the security and research teams to map out the path forward. I hope to come back with a timeline on this shortly.


Thank you for the explanation.

1 Like

Hey all, wanted to check in on a timeline here.


Thanks for asking Hazel, the current trajectory we are on is to have a design proposal for the community to vote on (and quick implementation afterwards if it passes).

Our current trajectory is to have the design floated this coming week (week of September 6th) for voting like Increased Canister Storage.


Another solution would be to have the NNS (or another governance platform) voting for adding canisters ID to the send_whitelist ? ( https://github.com/dfinity/ic/blob/89446f5a04f053040b4863eab5458446d925ed0e/rs/rosetta-api/ledger_canister/src/lib.rs#L1031 )


If I start depositing ICP into canisters today, is there any reason why those canisters wouldn’t be able to interact with the ledger post rollout?

This has been blocking me pretty badly, and I’d like to just push forward with a “No Withdrawals Yet” contingency.