# DEP 0003: Token Mint Authorization

```
status: accepted
```

## Current Situation

`Money::token_mint_v1()` allows minting a given token with the token ID
calculated as a commitment to the public key as
$$ T = \t{PoseidonHash}(69 || \mathcal{X}(P) || \mathcal{Y}(P)) $$
The ability to freeze minting tokens is offered. Let $Γ$ be the set of
frozen token IDs. When attempting to call mint, if $T ∈ Γ$, then the contract
will fail.

The amount being minted is publicly visible in the params.

## Motivation: Limitations of Current Approach

The main issue is contracts are unable to issue tokens. The current design
mandates the holder of a public key to issue the token.

Secondarily the token ID and amount being minted is visible breaking anonymity.

To fix the first issue, a basic fix would be allow setting an auth parent
contract for a specific token ID, but this does not fix the second issue.

## Proposal: Introspective Params

The authors preferred design goes for maximum generality, while
preserving existing functionality.

Firstly the token ID is changed to be calculated as
$$ T = \t{PoseidonHash}(\t{auth\_parent}, \t{user\_data}, b) $$
where $b$ is a blinding factor.

### `Money::token_mint_v1()`

We now define `Money::token_mint_v1()`. Let the params be coins $𝐂 = (Cᵢ)$
and `auth_parent`.
For each coin $Cᵢ$, let there be corresponding proofs $πᵢ$ such that

**Token ID integrity** &emsp; $T$ is calculated correctly committing to
`auth_parent`.

**Coin commitment integrity** &emsp; $Cᵢ = \t{PoseidonHash}(…, T, …)$

Additionally the contract checks that `auth_parent` is the function ID of
the parent caller.

The sole purpose of this call is to create a set of coins whose token ID
is a valid commitment, containing the field `auth_parent` which is publicly
revealed. Then it checks the parent caller matches this field.

### `Money::auth_mint_v1()`

In the interests of preserving the current functionality with minimal changes,
we provide a default auth module for use with token minting.

This provides an upgrade path to a future design with stronger anonymity
guarantees such as hiding the token ID from the network.

The contract performs the following checks:

* Reveals the token ID $T$ publicly.
* Checks $T ∉ Γ$, the set of frozen token IDs.
* Constructs a pedersen commit $V$ to the value in the coin, along with a proof.
  This allows auditing the supply since all commitments are linked publicly with
  the token ID.

### `Money::auth_mint_freeze_v1()`

Adds the token ID $T$ to the set of frozen token IDs $Γ$.
The caller must prove ownership of the public key which is set in the
`user_data` field of the token ID.

