The claimable balances problem, and what to do about it

964 views
Skip to first unread message

Justin

unread,
Sep 21, 2022, 3:06:49 PM9/21/22
to Stellar Developers

TL;DR: Claimable Balances are generating a ton of spam, and the number of unclaimed Claimable Balances is increasing.  That's bad for network health and decentralization.  What should we do about it?

What are Claimable Balances?
Claimable Balances are a type of ledger entry that make it possible to create a balance in a given asset, and to designate an account as the claimant independent of whether that account has a trustline for the asset, or even exists on the ledger.  

Theoretically, they reduce friction when an anchor onboards a new user since they allow the anchor to create an on-network balance for off-chain deposits without worrying about lumen reserve requirements or account and trustline creation.  Used as intended, they could allow new users to deposit funds onto the network via an anchor without first interacting with an exchange to purchase lumens.  Claimable Balances were first described in CAP-23, and went live when the public network upgraded to Protocol 15 on November 23, 2020

Why are Claimable Balances a problem?
When Claimable Balances aren't claimed, they persist on the ledger forever, bloating state size, increasing resource requirements for validators and Horizon operators, and making network participation more difficult and more expensive.  

Over the past few months, the number has increased dramatically, and the rate of increase continues to accelerate.  Two snapshots for comparison:

  • Aug 1, 2022: 

    • 157,084,978 created

    • 152,908,626 closed

    • 4,176,352 open

    • ~2.7% open

  • Sep 20, 2022:

    • 184,653,177 created

    • 169,850,749 closed

    • 14,802,749 open

    • ~8% open

There are, in other words, 10 million more unclaimed Claimable Balances on the ledger than there were 7 weeks ago, and without action, it's likely that the number will continue to grow unbounded. 

Moreover, Claimable Balances are not currently used by anchors to onboard new users.  By and large, they are created by issuers to airdrop tokens to a wide swath of accounts, and generally, the owners of those accounts do their best to ignore them.  In the first half of 2022, for instance, only 25% of Claimable Balances were claimed by a destination account other than the sponsor.  Sending unwanted tokens to random users at scale…that's called spamming.  

From a user perspective, spam is annoying, but it's not an intractable problem.  We all rely on spam filters for email, and wallets can (and do) provide the same service to hide unwanted Claimable Balances.  Out of sight, out of mind.   However, there's no spam-filter equivalent for transaction submission.  When spammers create unwanted Claimable balances and don't reclaim them, they remain on the ledger for eternity. When spammers do reclaim unwanted Claimable Balances, they tend to recycle the reserve to create a whole new batch, which means there's a constant, pointless, heavy load on the network. 

If the amount of on-chain spam continues to grow, it will be harder for existing validators and Horizon operators to keep up, harder for new validators and Horizon operators to join the network, and harder to increase the decentralization and resilience of the network.    

What should we do about the Claimable Balance problem?
The simplest way to mitigate the problem: deprecate the Create Claimable Balance operation.  Existing Claimable Balances would persist, and users would still have the opportunity to claim them, but no one would be able to create new Claimable Balances.  This approach would immediately stop the bleeding.

However, after some informal check-ins with people in the ecosystem, I realize there are several objections to that approach.  First, many builders have already incorporated Claimable Balances into their products and services, and it would take a fair amount of time and effort to update code and amend interfaces to undo the work they've already done.  Not only that, but app developers are loath to un-introduce features to their users, which I get.  

Second, several people I talked to believe that anchors will eventually understand Claimable Balances can be used to onboard users with less friction, and so it's premature to roll back the feature.  Instead, they suggest working to increase meaningful adoption. 

Third, some issuers are doing unexpected and interesting things with Claimable Balances, such as using them for governance.  Users can create a Claimable Balance that only they can claim, which allows them to cast and rescind on-chain votes. 

In all these cases, the people I talked to (and I hope they will jump in on this thread) understood the bloat and load problems Claimable Balances create.  However, they all suggested looking for alternatives to deprecation.

