Skip to content

Conversation

@fallen-icarus
Copy link
Contributor

@fallen-icarus fallen-icarus commented Jul 23, 2025

This CIP adds support for depositing assets into account addresses (a.k.a. reward/staking addresses) which helps alleviate some of the pain-points from the minUTxOValue requirement. The CIP also provides a mechanism for plutus smart contracts to get a sense of the account's current balance using account balance intervals similarly to how time is specified.


Rendered Proposal

@fallen-icarus
Copy link
Contributor Author

This is a first draft, but @GeorgeFlerovsky and I would like to start getting community feedback on it.

Tagging some people who might be interested: @Quantumplation @lehins @colll78 @michele-nuzzi

@colll78
Copy link
Contributor

colll78 commented Jul 23, 2025

Great CIP!

Can you add a script purpose that allows you to do partial withdrawals?

@fallen-icarus
Copy link
Contributor Author

fallen-icarus commented Jul 23, 2025

Can you add a script purpose that allows you to do partial withdrawals?

Why not just use the already present Withdrawal purpose? This purpose would be used for both full withdrawals and partial withdrawals. AFAIU only the ledger rules need to be changed to support partial withdrawal.

@rphair rphair added the Category: Ledger Proposals belonging to the 'Ledger' category. label Jul 23, 2025
@rphair
Copy link
Collaborator

rphair commented Jul 23, 2025

@fallen-icarus we'll tag it for Triage to be discussed at the next CIP meeting after it comes out of Draft: but if you would like to tag it for the meeting earlier (for more of that "community" feedback) please just say so (p.s.: and tag the editors in case we miss that message in the long conversation).

@michele-nuzzi
Copy link

@fallen-icarus maybe I'm missing something, but not supporting native assets means that minUtxo is solved only for ada-only utxos?

I think the big pain point is sending assets without minUtxo

@fallen-icarus
Copy link
Contributor Author

... minUtxo is solved only for ada-only utxos?

Yes, that is correct. This section discusses the concern for dusting attacks with native asset support.

I think the big pain point is sending assets without minUtxo.

That might be true for you, but that is not true for everyone. I have spoken to several projects and they would like to charge fees (in ADA) for their services, but currently the smallest fee they can charge is 1 ADA because of the minUTxO. Also, for DAOs whose treasuries are mostly ADA, using an account address makes more sense.

I would like to one day see support for native assets as well; but as the CIP says, why should we wait since we can safely add support for ADA now? It could be years before someone figures out a simple solution to native asset dusting attacks.

@Quantumplation
Copy link
Contributor

I think this does help with minUTxO though, because you can always withdraw from an account to cover minUTxO; so if someone has a very congested wallet, but wallets keep the reward account topped up, then the "solve" for utxo selection is less of a fixed point: select the UTxOs needed to cover whatever you're trying to do, and then furnish the minUTxO from the account. You don't have to go back to UTxO selection and potentially loop multiple times.

@michele-nuzzi
Copy link

but wallets keep the reward account topped up

Collateral taught us that making assumptions about the user wallet is not good, both for DevExp and UX.

Having support for tokens in the account helps everyone, solving both the singular case for ADA and the broader case for tokens

@michele-nuzzi
Copy link

I believe we could come up with a minAda for the account

minAda in the account would be significantly less problematic than minUtxo because you only have to have 1 shared minAda for all the assets, whereas the minUtxo implies an overhead for each utxo (the simplest utxo has at least the overhead of the address).

@fallen-icarus
Copy link
Contributor Author

fallen-icarus commented Jul 23, 2025

I think a minUTxO for account addresses would open up an attack vector. 🤔

Imagine if I have only 5 ADA in my account. You could mint a bunch of worthless tokens and deposit them into my account. Doing so effectively forces my ADA to be used as the minUTxO deposit in the account. I didn't consent to this. Now, in order to claim my 5 ADA, I need to do something with these worthless tokens.

This attack isn't possible with UTxOs since you can't use my ADA from other UTxOs to be your minUTxO deposit. You need to cover the minUTxO deposit yourself when you send me the worthless tokens and my ADA is still segregated from these tokens.

@michele-nuzzi
Copy link

