Always check allowance over inputs
As we have seen in the confidential token example, most of your external facing functions that expose a confidential input will want to be declared twice like so.msg.sender.isAllowed(value)
.
This is important because the caller may use an existing handle that it has not access to but that the contract
has access to. In this case, depending on the contract, the caller may be to deduce or gain access to the value in used as input.
Think in terms of information leakage
When designing an app, you need to be mindful not only to who receives access over the ciphertexts, but also about what can be deduced from the information that is publicly available. For example, if we were to naively port Uniswap pools to Inco, we may want to accept confidential input amounts for a swap and send confidential output amounts. If the price of the pool is public, then the swapped amount can be deduced by comparing the price before and after the swap. In another example, if you are holding a secret auction where the current highest bidder is continuously updated, one can deduce the current highest bid by submitting increasingly large bids until it becomes the highest bidder. This kind of possible deductions are called information leakage, and may show up often in your dapps.Don’t lose access over your ciphertexts
Don’t forget to calle.allowThis()
and e.allow
after an operation. By default, after the transaction is
included, no one retains access to the new handles being created and the contract will not be able to compute over them in the future,
and the user won’t be able to see them if not granted access.
Be extra careful of delegatecalls
A contract being delegatecalled can decrypt any ciphertext your contract holds or share access to it.Don’t hesitate to contact us for any question or if you want to discuss your dapp design.
We are also interested in your feedback on this doc.