So here's a suggestion: what if we significantly increase the reserves required to create  a Claimable Balance?  Rather than requiring 1 base reserve (currently 0.5 XLM), require 100 base reserves (50 XLM) to create a Claimable Balance.  At the very least, doing that would increase the incentive for Claimable Balance creators to list themselves as claimants, and to clean up unwanted balances rather than leaving them on the ledger forever.  The extra up-front cost may also deter large-scale creation of Claimable Balances. Thoughts?


Igor Natanzon

unread,
Sep 21, 2022, 4:46:25 PM9/21/22
to Justin, Stellar Developers
We use claimable balances in our organization, so their loss will significantly impact our ability to operate.

But, spam is a real problem with them, so perhaps another approach should be taken:


1. Add another authorization flag on an account, something like 'allow_claimable'. Have it off by default  if anyone needs to handle or process claimable balances they can activate it, at least temporarily.
2. An account that doesn not have the flag enabled cannot be set up as a claimant.

Additionally, perhaps there are some other options, such as ability for a claimant to reject CB, removing themselves from the list of claimants, and maybe even require a expiration time to be set, up to max value set by validators . Any unclaimed balances woild to back to the sender once expiration is set.

I personally don't like those other approaches but the approach of setting up an account flag should work nicely to eliminate spam. 


--
You received this message because you are subscribed to the Google Groups "Stellar Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stellar-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/stellar-dev/2057188d-78b8-454c-8a50-f4ef1a0cb381n%40googlegroups.com.

Enrique Rubio

unread,
Sep 21, 2022, 6:06:18 PM9/21/22
to Igor Natanzon, Justin, Stellar Developers
I love the idea to control the claimbalances. They are very annoying and load the network. 
It would be nice to allow to user to reject the claimbalance

Another idea can be to alow to the user to burn the claimbalance (this can be done with a new operation joining accept the claimbalance and send to the issuer accoun), This option would make scammers think twice about sending the transaction. 

Also the idea to increase the price of the claimbalance transtion could be good.


Jack Wilkinson

unread,
Sep 22, 2022, 12:17:13 PM9/22/22
to Enrique Rubio, Igor Natanzon, Justin, Stellar Developers
This is a tough one.  While spam is a major issue, the ability to send claimable balances is pretty integral to many projects.  What if there was an open source code provided to all wallets to do what Lobstr does (swap to AQUA or a token of choice)?  This combined with a bit of education might help deter spammers and help clean the ledger.  I would be curious to see how claimable balances on Lobstr stack up compared with the rest of the wallet developers.  I am not a dev so forgive my lack of knowledge on if this is feasible or practical.  Good luck with this dilemma.
Jack
Sent from my iPhone

On Sep 21, 2022, at 6:06 PM, Enrique Rubio <enr...@brave-corporation.com> wrote:



fraggedreality (Paul)

unread,
Sep 22, 2022, 12:17:26 PM9/22/22
to Stellar Developers
I can imagine to add a reject functionality to claimable balances. Together with this sponsors/senders of a claimable balance would need to deposit a drastically high amount compared to the reserves. If a claimable balances is accpeted / claimed, they get it back. If the claimable balances is rejected the deposit should go into the fee pool. It should not go to the claimant who rejected it in order to prevent misuse of the reject functionality.

Enrique Arrieta

unread,
Sep 22, 2022, 12:17:41 PM9/22/22
to Stellar Developers
Hi there,

I believe claimable balances have good use cases but the spam is way bigger than the good intentions. Being able to reject the CB or burn it is not a solution that is going to work (wallets currently allow both cased) because the amount of unwanted CB we will get is way higher to the amount of times we are going to do something.

The trustlines are the perfect way to avoid spam (one of the things I like about Stellar even doe it makes friction sometimes) and I feel that's the solution with CB, the problem will be that if we require the trustline we basically defeat the point of the CB so... The solution should be in the middle: Why not allowing users to just set their accounts to not accept claimable balances. This will solve it for those who don't want to receive it and at the same time it will allow existing businesses to continue using them (and people interacting with it).

I'm pretty sure most users don't use claimable balances, allowing them to just set their accounts to not receive them will reduce the spam problem a lot because spammers will see is not worth it anymore as most of the people will probably just decide to avoid getting spam if they are not actually using them (which will reduce the exposition of their spam assets IE not worth it).

