# Sapling test contract. Is it safe / audited ? Ready for mainnet?

**URL:** https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446
**Category:** DApps
**Tags:** sapling
**Created:** [July 8, 2021, 6:54pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446 "2021-07-08T18:54:13Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Christian](https://forum.tezosagora.org/letter_avatar_proxy/v4/letter/c/b2d939/32.png) [@Christian](https://forum.tezosagora.org/u/Christian)
#### Post date: [July 8, 2021, 6:54pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/1 "2021-07-08T18:54:13Z")

</div>

With the adoption of sapling contracts and shielded transactions with Edo, there has been a lot of talk about the integration of confidential transaction into main stream applications.

Sadly there is no “visible” progress in this matter.

The documentations for the sapling integrations includes a test contract for a shielded Tez pool with a 1 to 1 conversion to (unshielded) Tez.

[https://tezos.gitlab.io/010/sapling.html](https://tezos.gitlab.io/010/sapling.html)  
[https://gitlab.com/tezos/tezos/-/blob/master/src/proto\_008\_PtEdo2Zk/lib\_protocol/test/contracts/sapling\_contract.tz](https://gitlab.com/tezos/tezos/-/blob/master/src/proto_008_PtEdo2Zk/lib_protocol/test/contracts/sapling_contract.tz)

While It’s currently only usable with cli, I’m thinking about locking some funds in this contract and incentivize some usage.

Hence my question if it is safe to lock larger Tez amount in this contract?

---

<div class="post-metadata">

### Author: ![Christian](https://forum.tezosagora.org/letter_avatar_proxy/v4/letter/c/b2d939/32.png) [@Christian](https://forum.tezosagora.org/u/Christian)
#### Post date: [July 29, 2021, 9:12am UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/2 "2021-07-29T09:12:48Z")

</div>

@NomadicLabs can you comment on this?

---

<div class="post-metadata">

### Author: ![greeneye12](https://forum.tezosagora.org/letter_avatar_proxy/v4/letter/g/6f9a4e/32.png) [@greeneye12](https://forum.tezosagora.org/u/greeneye12)
#### Post date: [December 28, 2021, 5:34pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/3 "2021-12-28T17:34:31Z")

</div>

No answer…

Airgap has added support for sapling since August, when will the mainnet contract be deployed?

---

<div class="post-metadata">

### Author: ![Christian](https://forum.tezosagora.org/letter_avatar_proxy/v4/letter/c/b2d939/32.png) [@Christian](https://forum.tezosagora.org/u/Christian)
#### Post date: [January 1, 2022, 8:58am UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/4 "2022-01-01T08:58:43Z")

</div>

you really don’t see this level of ghosting the community anywhere else  
@NomadicLabs @murbard

---

<div class="post-metadata">

### Author: ![murbard](https://forum.tezosagora.org/user_avatar/forum.tezosagora.org/murbard/32/67_2.png) [@murbard](https://forum.tezosagora.org/u/murbard)
#### Post date: [January 2, 2022, 11:48am UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/5 "2022-01-02T11:48:53Z")

</div>

I don’t know if that code’s been audited but it’s very straightforward and only about 40 lines of well documented code, all the heavy lifting happens in `SAPLING_VERIFY_UPDATE`, not really in the contract itself.

However, it doesn’t really make sense to use it as such, as the absence of delegation would create an incentive to go in and out of the pool which would hurt privacy. This is essentially the type of use case ctez exists for.

---

<div class="post-metadata">

### Author: ![murbard](https://forum.tezosagora.org/user_avatar/forum.tezosagora.org/murbard/32/67_2.png) [@murbard](https://forum.tezosagora.org/u/murbard)
#### Post date: [January 2, 2022, 12:59pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/6 "2022-01-02T12:59:37Z")

</div>

It only takes a few minimal tweaks, for instance

```auto
storage (sapling_state 8);
parameter (list (pair (sapling_transaction 8) (option address) ) );
code {
       # Do not accept tez
       AMOUNT;
       PUSH mutez 0;
       ASSERT_CMPEQ ;
       # Get ctez contract entrypoint (or other)
       PUSH @ctez address "KT1SjXiUX63QvdNMcM2m492f7kuf8JxXRLp4%transfer" ;
       CONTRACT (pair nat (pair address address)); ASSERT_SOME ; 
       SWAP;
       # Stack manipulation
       UNPAIR;
       NIL operation; DUG 2;
       ITER { UNPAIR;
              DIP { SWAP };
       # We verify the transaction and update the storage if the transaction is
       # valid. The shielded transactions are handled here.
       # The new state is pushed on top of the stack in addition to the balance
       # of the transaction. If the rest of the script goes well, this state
       # will be the new state of the smart contract.
              SAPLING_VERIFY_UPDATE;
       # In the case of an invalid transaction, we stop.
              ASSERT_SOME;
              UNPAIR;
              DUP;
              # We have three cases now: unshielding, shielding and transfers.
              # If the balance is strictly positive (i.e. unshielding), we send funds
              # to the given address.
              # If no address is given (see ASSERT_SOME), we stop
              IFGT {
                     ABS @sapling_balance_is_positive;
                     DIIP { ASSERT_SOME };
                     SWAP;
                     DIP {
                           SWAP ; RENAME @to;
                           SELF_ADDRESS @from;
                           PAIR; SWAP; PAIR @param;
                           DUP 3;
                           SWAP;
                           PUSH mutez 0;
                           SWAP ;
                           TRANSFER_TOKENS;
                           CONS };
                   }
                   {
                     DUP ;
                     IFLT
                       {
                         # If the balance is negative, we are shielding. The spend will have to have been authorized in the fa1.2 contract
                         SWAP ;
                         DIP
                           {
                             ABS ; SELF_ADDRESS @to ;
                             DIG 2 ; ASSERT_SOME ; RENAME @from ;
                             PAIR; SWAP ; PAIR @param;
                             DUP 3;
                             SWAP;
                             PUSH mutez 0;
                             SWAP ;
                             TRANSFER_TOKENS ;
                             CONS ;
                           };
                       }
                       {
                         # Internal transfer
                         DROP ; SWAP ; ASSERT_NONE ;
                       };
                   };
            };
       DIG 2 ; DROP ; SWAP ; PAIR ;
     }
 

```

---

<div class="post-metadata">

### Author: ![NomadicLabs](https://forum.tezosagora.org/user_avatar/forum.tezosagora.org/nomadiclabs/32/763_2.png) [@NomadicLabs](https://forum.tezosagora.org/u/NomadicLabs)
#### Post date: [January 3, 2022, 4:07pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/7 "2022-01-03T16:07:43Z")

</div>

Sorry for the late reply.

Like @murbard pointed out, most of the complexity of the Sapling protocol is hidden in the Michelson instruction SAPLING\_VERIFY\_UPDATE, the rest of the contract logic should be auditable by any Michelson developer. No special expertise is needed.

Our goal was to integrate a privacy enhancing solution as generic as possible. We therefore did it as a Michelson instruction. The contract we provided is just a simple example that we developed for testing and educational purposes.

There are many ways in which Sapling can be used inside a product, we are happy to provide support to any interested developer.

---

<div class="post-metadata">

### Author: ![murbard](https://forum.tezosagora.org/user_avatar/forum.tezosagora.org/murbard/32/67_2.png) [@murbard](https://forum.tezosagora.org/u/murbard)
#### Post date: [February 28, 2022, 4:13pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/8 "2022-02-28T16:13:56Z")

</div>

With Airgap launching, I had another look at the contract over the weekend. As I’ve said above, it’s pretty straighfoward code, but it also has a subtle issue. `SAPLING_VERIFY_UPDATE` only returns the unshielded amount, but it doesn’t bind the proof to the output address. This makes unshielding transactions malleable.

While it’s _technically_ possible to use Sapling as is on Tezos with a commit/reveal scheme, writing a safe and practical contract would require a version of `SAPLING_VERIFY_UPDATE` that binds the proof to a given output, in our case the optional address. It’s not a difficult fix, but it is a protocol level change. I contacted the AirGap team when I spotted the issue and there was only about 68 tez in the pool.

---

<div class="post-metadata">

### Author: ![NomadicLabs](https://forum.tezosagora.org/user_avatar/forum.tezosagora.org/nomadiclabs/32/763_2.png) [@NomadicLabs](https://forum.tezosagora.org/u/NomadicLabs)
#### Post date: [February 28, 2022, 4:17pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/9 "2022-02-28T16:17:47Z")

</div>

We agree with @murbard in his observation that this sapling contract, as deployed on `mainnet`, is indeed vulnerable.

We are working towards producing a patch to fix this issue, which will be included with the next protocol proposal J.

In the meantime it is not advisable to rely on this contract as is.

---

<div class="post-metadata">

### Author: ![AirGap\_it](https://forum.tezosagora.org/user_avatar/forum.tezosagora.org/airgap_it/32/1511_2.png) [@AirGap\_it](https://forum.tezosagora.org/u/AirGap_it)
#### Post date: [March 3, 2022, 11:08pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/10 "2022-03-03T23:08:24Z")

</div>

At the end of last week, we at AirGap announced the integration of Sapling into our solution.

This was the first known implementation of Sapling into a product. Unfortunately, an issue with Sapling was spotted by Arthur Breitman - as a precaution we acted quickly to disable this integration.

It appears that with the current integration of Sapling, it is possible that the address to which funds are unshielded to, can be changed while the signed operation is in the mempool. As the current contract that AirGap uses holds only an amount of 68 tez, this flaw was fortunately caught in a timely manner.

We advise any users who have locked funds to reach out to us on Discord, Telegram or by Email.

The Nomadic Labs team is aware of this and has also confirmed they are working on a fix that will be proposed for inclusion in the “J” protocol proposal.

We are excited to reactivate this feature once the fix is implemented so users can use Sapling from our solution.

---

<div class="post-metadata">

### Author: ![NomadicLabs](https://forum.tezosagora.org/user_avatar/forum.tezosagora.org/nomadiclabs/32/763_2.png) [@NomadicLabs](https://forum.tezosagora.org/u/NomadicLabs)
#### Post date: [March 15, 2022, 5:23pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/11 "2022-03-15T17:23:52Z")

</div>

After the announcement of this vulnerability, we have developed a new, safer integration, for Sapling transactions into Michelson smart contracts. This has already been merged into the Tezos `master` branch, and will be a part of an upcoming “J” protocol proposal.

More details can be found in our latest blog entry: [https://research-development.nomadic-labs.com/fixing-the-sapling-protocol-integration.html](https://t.co/uSS1ltF19Y)

Notice that this new version of the integration is part of the Tezos economic protocol, and as such it will **only** be available if protocol proposal “J” is accepted by the community, and **only after** it becomes active on mainnet.

Until then, we advise against originating new Sapling contracts on mainnet, and to avoid interacting with existing deployed Sapling contracts.

---

<div class="post-metadata">

### Author: ![Christian](https://forum.tezosagora.org/letter_avatar_proxy/v4/letter/c/b2d939/32.png) [@Christian](https://forum.tezosagora.org/u/Christian)
#### Post date: [May 24, 2022, 1:05pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/12 "2022-05-24T13:05:02Z")

</div>

> [@AirGap\_it](#):
>
> We are excited to reactivate this feature once the fix is implemented so users can use Sapling from our solution.

are you launching it on jakartanet (testnet)?  
would be great if we could try it out prior to the mainnet launch.

---

<div class="post-metadata">

### Author: ![Christian](https://forum.tezosagora.org/letter_avatar_proxy/v4/letter/c/b2d939/32.png) [@Christian](https://forum.tezosagora.org/u/Christian)
#### Post date: [May 24, 2022, 1:14pm UTC](https://forum.tezosagora.org/t/sapling-test-contract-is-it-safe-audited-ready-for-mainnet/3446/13 "2022-05-24T13:14:53Z")

</div>

[this](https://gitlab.com/tezos/tezos/-/blob/master/src/proto_013_PtJakart/lib_protocol/test/integration/michelson/contracts/sapling_contract.tz) is the **fixed** contract for **J** right?
