# Watr Proof of Concept
Watr will be an exchange platform for commodities (or rather virtual tokens in place of them)
## High level overview
We represent commodities as tokens, for example GOLD, USD, ALU, etc.
### Assets
What will actually be stored on the blockchain we'll call *assets* - each will symbolize e.g. 100 USD, 1 (tonne of) ALU, 3.5 (barrels of) OIL. Think of them as banknotes or UTXO - your wealth is the sum of the banknotes in your wallet.
There are two important values regarding each asset:
- *leaf value* (name is non-standardized) - a value that is published when asset is created (minted)
- *nullifier* - a value that is revealed when asset is spent (burned)
By *minting* an asset, we'll further mean adding the leaf-value to blockchain (to Merkle tree more precisely), and by *burning* marking the nullifier as "spent" (throwing error if it's spent already).
Those values are inevitably linked - what's especially important is that one cannot produce another valid nullifier for the same asset, which prevents from double spending.
It is impossible, however, to deduce one value from the other - which is important to preserve privacy, as it's impossible to connect events of creating and spending the same asset.
### Ownership
There were many different choices for the notion of ownership (what's sufficient to spend the asset), among others:
- \* Note: first of all we have to prove that asset with given leaf-value exists on the blockchain in the first place
- knowledge of the secret values used to generate leaf and nullifier values (used by TornadoCash)
- what's mentioned above as well as knowledge of the secret key corresponding to the embedded public key (used by ZCash and also us)
- the main advantage is that one can allow others a "read only" access to his asset, that is the ability to view hidden content and history without giving ability to spend
- also, in this approach we can safely reveal nullifier without the threat of front-running, which shouldn't be neccessary, but it's safer and easier having that assumption in mind
### Transaction
We think of *transaction* abstractly as something that burns certain assets and mints others. This way, even complicated deals can be constructed using the same interface.
In this PoC we only implement the simplest type of deal for example "I wish to exchange 3000 USD for 1 ALU". We also assume negotiations are performed off-chain and blockchain is only used as a platform to execute pre-negotiated contracts.
<!-- To do so, both sides agree off-chain on (apart from 3000 USD $\leftrightarrow$ 1 ALU of course):
- a random number $r$, from which transaction id is constructed:
- $\text{id} = Hash(3000,USD,1,ALU,r)$
- $r$ is important to make the contents of the transaction hard to guess and check
- labeling sides (which one is side "0" and "1")
-->
Then, each side publishes the following (later called a *commitment*) on the blockchain (using side with USD for example, labeled as "left" side)
- obfuscated transaction contents
- $\text{id} = Hash(3000,USD,1,ALU,r)$ for some random pre-agreed nonce $r$ to prevent guess and check
- proof that I own some $x$ USD corresponding to the nullifier that I'm also revealing
- proof that this obfuscated transaction content really contains $x$ USD on the "left" side
- leaf-value of what I wish to be minted
- proof that what I wish to be minted really is the other side of the transaction (1 ALU) and not, let's say 1 trillion ALU.
- secret shares of the transaction contents (explained in more detail in *Secret shares*)
When both sides of the transaction publish that, transaction is executed, that is transaction "inputs" are burned, and transaction "outputs" are minted.
To avoid the risk of only one party commiting to their deal, in which case they've:
- revealed their nullifiers
- agreed to a deal without the deadline for the other party to respond
- potentially wasted money for the fee
but the only solution I could think of was an expensive simultaneous reveal protocol.
Notice that the assets do not "change ownership" but rather are burned and minted anew and we simply guard that the balance is preserved.
### Secret shares
To calculate some aggregates such as average price, total volume, etc. we require transaction participants to disclose details in the form of $M$ shares sent to $M$ predefined semi-trusted parties (later called *computing parties*).
We currently use additive sharing scheme, as it is easy to implement, efficient and universally suported. It however makes it harder to protect against malicious parties, however (explained in more detail in *Risks*)
Your secrets are then safe as long as 1 party is honest (only all $M$ parties can reconstruct it)
The aggregates mentioned above are then calculated using multi party computing (MPC).
## Risks:
- Two market participants make a deal to manipulate volume or average price, for example
- Since deals are private, it's hard to protect against those attacks, in the current form practically impossible
(switching to orderbook format could solve that)
- One of the computing parties manipulates the result
- We can protect against even $M-1$ such parties via something called the GMW paradigm, albeit expensive
- There are less expensive solutions with other tradeoffs (usually tolerance of only $\frac{M}{3}$ malicious parties, still an active area of development)
- One of the computing parties refuses to reveal the secret
- In the current form $M$ computing parties are required and as such 1 non-cooperating computing party is enough to disrupt the system
- The number can be adjusted, with tolerance of up to $\frac{M}{2}$ non-cooperating parties
## Low level overview
- $MiMC$ - Minimal Multiplicative Complexity hash function, a zk-friendly hash function
- $Pedersen$ - Pedersen hash function, a zk-friendly hash function
- *leaf value* $=Pedersen(quantity,commodity,pk,nonce0,nonce1)$
- *nullifier* $=Pedersen(quantity,commodity,pk,nonce0)$
- secret shares:
- circuit receives:
- public keys of the *computing parties*
- since they're points on the eliptic curve, they consist of X and Y coordinate
```
signal input pkX[n];
signal input pkY[n];
```
- seed for the random nonce
- secret value to be encoded
- circuit outputs:
- $\text{ecdhNonce} = g^\text{seed}$ - it actually simultaneously performs ECDH with all *computing parties*
- $\begin{align*}\text{offset} &= \text{value} - {\text{pk}_1}^\text{seed}-\ldots-{\text{pk}_n}^\text{seed}=\\&= \text{value} - g^{\text{sk}_1\cdot\text{seed}}-\ldots-g^{\text{sk}_n\cdot\text{seed}}\end{align*}$
- each *computing party* computes their share:
- $\text{share}_i = \text{ecdhNonce}^{\text{sk}_i}=(g^\text{seed})^{\text{sk}_i}=g^{\text{sk}_i\cdot\text{seed}}$
- together, shares and offset add up to value:
- $\begin{align*}&\text{offset}+\text{share}_1+\ldots+\text{share}_n =\\&(\text{value} - g^{\text{sk}_1\cdot\text{seed}}-\ldots-g^{\text{sk}_n\cdot\text{seed}})+g^{\text{sk}_1\cdot\text{seed}}+\ldots+g^{\text{sk}_n\cdot\text{seed}}=\\&\text{value}\end{align*}$
- $\textit{transaction id}=Pedersen(quantity0,commodity0,quantity1,commodity1,r)$