you can always withdraw from an account to cover minUTxO

how does this not have the same problem you describe?

@michele-nuzzi
Copy link

one naive-ish way to solve for this attack would be to require authorisation to deposit in the account (either by pub key signature or by contract)

@fallen-icarus
Copy link
Contributor Author

how does this not have the same problem you describe?

You're right. It does.

one naive-ish way to solve for this attack would be to require authorisation to deposit in the account (either by pub key signature or by contract)

I don't think this would work for pubkeys since it requires the business to sign every transaction that wants to send them money. For it to work at scale, the business would need to automate the signing and have their keys online 24/7. This is a major security sacrifice just to allow filtering native asset deposits.

Also, I'd personally like to avoid requiring deposit script executions due to execution costs. Some services could possibly charge 0.01 ADA per tx, but a deposit script execution would add way more than that in tx execution fees.

@fallen-icarus
Copy link
Contributor Author

Perhaps it is possible to whitelist native assets in an account address' registration certificate? But I don't know if this would add too much overhead to still rely on Phase 1 validation. @lehins

@michele-nuzzi
Copy link

I'm not sure why everyone is so scared about executing scripts lately, but these are the relevant parameters

{
"price_mem":0.0577,
"price_step":0.0000721,
"max_tx_ex_mem":"14000000",
"max_tx_ex_steps":"10000000000"
}

that means that a tx that spends 100% of the max tx budget pays 14000000 * 0,0577 = 807800 lovelaces for memory and 10000000000 * 0,0000721 = 721000 lovelace for cpu

that is 1,5288 ADA of the MAX possible fee paid for a script execution.

I would find hard to believe a script that verifies the whitelist of contract (a single utxo ref in a linked list) to go over 2% of max tx budget

2% implies a ~0,03 ADA of additional fee

@fallen-icarus
Copy link
Contributor Author

IMHO a fee-based script is a workaround, not a solution. Since all we are trying to do is filter native asset deposits, a phase 1 check that also works for pubkey addresses would be preferable.

@michele-nuzzi
Copy link

a phase 1 check that also works for pubkey addresses would be preferable

agree, but, as you said, we don't want to put too much load on phase 1, so it would have to be benchmarked.

if it is doable it would be preferred.

regardless, in order to truly solve for minUtxo we need to consider CNTs

@lehins
Copy link
Contributor

lehins commented Jul 23, 2025

I am pretty sure we will also need to provide the ability to operate on multi-assets in accounts, because:

  1. it would be an awesome and desired feature in the community
  2. one of the important reasons why we also want to have this account enhancement is to potentially be able to do treasury withdrawals that will have multi-assets in them (that feature will need its own CIP). In the nutshell, it would allow annual budget be defined in stable coins, instead of volatile native asset.

Problems that I am aware of with respect to putting multi-assets into accounts are:

  1. the dust attack, where one could split junk multi-assets and deposit them into millions of accounts.
  2. attacking individuals with many junk multi assets, since it would cost them money to get rid of that junk from the account

Solution that comes to mind is to also require addition of ADA to the deposit associated with the account, where the amount of ADA would be proportional to the size of binary representation in memory of the multi-asset (which is similar to how minUTxO works). This has a few benefits:

  • it places an actual cost on the attacker that would try to send junk to accounts that are not controlled by the attacker
  • requires more skin in the game if an attacker wants to register millions of addresses and put junk in there, which is a similar deterrent that we get from the 2 ADA deposit that we already have today upon registration of accounts
  • if a user A sends some junk multi asset to another user B, it will cost that user B some ADA to get rid of such multi-aseset, if such multi-asset was undesired by user B, requiring to transfer some ADA with multi-assets would give user B enough money in order to get rid of it.

Naturally, this is still just an idea that I have not given good enough thought, but I have a feeling that it could work.

Slight complication I can see with this is with getting the deposit back. After all, we do not want to encourage users to drain accounts and unregister in order to get what could be a pretty big deposit. This could potentially be solved with a special "rebalance" certificate that allows users getting back surplus from the deposit by looking at current multi-asset balance in the account. I am just not confident that it is safe to do something like this automatically on a withdrawal, since there would be a dependency on some protocol parameter and that has implications for plutus scripts, but maybe that would be fine too.

