Help us find a better way to shield ETH/ERC-20 assets

Hey problem solvers, here’s a tricky one.

To improve the shielding user-experience, we’re researching whether it’s possible to deploy fixed deposit addresses, unique to each user payment address - without compromising privacy. This could mean no more shielding time-outs, no more duplicate-use headaches, etc.

As you can imagine, there are many things to consider and some issues to circumvent, so we’d love to have your input on the best way to do this.

Here’s some context.

The current flow (rotating shielding addresses):

  • There are currently multiple temporary rotating addresses used for every new batch of shielding requests.

  • There’s an amount of ETH reserved for gas fees in each wallet, which proceeds to call requests to the Incognito smart contract. We rotate these temp wallets among user requests to make sure gas fees are sufficient. There are 2 actions executed at this time –

  1. Approve: to verify whether the token is ERC-20 or something else.

  2. Deposit: to send users’ tokens from the temporary address to the Incognito smart contract, and keep it safe there.

This works well from a privacy standpoint, but suffers when it comes to real-life ease of use. Some users get nervous when addresses expire, and sometimes delays do happen - either due to gas fee volatility, issues with depositing from crypto exchanges, and so on. That’s why we started exploring ideas on how to implement fixed shielding addresses unique to each user (per payment address).

Possible new flow (fixed shielding addresses):

  • A new temporary shielding address will be generated for each payment address, fixed only for that payment address, and will never change.

  • ETH gas fee will only be provided to that temp address once our system verifies and confirms the receipt of users’ tokens. It might be a good deal higher than the current gas fee paid, as we would need to make sure that the request to our smart contract is processed successfully.

  • Instead of expiring after 2 hours, this new fixed temp address will expire in 24 hours. Once expired, users just need to retry it on their own, and will be able to do so easily in the app.

  • If a user makes a new shielding request, that same fixed address will be given, as it now belongs to that payment address.

Disadvantages of this idea:

  • Time to complete the transaction will be 5-10 mins slower than it is now, as our system needs to continually ensure a sufficient amount of ETH is provided to cover gas fees, in order for this to work well. If gas fee requirements suddenly increase due to congestion on Ethereum, transactions could be pending for a while.

  • This implementation has privacy drawbacks, and could impact decentralization. Since shielding transactions require funds transfer from external public chains, if a temp address is fixed to a certain payment address, someone else could theoretically figure out whose address it is, and could possibly track how much that user deposits to Incognito.

This is obviously not ideal, and we are unwilling to compromise user privacy, so…

What do you think?

Help us explore how to improve user experience without costing their privacy. Our team is actively researching in this area to find a solution that fulfills both usability and privacy requirements, but there’s probably something we haven’t thought of – so please do share your ideas!


Unfortunately right now I do not have a better solution. But what I can say is that I really do not like the new approach. Because people already now getting nervous because shiedling might take a while so it should never take longer than it does right now. Also according the privacy effect we should only do changes which increase the privacy instead of decreasing it.


Agreed @sato, thank you for your input. That’s why we’ve opened this question up to the community - let’s put our heads together and see if we can find a solution that is both user friendly and secure.


What about having a compromise between the old and new flow? For example:

  • Generate a new “fixed” address with 24h validity and manual retry, but add the possibility to generate a new one. When user chooses to generate a new one the old one will be put in the pool of available addresses (rotating) that can be requested from another user and an available address (different to the previous) will be associated to the user. This pool should have a sufficient number of address (depending on the demand) and new addresses should be generated and put in the pool if necessary.
  • An enhancement could also be to give the possibility to have multiple (eg. 3) shielding addresses per user, so maybe one user can keep a seat for better privacy shielding, changing the address every time with expiration every day, and another seat used for example for a truly fixed address.
  • Another interesting thing could be to add a selectable expiration time (limited choices or N of hours), maybe also with the possibility of an infinity expiration. This last case could be used for example to receive donations in an anonymous way (tipping address with shielding feature). Not really secure from a privacy PoV but in this case it’s the only way.
  • Maybe there could be an option to “reserve” the same address after the expiration (otherwise it will be released to the addresses pool), that is what you are calling “retry it…”. In this way you can determine if you need to use the Flow 1 or the Flow 2 for the ETH fees management. I think this strategy can apply also to the other bllockchains when shielding (eg. BTC addresses…)

What do you think?


Bad idea, Incognito is about privacy and the shielding issue should not impact the privacy aspect. If users don’t like the shielding process, I think somebody here will build another wallet for prv coins sometime which these users can use, but in the original app everything should be focused on privacy and we shouldn’t make exceptions. Once you understand it, the shielding process is easy. Could be a bigger button though, but this is just a UI aspect.


I like this idea :bulb:

1 Like

I also like this idea, great approach.

1 Like

I kind of feel this will result in a lot of trouble, but maybe I am not understanding it properly.