With this solution the true question is: what should be the default? Not accepting CB or accepting CB? I think not accepting is the better option, the amount of use cases where that's needed is lower than the amount of spam than can benefit for having it allowed by default 

Regards

Leigh McCulloch

unread,
Sep 22, 2022, 12:52:16 PM9/22/22
to Stellar Developers
I think we should give users the ability to discard/burn claimable balances where they get to keep the XLM sponsored reserve.

Claimable balances sometimes present themselves as notifications in applications. They're something to take action on. Discarding seems like a natural action to offer. Giving the reserve back to the sponsor feels inappropriate in this case because the user discarding will have to pay a network fee to discard. Giving the user the reserve feels like a good solution to that.

If this has no impact on spammers we can also tweak the reserve required for claimable balances, and at least users get to keep that increased reserve.

I think it would be a small lift to add a BurnClaimableBalanceOp operation that is usable in all the cases and under the same conditions that ClaimClaimableBalanceOp is usable. Instead of moving the balance into the user, it would simply burn it, and credit the user the reserve.

What do you think?

Tomer Weller

unread,
Sep 22, 2022, 1:04:34 PM9/22/22
to Leigh McCulloch, Stellar Developers
I agree that burning claimable balances and allowing users to get the base reserve should, in theory, ensure that claimable balances are worth more than the base reserve. 

However, there's a strong dependency on adoption, which depends on wallets exposing this functionality and encouraging users to use it. Any wallet developers in the audience care to comment? 

fraggedreality (Paul)

unread,
Sep 22, 2022, 1:43:44 PM9/22/22
to Stellar Developers
There is: https://github.com/hanseartic/stellar-claim/blob/2708bf6/src/Pages/ClaimBalances.tsx#L96.
It currently only converts to XLM - no option to choose from. But I will change this in the future.

