In the frozen shadows along the vast walls that mark the boundary between Degenland and the world beyond, I stand guard, much like the Nightâs Watch of old. Forever bound to this duty, I often come across ancient ledgers, carried by brave souls, hoping their tokens might find a place in the annals of icpcoins.com.
Some of the problems devs come across while trying to pass the gate:
Canât make their ledger source replicable well enough to prove it compiles to a wasm with a specific module hash (I donât want to run scripts from anons without checking them first which means they have to either not have complicated obfuscated scripts or make a docker container of some sorts) There is a popular ledger going around with .sh file and a base64 encoded things that get eval-ed and thatâs not something I will run
The ledgers are not tested. In my journey, Iâve come across awesome libraries that at particular versions somehow came short after a few thousand records and there is no way of knowing if they will perform unless someone tests them
Ledgers arenât audited. The IC hack-hackathon era left us with a dozen ledgers of all sorts that people randomly use, but none of them were really audited. Even the beloved Psychodelic WICP ledger is massively flawed with the special ability to throw errors while transferring funds. Iâve notified organisations who were susceptible to the attack and theyâve got their handling fixed
Not blackholed. Such a ledger can be modified by its controllers and isnât decentralized even tho itâs running inside a decentralized protocol.
No transaction history. No comment, but itâs bad.
Distribution - Unknown and unwitnessed
For the purpose of simplifying the explanation, letâs coin a term - Napkin ledger. That is a ledger that is as decentralized and secure as someone keeping account balances on a napkin. All of the LP in dexes paired with a napkin ledger can be stolen. You canât really call a napkin ledger - crypto. Itâs like a man dressed in Supermanâs suit that is not Superman.
It seems to be not immediately obvious for not-so-obvious reasons:
A ledger that is not DAO-controlled or blackholed is a napkin ledger
A ledger that is blackholed, but nobody can verify its module hash comes from public source code is a napkin ledger
A ledger that is blackholed and verifiable, but has vulnerabilities is a napkin ledger
A ledger that is blackholed, verifiable with no vulnerabilities, but nobody witnessed its distribution is (stretching it a bit here) a napkin ledger or you could say Samâs ledger.
I believe we need to protect the newly arriving users and not expose them to risks they donât understand. It seems most who unknowingly took a risk that went boom will later blame Dfinity for âallowing itâ.
Solution:
There is a solution I believe and it seems to be pretty easy to come to. I am just summing 1+2 here. Yes, there is the SNS and it solves these, but it doesnât fit everyone and also it wonât give you secure ledgers for utility tokens like @ellipticdao 's TAL
NNS votes on SNS ledger wasms and stores them in a canister with a clear upgrade path with patches to the latest version. These are the ledgers SNS uses and are pretty secure and battle-tested.
Someone can create a blackholed canister, that uses that registry and installs new ledgers with initial params. It will be the only controller and it will update these ledgers automatically with patches. (Casually blackholed ledgers will be struck with a specific version and that isnât as good) That will make them as secure as SNS ledgers (Except the part that an SNS DAO can refuse a ledger upgrade). They will still need additional distribution contracts so they donât become Samâs ledger, but thatâs a different problem.
What do you think of this? Is it something the SNS team is okay with and can guarantee that the wasm registry canisterâs interface wonât change? @lara@bjoernek If it changes then the blackholed controlling canister will stop upgrading ledgers. It could also be NNS-governed. Maybe someone is already making that as we speak. SNSes also need additional ledgers.
In terms of user experience for newly arriving users, I think we need is a graphical interface to provide all that information, not everyone in around web3 has the technical knowledge to get into all the details, including myself.
Hereâs some information Iâd like to be displayed based on the frozen shadows along the vast walls that doesnât mark the boundary between Degenland and the world beyond.
-The Ledger (Name or group, a description or what is it about)
-Is it DAO controlled, Blackholed, both, or none(napkin ledger)
-What exactly does it mean to be blackholed and napkin (tool tips)
-If its source code is Public or Private
-If the Hash Module can be verified that comes from the public source code (Verifiable)
-If the code has vulnerabilities (need list of Trusted auditors and only for ledgers with verifiable public source code)
-If vulnerabilities are found, list them and the potential risks around them
-If passed the Audit, who did it and why they are to be on the Trusted Auditor list
-If it had a public verifiable initial distribution, and if it does, preferably show in pie charts
Is there any project like this outside the IC? to take it as an example. I know thereâs companies like Certik, but itâs all based on just paying their re-selling distributors. How come we canât do something completely decentralized?
It seems like a big adventure to hop in, not only for code but also to find those auditors and make those ledgers to get verified.
I mentioned this topic area on a DSCVR space yesterday⌠I agree that we (IC collectively) need to tighten up our ledgers. I understand the why weâve got to where we are - weâre about 12-18 months behind where we should be with token standards. ICRC-1 through 3 should have been agreed a long time ago.
However looking back doesnât help where we are now. The honest truth is weâre far too vulnerable to bad actors using most (not all) of the token ledgers on IC. The key problem we have is that there isnât an easy way to see/ audit the code a canister is running. I honestly think that this should be a higher priority than ckETH.
Can you imagine going onto the IC dashboard, searching a canister and having the option to view source code or at the very least know that the canister === a github repo.
Iâm not a super leet coder and I could stick a backdoor into a ledger canister and deploy and update in 30min or less⌠without any change showing to the candid file/ public interface. This has just given me an idea - perhaps a multi-sig canister type could be created where a single developer principal cannot update a canister code (at the IC level)?
With ETH integration weâre going to get more scammers and at the moment our tendency for napkin ledgers is setting us up for a bad situation.
Devs are responsible for making their builds easily and safely replicable. The dashboard canât do the verification unless a project is a really simple almost one-file contract, like the verification Iâve put in Blast. Itâs just hard for a dev to set it up properly. Basically, you build the project, get the hash of its binary, and compare it to the one working on the IC.
Not sure what you mean overall. We arenât that vulnerable. From the ICPcoins in the list, only Tendy and Boxy arenât secure and they are working on it. All the rest on the list are perfectly fine. There are other tokens in the ecosystem - most without teams, no sites, no liquidity in pools, whitepapers, or any info. Anyone can create a dozen of these in their lunch break. Some of them are decent, we havenât listed everything good, but we are in the process of doing so.
Your interface doesnât play a role in the security of a canister, module hashes and source codes do.
No need for a new canister type. You can have a canister that is the controller of another one and does this. Itâs how DAOs work.
Fair point with canister being controlled by another canister⌠as long as the controlling canister is blackholed/ DAO upgradable.
Are all the canisters you mention blackholed or DAO controlled? Iâm not talking about code specific vulnerabilities like the one you found. Iâm talking about the ability for a dev to upgrade the canister with new code. For example sticking in a new update method which can alter the ledger state.
The risk is that a dev could in a couple of minutes push new code to the ledger and be away with the funds before anyone notices the module hash and source code donât match.
I agree that source code/ module hashes are the key⌠however without monitoring this is next to useless. Sure you can verify my code when I launch but whoâs checking the canister module hash every few minutes to see if Iâve been a naughty dev?
In essence Iâm agreeing with you that there is a problem with the current way devs are creating/ using ledgers. Iâm not critiquing your solution.
EDIT - Sorry I should say I like your solution BTW for getting verified code into the ledgers. Am I right in thinking that a dev could still upgrade the canister though?
Well, this tells me things need a lot more explaining. Iâve already planned on adding tooltips & badges for âDAO governedâ, âblackholedâ etc, but it looks like I should prioritize it.
Yes, these are all secure. DAO controlled. OGY through their own DAO. XTC - Sonic SNS. The rest are NNS-governed.
I think we might be crossing wires here a bit. Iâm not commenting on ICPCoins or specifically on the tokens youâve included. Although I like that you are auditing the tokens you are adding
Iâm making a general point that on the IC itâs crazy easy to create a ledger or any smart contract, and then update the ledger with malicious code without anyone noticing. This is the issue.
EDIT - Sorry I missed the bit in your first post about the only controller being the canister installing the wasm. Iâve re-read and like your solution. Again, Iâm agreeing that this is a problem. Your solution is a good work around.
Iâd still like to see a way to routinely check or get alerted if a canister hash unexpectedly changes. I know cover protocol was trying to go down this route but that died when psych left.
Oh, I see. Yes well, outside this list pretty much everything is non-blackholed, non-audited, and hard to verify. And some of the teams are good-intentioned, but they canât afford to pay for an audit so they stay away from blackholing. Their only solution for getting a good secure ledger is with the mechanism Iâve proposed.
A stream of random thoughts that donât go anywhere and may muddle the situation further, but probably should be said.
The issue with trying to standardize the actual wasms of ledgers is something along the lines of âany sufficiently interesting token requires some unique functionalityâ. Sometimes this is simple. For example, the OGY canister uses the ICP canister, but we added a feature to allow âsuper principlesâ that have ledger rights. We use this for the DIP20 passthrough and hope to deprecate it once we activate ICRC2 and the main DEXs can switch over. But we needed that like 16 months ago and if weâd needed to wait for ICRC2 we just wouldnât have had DEX functionality.
Other functionality is more complicated. Like YC charging a % on each transaction, or other kinds of demurrage.
This makes the build and replicate super important. Psychedelic was working on Cover at one point and ICDevs sponsored a Chrome extension that would warn you if you were using a non-validated wasm: Complete: ICDevs.org - Bounty #9 - Cover Browser Plugin
Of course, leaving it up to the user to install something like that is a usability nightmare.
One other consideration, that I donât really know the answer toâŚAXON deploys tokens and the token is a subcontractâŚso it isnât really compiledâŚwell maybe it isâŚbut it is put into the parent wasm and then deoplyedâŚI donât know if you compile it separately if the wasms match. I think this may be a question for @claudio as he worked on the system upgrade features for motoko.
Never mind who is going to read and validate all these contracts/upgrades. DFINITY is likely the only player in the ecosystem who has the resources to write a rust-based contract and have it audited. But rust is an awful language for the âcommon personâ self-auditing. My personal opinion is that until system contracts are written in a âsmart contract shapedâ language that is high level enough to be read by âmostâ(aka a âtrustable mass of programmersâ) there will be an almost unbridgeable trust gap. Right now that is likely motoko and solidity. I havenât read many Azel contracts, but they at least have the advantage of being in a common language that âmostâ programmers know.
I think most of the time having something basic that works is going to be okay. Yes, you can add things inside the ledger to get a speed boost and add special features similar to what YC did, but thatâs a huge tradeoff that requires big teams to be done right.
Hi all,
very interesting discussion! As I was tagged, let me share some initial thoughts on this.
What do you think of this? Is it something the SNS team is okay with and can guarantee that the wasm registry canisterâs interface wonât change? @lara@bjoernek If it changes then the blackholed controlling canister will stop upgrading ledgers.
I donât think we have thought about this, so I think this is not a guarantee that is given right now.
Some potential difficulties that I see:
A blackholed canister always has the risk that it cannot be changed if any bugs / problems are found later. Of course on the other hand it provides stability / verifiability that lasts. I am sure you are aware, but thought it might be worth recalling for everyone.
An upgrade might sometimes require more than just a WASM. For example, one problem that is also not yet solved for SNSs is the following. The ledger canister can be upgraded to support ICRC-2, but for this an upgrade requires upgrade arguments. Similarly upgrade arguments are need for example to reset certain configurations in the ledger, e.g., the token symbol*. This is currently not supported by SNSs, as it is a bit unclear who would provide these arguments. For ICRC-2 support, one can argue that this could be set by NNS decision to the overall SNS framework - included in the next ledger version that SNSs can upgrade to. However, things like the token symbol need to be changed on an individual ledger-basis (some might even argue that it should not be supported at all). So due to these aspects
it might be conceivable that the SNS framework needs to be adapted in the future
I expect there might be similar challenges in your example (questions regarding who could provide args if this would ever be needed)
* I have to double-check this, but I think this is one of the examples that is already supported by upgrade arg
Iâm not a super leet coder and I could stick a backdoor into a ledger canister and deploy and update in 30min or less⌠without any change showing to the candid file/ public interface. This has just given me an idea - perhaps a multi-sig canister type could be created where a single developer principal cannot update a canister code (at the IC level)?
I was wondering if you know the possibility to look at a canisterâs âhistoryâ?
Note that this would not help with the attack that you describe below, where someone upgrades the code to something maliciously and runs away with the tokens.
However, it can help in making the canister more verifiable: without looking at the history I could look at a canisterâs code today and tomorrow without noticing that in between it was running a version with a backdoor. By looking at the history, I can see if unexpected upgrades were done.
Yeah thatâs interesting - I didnât know that! I think canister history is certainly part of the security package along with alerts and verifying the canisterâs hash against a codebase.
I would really love this to be a thing on ICP⌠given enough time I might be able to code this myself but Iâm quite new to rust and still getting my IC dev skills up to speed.
@infu is a lot better at coding than me - do you fancy building a canister verification/ history/ alert system? Youâve got a good head for this kind of stuff!
Iâll help write the Dfinity grant request for you if needed (I honestly think this would be a no-brainer) and Iâve got an OpenChat bot (work in progress) which could handle the user alert side.
Thanks, all information is going to be helpful.
Please let me know if some of these statements are wrong (I havenât had the chance to go deep into the ledger yet. For now overall architecture will be good enough). Donât feel obligated to explain too much. If you tell me where I am wrong, I can read the code and figure the rest:
A canister can set the NNS gov canister ârrkah-fqaaa-aaaaa-aaaaq-caiâ as controller and later anyone can make proposals of type âNNS Canister Upgradeâ to upgrade this canister (In this case - when there are unexpected changes in the upgrade system)
Not sure thatâs going to bring much value. A lot of the ledgers donât need monitoring since they are secured by the NNS. Also, funds can be drained from everywhere in 4sec after a malicious upgrade. So basically, that system will be monitoring non-blackholed non DAO governed ledgers? and sending SMSes to people that itâs all gone and they canât do anything
Maybe it will be still valid for other types of canisters, havenât thought about that.
We are going to try to make a canister that installs NNS-blessed ledgers once the latest icpcoins upgrade is complete.
@infu Is there an official procedure to be listed on ICPCoins? Could that be made official? $SLICES 5000 team contacted you since September 24th and so far no response. It would be good to know if there is a procedure for a token to get listed. At your convenience, please check out $SLI open-source code here : 5000SLICES/5000-SLICES-AND-GOLDSLICE-DIP20-STANDARDS at master (github.com)
If by sub-contract you mean actor class, yes these are essentially compiled with the wasm embedded in the wasm of the importing actor (or actor class). The code should match that of the separately compiled actor class, bar some unforeseen compilation artifacts Iâm unaware of.