Let’s say I want to deposit from three sources and really like my privacy, I would generate one address, send it to whomever needs to pay me. Then move on to generate a new one for the next person who needs to pay me and so on.

Won’t my addresses (and funds) be lost going from one to the other if on generating a new address the former one gets returned to the pool and possibly assigned to someone else?


I will try to explain better. I think that there must be privacy, but also that an user should be able to select his own tradeoff between privacy and usability, obviously remaining inside some limits. Supporting high privacy as default, with with the option to choose.

Proposed flow:

  • The user can generate up to (for example) 3 “temporary” addresses that can expire or not and that can be “reserved” or not
  • A generated address is taken from the “addresses pool” (rotating) and the user can change the default expiration time/conditions and reserve option
  • During the expiration time the user can receive money for shielding. If the expiration condition is set to “single transaction”, the address will expire just after first shielding. Otherwise it will expire at the end of the expiration time (selectable)
  • If the address is marked as “reserved”, it will be kept also after expiration, but a manual retry is needed, defining the new expiration time, with the possibility to change the reservation setting and expire condition.
  • If the user need a tipping address with enabled auto shielding feature, he can create a “temporary” address with infinite expiration, no expiration condition and enable reservation. (Just a possibility…)
  • An address can be always manually expired or removed (un-reserved)
  • When an address expires and is NOT reserved (or when manually removed from the app) it returns to the “addresses pool”, and it’s available for another user. If the number of available (rotating) addresses in the pool is not sufficient (high demand) new addresses can be added
  • Depending on the address chosen parameters, the correct FEE management system can be determined (team proposed flows considerations). So maybe the user can see a message indicating if there could be higher delays for the shielding procedure and/or privacy issues (lower privacy) before confirming. I think only with reservation enabled the ETH for paying fees will be added using the second method.
  • This way there is high privacy as default, but the user can tune it and there could be also new features (like the auto-shielding tipping/donation address)

Maybe this is written better than my previous comment


Since privacy is the object of the project, I really don’t want to sacrifice any of that just for convenience.

Put alarm bells on the screen, with the deposit address when people revisit, and when the copy button is pressed, if needed.


The problem I have is that ANY address reuse lowers security. In theory, a new address should be generated for each and every. The problem with this is that gas costs would eventually become prohibitively expensive to send a bit of ETH for every shield.

I like the idea above on rotating addresses, but they should only be limited to one deposit per use. The app could generate several addresses before hand to give to multiple parties.

Extending the deposit window may be the best option. From 1hr to 4hr.


There are currently multiple temporary rotating addresses used for every new batch of shielding requests.
The “addresses pool” will be a thing like this. If you don’t want to reuse addresses, simply create new ones…

However, in your example, if you generated three addresses, received the money and then expired, if it was not reserved and returned to the pool you don’t have that address anymore. It’s like the current situation. If you start a shielding procedure and receive the money (2h expiration) and tomorrow you give the same address to another friend, you can not receive the funds. So it’s your fault because you used an expired address.

In my proposal, if you want to keep your address, you reserve it.

It’s like DHCP and IP addresses with reservation… This could used as example, more or less. Suppose to have a server that can accept connections, you obtain an IP and it could expire in, for example 4h. But you can set the reservation time. Maybe you can reserve it forever. But this is only an example, and doesn’t cover the full mechanics of my proposed flow. Maybe it could be difficult to implement or something, I don’t know… But it’s flexible ad I would use it in many ways.

1 Like

Thanks for explaining it in a different way.

I still believe we should focus on privacy. People can use other wallets when privacy is not important.

The long term idea is to have people use the wallet for all their transactions, not just moving coins in and out. The majority of the transactions will be on chain from one Incognito account to another.

Promote that.


It sounds like to me that the process we have now works but the fees present an issue.

Would it be hard to do one of the following?

  • Do like all other wallets do and charge the gas fees to the users. Provide 3 different speed tiers and charge 3 different amounts.

  • Offer a way for users to avoid paying high fees by clicking a “pool my transaction” button where their transaction will wait to be processed until enough ETH transactions are pending processing. This could be an advanced button or feature and explaining that while fees are very low with this feature the transfer of funds is very slow and provide a time frame (example 2 - 6 hours).

Using this process would keep us coherent with what every other wallet does and still hold us to our privacy first focus.

If we switched to these methods it would allow us to generate a new address for each transaction therefore eliminating the need to worry about transactions timing out.


Hey @Jared I do like the idea

Maybe by providing both of these methods you get the best of both worlds, users who dont mind paying a high fee for high speed and users who are in no hurry and would like to batch/pool their transaction.

1 Like

I don’t think so… Incognito it’s a way to add privacy to public blockchains (in terms of privacy). The real goal is to enable the privacy layer to all the non-private operations. Like for example paying with crypto on ethereum chain.
Incognito internal transactions will be used by incognito users, and many businesses can not operate directly with privacy assets due to regulations for example. This is done with shielding and unshielding. This is the big innovation and the difference between Incognito and other privacy coins/solutions.