Still the issue remains as longs as this is a manual task. Therefore I am thinking of a turret-powered automation (don't know if soroban would be feasible). But there are a few edge-cases to consider.

fraggedreality (Paul)

unread,
Sep 22, 2022, 1:48:35 PM9/22/22
to Stellar Developers
I am not too sure if giving the reserve to the claimant (in this case rejectant) would be fair in all cases. So why not just move it in the fee pool and make the transaction fee-less for the claimant. That way the fee-pool would probably receive a lot more funds and could maybe at a later stage also be used pay or support individuals who want to run a node - another topic that is discussed every now and then.

Also I want to repeat my suggestion to have a split reserve for the sender. The current base-reserve we have right now. The sender will get that back in any case. On top a deposit that is only given back to the sender in case of a successful claim. In case of rejection the deposit would go into the fee pool.

Also the deposit could depend on the time bounds. The longer the CB is valid the higher the deposit needs to be.
And one last thing: currently CBs that are not claimable anymore stay on the ledger forever. Maybe they could be garbage collected after expiration (no claim-predicate allows to claim anymore or all claimants where claim-predicates would allow to claim are locked).

Whatever way is decided I would immediately implement it. Though my userbase is really small compared to others.

Enrique Arrieta

unread,
Sep 22, 2022, 3:30:22 PM9/22/22
to Stellar Developers
Hi @tomer xBull Wallet creator here, regarding the question I feel it won't work for the next reasons:

- Amount is not enough: my wallet and Lobstr have the option to auto convert the spam into XLM or AQUA, the tool created by @fraggedreality is probably the most completed one for the job but I know there are people (myself included) which don't want to use them because the amount we can get is less valuable than the time we will need to spend in accounting for taxes reasons so unless there is the perfect tool for reporting these users will continue avoiding these types of tools.

- It can hurt legitimate projects: If I'm interacting with a project which relies on claimable balances I could make it so the project creates a lot of claimable balances for me with a low value and I will on purpose reject them so I get the base reserve and in consequence I will hurt the project while making a profit. This will be only fixed if the projects force me to be the sponsor always but that will depend on the project and how they work.

- Profits from spam are greater than what they can loose: Sadly many spam assets do this so people sell them later using one of the available tools while they are the ones buying the same spam token, doing this they artificially increase the price of the token so they can later make people believe is a desired token and it's easier to pitch it to others. One recent example is how scammer have tricked people to give them the private keys in order to "unlock" those claimable balances that have a high price. In some way those tools that help users to sell spam tokens actually help spammer to fake volume and price of their assets... This will only be solved if the assets is burned and not exchanged to another one

I truly believe the solution is at the creation of the claimable balance process and not what we can do after is created.

Regards.

Eric Saunders

unread,
Sep 23, 2022, 8:08:54 PM9/23/22
to Enrique Arrieta, Stellar Developers
The fundamental issue is that I can get a benefit (free advertising spam + profit by some fraction of the spam) for no cost, just a temporary, zero interest loan (because all fees can be recouped).

So increasing fees just means I need a bigger chunk of cash to put up as collateral.

I think a real solution has to make it cost something to create a claimable balance. Something unrecoverable. The burning to give to users feels nice, but the tax issues are real I think.

Can we change the model so that fees for claimable balances can never be recouped, and are simply lost? Ideally we would add a time dimension, so that a claimable balance must be constantly paid for until it is claimed, like putting coins in a parking meter. This then matches the fee model to the cost to the network of "renting" this space on the blockchain.

From this follows a more general argument to do this for all persisted blockchain state, but we don't have to go there yet. ;)

Eric

John Wooten

unread,
Sep 24, 2022, 5:16:10 AM9/24/22
to Stellar Developers
Thought about this as a potential solution, too.

But, off the cuff, it seems like you'd use significantly much more resources enforcing state-based fees, which negates the whole purpose of "parking meters."

Plus, something like this seems to go against the principles of Stellar.

Consider someone in sub-Sarahan Africa that gifts their young grandson ≡$100 via M-Pesa, but they only want them to receive it after their 21st birthday.

Enforcing recurring fees on this could push users to off-chain solutions, which seems like an undesirable outcome.

The spam problem is big, and I don't particularly see a "reputation-based" criteria akin to email hard bounces working with Stellar's decentralized character.

I think the solution should have something to do with the assets being used in the claimable balance.

Just struggling to think of a sybil-resistant asset property you could use to qualify a create_claimable_balance_op that stays equitable.

I know it might not perfectly fix the user annoyance side of it, but I do think the proposed reject_claimable_balance_op burning token/sending the reserve to fee_pool is a good idea.

Eugene

unread,
Sep 29, 2022, 12:56:55 AM9/29/22
to Stellar Developers
The main advantage of CBs for me is that I don't have to worry about the claimant's wallet state (established trustline or even if the wallet is created or not). So adding the "allow_claimable" flag defeats the purpose of CBs for me and I'm sure for other devs too.

In my opinion, the spam is a UI issue. Just don't show users all CBs. Make them whitelist sponsors if they want to see CBs. For example, if I want to receive notifications about CBs from project A, I whitelist their sponsor address, and I'm good. Not to mention that project A probably has a UI to claim the CBs from their website. Wallet providers can easily query Horizon by a sponsor, so it's not a big deal. Maybe a SEP should be created with guidelines for the wallet providers.

As for the blockchain bloat: I'm sure it'll stop as soon as the wallet provides stop showing all CBs. But I still think the blockchain shouldn't allow the creation of "unclaimable" CBs. At least one of the claimants should be able to claim the CB at any given time. Otherwise, we have a situation where no one can claim the CB, and it's stuck forever on the chain.

Peter reteP

unread,
Sep 29, 2022, 11:14:11 AM9/29/22
to John Wooten, Stellar Developers
the problem arises due to the limitation of the number of trust lines .. you have to remove this limit and quickly because it blocks the development of the tool ... you cannot block the tool in this way also the minimum cost must be scalable to the price so as not to limit the possibility of joining entities and services to the tool..

Igor Natanzon

unread,
Sep 29, 2022, 2:30:55 PM9/29/22
to Stellar Developers
The thing is though is that use of claimable balances goes beyond initial design goal, as uses do evolve.

In our implementation, we use CBs to delay completion of a payment until certain time. So for us, we pre-establish trust lines anyway, but use CB for payment delay. 

Maybe the right approach is flexibility. If an account does not want them, they can turn them off, OR restrict them to trust line assets only (I understand that's contrary to original goal). Just like an account already has to take control of allowing an asset to be sent to it (via trust line), they should continue to have control with CBs. At least they can turn them on and off as needed. I believe accounts should always be in control over what happens to them. So for all of our use cases, having a CB flag that has 3 states: disallow all, allow all, allow trusted, will cover various use cases. Many account types, such as those used by crypto exchanges, may want to have nothing to do with CBs and could turn them off. And if a particular vendor has a specific relationship with a client that requires open CBs, they could require that. 

The issue with UI and filtering of assets is now every single app and vendor will have to keep track of an ever growing list of spam accounts (that are very easy to create) and I can't see that as a truly practical solution. 

I am not opposed to increasing reservation cost as well (maybe with additional entry per predicate),  but increasing actual transaction fee may negatively impact adoption. 

Eugene

unread,
Sep 30, 2022, 4:10:29 AM9/30/22
to Stellar Developers
I'm against any flags. It not only breaks the logic of CBs, it's just weird, considering CB does not affect the claimant's account (unless the claimant decides to interact with it).

I'm also against raising the reserve amount as it won't prevent spam, it only will hurt legitimate projects. Any reserve will be justifiable if the end user sees a "pending" payment in their wallet app.
 
Let's take BNB Smart Chain and Trust wallet, for example. If Trust wallet had sent me notifications every time I received some random token, I would have drowned in notifications. I must manually add a token's smart contract if I want to receive notifications. Similar should be done with CBs. Let's say I want to receive notifications about AQUA airdrop, I whitelist sponsor GDFCYDQOVJ2OEWPLEGIRQVAM3VTOQ6JDNLJTDZP5S5OGTEHM5CIWMYBH in my wallet, and that's it, I'll receive only notifications about CBs from this sponsor. 
And considering that Horizon allows filtering CBs by the sponsor, there is no need to loop through every single CBs. 

John Wooten

unread,
Oct 20, 2022, 5:26:48 PM10/20/22
to Stellar Developers
Also against flags.

From limited observation, it seems a lot of these distributions come from a few accounts that spam many tokens.  

These issuers often get flagged on Stellar Expert as spam, which leads perhaps directly to the issue of ignoring CBs and bloating memory requirements for validators, which is bad.

I think the fix here should punish bad actors, not increase costs for everyone or remove a feature in response to a few abusers.

We can disincentivize spam airdrops at the distributor level by enabling tangible punishments to spammers like deny_claimable_balance -> fee_pool burn.

In particular, newfound "airdrop providers" advertise that they'll distribute your tokens for about 0.1 XLM/sent account. (source available)

Assume semi-honest users that only deny obvious spam.

If only 20% of users deny a CB, these distributors will lose 0.5 XLM base reserve * 20% burn rate = 0.1 XLM/account on average, equivalent to all their fees.

Sure, these services can increase costs, and maybe this isn't the perfect final solution.

But this seems like a pretty simple first step to gradually fix the problem.

If the community continually denies enough spam, a simple addition like this could fix the problem indefinitely. 


I am very biased. We think CBs are a great tool for vesting restricted stock.

In particular, public American CFOs are routinely bound between their transfer agent and their corporate counsel requesting routine releases for 12-mo vested restricted shares.

It's a huge waste of time for a process that can easily be automated and policed in real time using CBs.

We prefer CBs to pre-signed txns because they provide much more transparency and clarity for employee stockholders.

Employees know exactly what to expect from their employer, and external investors can easily audit an employee benefit plan's future claimable balances to forecast increasing share supply.


CBs do good things, and we'd hate to see them go because of misuse. 

Let's find a way to fix this for everyone.


- John Wooten

fraggedreality (Paul)

unread,
Oct 24, 2022, 2:40:29 PM10/24/22
to Stellar Developers
I articulated my opinion earlier: keep legit use-cases cheap and simple while making misuse expensive. The latter being: increase the base-reserve per claimant, allow claimants to chose between *claim* and *deny* a CB, on denial pay the reserve into fee pool instead of returning to the sponsor.

On top I wanted to ask if soroban might be able to interact with CBs. If so we could have users allow a clean-up contract that would automatically deny CBs.
Best,
Paul

John Wooten

unread,
Oct 24, 2022, 2:40:59 PM10/24/22
to Stellar Developers
Upon further investigation using this src:

There are currently 1,784,549 open AQUA claimable balances, an application I think most people would say is beneficial to the network.

Storing all the CB data for these records in plaintext takes 2.56GB (2,559,784 KB with newline separators).

Extrapolating to the cited 14,802,749 open trustlines gives us a 21.23 GB storage requirement, assuming no deny_CB_op (which any claimant should be able to effect).

Since we're talking about disk storage, this shouldn't be overly burdensome for small validators, even when scaled by 100X -> ~2 TB.

Moreover, a final thought. There are tons of CBs that simply can't be claimed by their claimant per permanently-locked conditions. The deny_CB_op would fix these, too.

Potential backwards incompatibilities: consider A creates a CB with B and C as claimants with conditions C(not(abs_before(...)), B(not(unconditional)). Malicious B could deny the CB, which could be unintended.

(src data available)

John Wooten

unread,
Oct 31, 2022, 10:12:04 AM10/31/22
to Stellar Developers
This is a great idea, Paul. Nice work.

Also wanted to address another point made by Justing:
> Claimable Balances are not currently used by anchors to onboard new users

Perhaps a reason: 
There are not particularly many anchors yet with many diverse asset offerings.

Off the cuff, the largest (credible) anchors only issue a few assets they specialize in (stablecoins, yield tokens, depository crypto).

These projects generally fall in the "add-your-own-trustline" category (think Centre) or "done-for-you/Web2" (think ClickPesa).

There aren't yet many middle-ground non-custodial wallets (think Beans) at scale.

Consider an application where the issue has a large number of assets.

Say a user can hold a portfolio of these assets via a non-custodial wallet. 

Let the issuer need to distribute initial asset holdings to the wallet based on a prior anchor asset.
In our example, this would be shares held in a legacy brokerage account.

Under the "send-only" world without CBs, the user would need trustlines for all the assets issued if they wanted to receive assets:
  • where nobody knows which assets a user could get without (bad) central coordination
  • where users could receive assets at any time (adding a trustline in real time would require central coordination)

For this to work in the traditional non-custodial method, the user has to:
  • receive a centralized prompt to add a trustline (they likely have no clue what that is)

Bad solution:
User adds an entire portfolio of assets to their wallet rather than a just few (huge base reserve; account bloat).

Bad solution :
A centralized middleman signer key adds the trustline when distributing the initial (or P2P gift) asset.
The signer always controls at least medium threshold for the user, which introduces new custody risk.
Central authority for day-to-day txns bad.

Good (existing) solution:
Send user a CB that they can claim next time they open their wallet.
(Future: user default is to deny CBs not from trusted anchor, which is fine because it's not like you're burning the rejected tokens.)

In conclusion, 
  • Non-custodial users need CBs
  • CBs keep wallets decentralized
  • We support adding a reject_claimable_balance_op 
(personally think "reject" complements "claim" slightly better)

John Wooten

unread,
Aug 15, 2023, 10:00:38 AM8/15/23
to Stellar Developers
Haven't seen much on this topic in a while. Wanted to bring it back because this is still a pertinent network challenge.

Another use case for the reject_claimable_balance_op could be in a collateralized loan.

Say you post 10 yBTC for a 60% collateralized loan repayable in one lump sum next January.

You could create a CB to the creditor for the yBTC claimable after February in case you default. 
(for simplicity assume the specifics are governed by an offline contract)

If you repay the loan, the creditor can reject the CB. Per our proposed rejection scheme:
- a nominal reserve fee is burnt -> fee pool
and
- you get your 10 yBTC back.

This prevents the creditor from having to claim the yBTC and then send it back to you, assuming you repay the loan.
That means easier accounting on their end since they don't have to reconcile the asset income or return payment.
(+less network bloat and ambiguity since you don't have to add yourself as a claimant after February)

- John
Reply all
Reply to author
Forward
0 new messages