@fallen-icarus
Copy link
Contributor Author

fallen-icarus commented Jul 23, 2025

@lehins Whitelisting CNTs in the address' registration cert seems much cleaner. The registration deposit could be exponentially proportional to the number of CNTs whitelisted. Then any tx that deposits a non-whitelisted CNT just fails (phase 1?) validation. This approach safely allows the account address owner to cover the minUTxO for all deposits.


EDIT: Actually, I think the whitelist could be checked during phase 2 validation. Phase 1 would only check that the receiving account is registered. This means depositing CNTs would require posting collateral. This seems fine since it is your fault if you try depositing a non-whitelisted CNT. ADA can always be deposited without specifying collateral.

@lehins
Copy link
Contributor

lehins commented Jul 23, 2025

Whitelisting CNTs in the address' registration cert seems much cleaner.

Whitelisting is a limiting solution, IMHO, since you need to know all multi-assets you want to accept a priori. In other words, if you'd like to accept a new token, you'd have to unregister and register back again, which would also require undelegation from DReps and Stake Pools.

Also, from what I understand about this suggestion, this is not an acceptable protection from ledger perspective, because it would rely on logic that is not directly enforced by the ledger. In other words, ledger has no knowledge or control of what is being validated in phase2. If we are to allow multi-assets in accounts, all of the enforcement must be done at the ledger rules level.

Most importantly, however, whitelisting does not protect against an attack where an attacker creates couple of hundred accounts with millions of multi-assets white listed. That would allow such an attacker to do a DDoS, and it would be fairly inexpensive.

Perhaps it is possible to whitelist native assets in an account address' registration certificate?

So, I am sorry to say, but this is not a viable solution.

@lehins
Copy link
Contributor

lehins commented Jul 23, 2025

AFAIU only the ledger rules need to be changed to support partial withdrawal.

@fallen-icarus You do need to mention that partial withdrawals will not be available in presence of Plutus versions that are already active on mainnet (PlutusV1-V3 today), otherwise this would be a backwards incompatible and unsafe change, which we must avoid.

@Quantumplation
Copy link
Contributor

Why would a partial withdraw look any different from just a withdrawal certificate with less ada in the wallet, from the perspective of plutus v1-v3?

The "account balance interval" stuff, or deposits, certainly wouldn't be visible, but any existing script can't possibly care whether it's a partial or "complete" withdrawal

@fallen-icarus
Copy link
Contributor Author

fallen-icarus commented Jul 23, 2025

Whitelisting is a limiting solution, IMHO, since you need to know all multi-assets you want to accept a priori.

I don't see how this is a problem. If I'm running a service and people need to pay me, they need to use a pre-approved currency. I won't accept payment in just any asset. If they need to send me a one-off asset, sending it into a UTxO is still possible. In what scenarios do you need to frequently accept random assets? 🤔

... if you'd like to accept a new token, you'd have to unregister and register back again ...

I personally don't consider this to be an issue since adding pre-approved assets to the whitelist for payments would be a rare occurrence. But if it is an issue, we can decouple the whitelist into its own certificate.

Most importantly, however, whitelisting does not protect against an attack where an attacker creates couple of hundred accounts with millions of multi-assets white listed. That would allow such an attacker to do a DDoS, and it would be fairly inexpensive.

I don't see how this attack is actually possible. The whitelist itself must fit inside a certificate which must fit inside a transaction. I doubt you can fit "millions of multi-assets" into a whitelist. My guess is that it is only a few hundred per address before the certificate size exceeds the tx limits. Plus, if we have the exponential deposit calculation like I suggested, it could be prohibitively expensive after only 20 assets whitelisted. The attack you're describing would require locking up millions of ADA.


AFAIK the number one use case for this feature is accepting payments or specific markers (e.g. vote counting). This implies a very finite list of assets that each account address needs to accept. I don't see why we need to enable support for depositing a lot of unique random assets into each account address.

@lehins
Copy link
Contributor

lehins commented Jul 24, 2025

Why would a partial withdraw look any different from just a withdrawal certificate with less ada in the wallet, from the perspective of plutus v1-v3?