Your are acting in a binary way: use incognito with super high privacy but not user friendly or use another wallet with zero privacy. My approach would be to enable best privacy as possible as default option (at the bridge, when you are inside incognito you are always with the maximum privacy), but let the user to tune it like a grayscale.
In my opinion, the best thing that can be done is to be flexible (between certain limits) and EDUCATE PEOPLE about privacy without limiting certain possibilities. Educated people will be self-conscious about the drawbacks of their choices.

I think the major issue currently is the fact that some people need more time for the shielding procedure. For example if I generate an address and ask money to a friend (outside incognito), maybe he doesn’t send the money immediately. Maybe it’s a payment he will send in the coming days… So the address in this case must wait the transfer before expiring. Maybe in this case forcing the friend to convert to incognito is not an option. Maybe he is not a friend, maybe is an exchange and there are delays, technical issues…
The other issue is that some people wants to use the account multiple times but not to much times (maybe 2-3) and then change the address.
You can increase the privacy generating new addresses instead reusing the addresses from the pool. But in this case you don’t optimize the ETH transfers used for the fees probably.
However, also if someone uses a different address each time, but sends the funds from the same personal address, or the same exchange address, you can use a blockchain analysis tool to check all the outgoing TX from a particular address and then check, for every destination address, if there is a TX to the incognito smart contract. You can determine how much you sent to the incognito network, but obviously you know nothing abut the real recipient of the coins (maybe your incognito account, maybe your friend, maybe your friend passing before from your account…). With an addresses pool it’s the same, you reuse the addresses but you don’t know who is using the address and when, and of course you can not determine the recipient. You can only say that some money entered the incognito network and the source was the same. Exchanges, if they want, will always be able to determine if money is entering in incognito network monitoring the paths.
Only if you have an address reserved forever and you always send to that address you have less privacy, especially if you use the same address also with other people that know you. This can tell that you received money on incognito network but nothing more…
Let’s think about the case of 100 people sending money to you. The best thing would be all of them sending the money using incognito chain. But if this is not possible you have 3 options: 1) they send to and ETH address (manually crated by you) and then you shield the whole amount. 2) you generate 100 single shield requests each with a different single use address 3) You create a single temporary address used only for this purpose for a limited time. The option 3 is more or less similar with option 1, but it’s faster and better in my opinion because everything is automated and then another user will use the address so the system is like a mixer. Option 2 is not user friendly, it takes a lot of time. Best privacy for sure but not a good option for a real use case. So, if doing everything inside incognito network is not a possibility, which would be the best compromise between options 1, 2, and 3?


This also is a good idea!
So when shielding the system needs to lock some PRV, wait if/when there is an incoming transaction on the temp address and then use the PRV to buy ETH and send ETH to the temp address to pay for smart contract interaction? Because when you send from an ETH address to a temporary incognito address you pay your ethereum fees, then there are the other fees from the temporary address to the smart contract… The problem is there. And you need to pay only if you receive something.

Batching transactions together works only if the same address is used multiple times or by multiple users so you need to wait. Also this could be a good option. But if the address is used only one-time you can not accumulate more transactions and you always have to pay for the smart contract interaction.

In any case I think that a flexible system, like the one I described, is obviously more complex but it could be used to optimize many things.

1 Like

Good point there and I agree with Jamie’s point …which is this project and main point is privacy and should be a our north star when making decisions about the project. Incognito primary reason for being is to maximize privacy for the individual…if there are enhancements or updates or changes to be made to the project though it might create features that be convenient for the user does the new feature or policy affect the primary purpose of the project…once again…our north star…Privacy…not at any cost of course but our prime objective of the project if I am correct was and has been privacy…so I agree with Jamie it might be best not to tamper with it at this time… :sunglasses: …unless of course another idea is offered that well deal with gas issue but does not possibly violate any privacy aspect of Incognito. This an update to original post…Jared and Horus raise good ideas and going down that route might be a possible fix to eth gas issue…:slight_smile:

I am not a fan of the fixed shielding address.
I do have some ideas that could potentially fix the problems we are experiencing.

  1. Give users the ability to pay some extra PRV to extend the temporary address for a short amount of time

  2. Crowdsource Ethereum Gas Fees in exchange for a PRV Bond token

If normal users could supply Ethereum for Gas Prices, they should be rewarded with PRV. To create an incentive to do this, the PRV reward should be higher then the value given for the gas fees. To stop a crazy amount of PRV from getting flooded into the market, devaluing the price, the funds should be frozen for a specified time period: essentially making it a bond. During this frozen time, the PRV could be staked creating more funds to supply for these Ethereum PRV bonds. (If the values are balanced correctly, Incognito is still technically supplying the Ethereum Fees, but they are paying way less then they normally would)


Hmmm…interesting idea there Revolve…something to consider indeed