Because there is an implicit assumption that some scripts might rely on the account balance to be fully drained. It might not affect anyone, but it might affect someone significantly. We just never know.

The "account balance interval" stuff, or deposits, certainly wouldn't be visible, but any existing script can't possibly care whether it's a partial or "complete" withdrawal

Presence of an interval or deposit would immediately disqualify any presence of PlutusV1-V3 scripts in a transaction. The only exception we have ever done intentionally to this rule was enabling reference inputs for PlutusV1, which was weighted very carefully.

@lehins
Copy link
Contributor

lehins commented Jul 24, 2025

I don't see how this is a problem. If I'm running a service and people need to pay me, they need to use a pre-approved currency. I won't accept payment in just any asset.

This fact of whitelisting has to be stored in the ledger state, which itself has the exact same overhead as just storing that multiasset for the account state in the ledger state. So, you are not solving anything with this.

I don't see how this attack is actually possible. The whitelist itself must fit inside a certificate which must fit inside a transaction.

It is not the transaction that is the problem, but the space whitelist would occupy in the ledger state.

I don't see how this attack is actually possible.

Imagine that I am an attacker and I submit a certificate that contains as many multi assets that you'd like to whitelist as transaction size limit allows. Now you have 16KiB of data that has to be stored in the ledger state. Rinse and repeat for more accounts until node is killed with out of memory. The reason why we have reward account deposit and minUTxO, is to prevent precisely this attack.

Side note. I think we should consider renaming withdrawal and deposit to something like credit and debit. It is really confusing discussing deposits, since accounts already have 2ADA deposit, which means something totally different.

@lehins
Copy link
Contributor

lehins commented Jul 24, 2025

I don't see why we need to enable support for depositing a lot of unique random assets into each account address.

It is not a problem of allowing depositing anything random into the account, it is a problem with storing the whitelisting in the state, cause it occupies the same amount of memory as the multi-asset itself. We could potentially make the deposit proportional to the size of the whitelisting. That could work too. However, it would be very similar to my suggestion, except the user that is creating an account would have to leave the deposit, instead of the one that is putting the actual multi-asset into the account. 🤷‍♂️
In this sense the difference is only in:

  • whether users are ok accepting any multi-asset from anyone, knowing that they will also get enough ADA to get rid of it
  • or giving the choice to the owner of the account which multi-asstes they are willing to accept.

FTR. We'd also have to cap the amount of any multi-asset that can be stored in the account to 2^64-1, but I don't think that would be a deal breaker 😄

@lehins
Copy link
Contributor

lehins commented Jul 24, 2025

I've made this CIP a topic for the next Ledger Working Group Meeting #20. Anyone interested in it is encouraged to join.

@fallen-icarus
Copy link
Contributor Author

I'd suggest to include a soft session like Acknowledgement from key infrastructure players such as:

  • Smart contract language maintainers (e.g. Aiken)
  • Offchain libraries maintainers (e.g. Mesh)
  • Wallet (e.g. Vespr)
  • Indexer (e.g. Blockfrost)
  • etc

While I understand the sentiment, this seems like a slippery slope. As my comment above highlights, two wallet creators can disagree. I am also against naming specific "key players" for each category because they are entirely subjective or context dependent, and doing so will give them power they shouldn't have. If people are against a CIP, they should voice their concerns in the discussion. IMHO this approach enables a much healthier discourse instead of "yeah well the representatives for each group have already agreed..."

@colll78
Copy link
Contributor

colll78 commented Oct 27, 2025

I'm not a fan of "key players" either. I do, however, agree that feedback from different components of the ecosystem tech stack is important to such a large scope proposal. Instead I would prefer:
Acknowledgement from infrastructure parties to be an open call for any and all smart contract language maintainers / offchain tx building maintainers, wallets, indexers, chain followers and so on.

This way we don't give any special designation to any projects without community consensus.

Copy link
Collaborator

@rphair rphair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fallen-icarus my apologies for not noticing that your 225dea8 had addressed @HinsonSIDAN's #1061 (comment). Assuming @colll78 also agrees the new language is acceptable as per #1061 (comment) I think this is now ready to merge & so marking Last Check for the next meeting as agreed at the meeting today.

@rphair rphair added State: Last Check Review favourable with disputes resolved; staged for merging. and removed State: Confirmed Candiate with CIP number (new PR) or update under review. labels Nov 25, 2025
@fallen-icarus
Copy link
Contributor Author

@rphair @Ryun1 @Crypto2099 @perturbing In order to get this CIP's development fast-tracked, the ledger team (cc @lehins) is asking to break this CIP into two phases:

  • Phase 1:
    • ADA only deposits
    • Partial withdrawals
    • Account balance intervals for ADA
  • Phase 2:
    • Multi-asset deposits
    • Whitelisting certificates
    • Account balance intervals for multi-assets

Phase 1 is small enough to possibly be delivered for the Dijkstra era while Phase 2 would be too much work to finish in time. The reason to prioritize Phase 1 is that it will make DeFi cheaper - aggregators and wallets currently charge a minimum of 1 ADA due to the minUTxO requirement. Phase 1 entirely removes the minUTxO restriction for ADA-based fees.

AFAIK no CIP has ever been phased like this. What is the process for phasing? Should this CIP be broken into two separate CIPs? Or should the phases just be add to the Path to Active section of this CIP?

@rphair
Copy link
Collaborator

rphair commented Dec 4, 2025

@fallen-icarus this sounds like a solid approach (effectively taken by all the CIP-0013 and CIP-0068 evolutions) although FYI I'm on an indefinite leave of absence from CIP editing beginning this week (cc @lehins).

@lehins
Copy link
Contributor

lehins commented Dec 4, 2025

I'm on an indefinite leave of absence from CIP editing beginning this week (cc @lehins).

I've heard about it! I really hope this situation will get resolved ASAP!!! Your work on CIPs is of enormous value for the Cardano ecosystem!

@rphair
Copy link
Collaborator

rphair commented Dec 6, 2025

p.s. @lehins (cc @fallen-icarus) someone at the CF convinced me today to return to service for the time being & so I'll be continuing on this review thread & all other CIP repository / community activities as usual going forward. 😎

@rphair
Copy link
Collaborator

rphair commented Dec 6, 2025

@fallen-icarus #1061 (comment): What is the process for phasing? Should this CIP be broken into two separate CIPs? Or should the phases just be add to the Path to Active section of this CIP?

I think breaking this up into two separate CIPs would cause confusion both in the Implementation Plan as well as node Ledger teams' attempts to follow through that phased implementation properly. I'll take this off Last Check for now & let's see if you can break down the 2 sections of Path to Active by phase. Then the editors can (re-)review it and confirm with @lehins that it's something the Ledger implementors can follow: and, if so, tag it for final review after that. (cc @perturbing @Ryun1)

@rphair rphair added State: Confirmed Candiate with CIP number (new PR) or update under review. and removed State: Last Check Review favourable with disputes resolved; staged for merging. labels Dec 6, 2025
```

Crucially, since the `AccountValue` will take up space in memory, it must be accompanied with an
extra protocol deposit that is proportional to the size of the `AccountValue`. This extra protocol
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does proportional look like?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The calculation is similar to the minUTxOValue/utxoCostPerByte param. When you whitelist assets, you create a Value with the quantities initialized to 0. How much space does this Value take up? There would be a whitelistCostPerByte param.

@fallen-icarus
Copy link
Contributor Author

fallen-icarus commented Dec 12, 2025

Updates:

  • Added deposit amounts to whitelist certificates to match the other Conway certificates.
  • Added comment about minUTxOValue being renamed to utxoCostPerByte.
  • Added comment about the need for a new whitelistCostPerByte parameter.
  • Updated account balance intervals cddl to make it possible to specify either the lower bound or the upper bound, or both.
  • Added comment about using nested transactions to safely allow these new features in transactions with plutus v1-v3 contracts.
  • Split the Path to Active into two delivery phases: ADA-only support first and then multi-asset support later.
  • Minor formatting fixes.

@fallen-icarus
Copy link
Contributor Author

@lehins This is ready for your review again. See the comment just above for changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Category: Ledger Proposals belonging to the 'Ledger' category. State: Confirmed Candiate with CIP number (new PR) or update under review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.