Skip to content

Commit

Permalink
Merge pull request #914 from ShieldedLabs/zip-234-nsm-issuance
Browse files Browse the repository at this point in the history
[ZIP 234] NSM: Smooth Issuance Curve
  • Loading branch information
nuttycom authored Nov 6, 2024
2 parents 6025d32 + b0d3760 commit 34c2194
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 110 deletions.
File renamed without changes
File renamed without changes
225 changes: 115 additions & 110 deletions zips/zip-0234.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
```
ZIP: 234
Title: Smooth Out The Block Subsidy Issuance
Owners: Jason McGee <jason@shieldedlabs.com>
Mark Henderson <[email protected]>
Title: Network Sustainability Mechanism: Issuance Smoothing
Owners: Jason McGee <jason@shieldedlabs.net>
Zooko Wilcox <[email protected]>
Tomek Piotrowski <[email protected]>
Mariusz Pilarek <[email protected]>
Paul Dann <[email protected]>
Original-Authors: Nathan Wilcox
Credits:
Status: Draft
Expand All @@ -16,138 +17,148 @@ License: BSD-2-Clause
# Terminology

The key words “MUST”, “SHOULD”, “SHOULD NOT”, “MAY”, “RECOMMENDED”, “OPTIONAL”,
and “REQUIRED” in this document are to be interpreted as described in RFC 2119. [1]
and “REQUIRED” in this document are to be interpreted as described in RFC 2119.
[1]

"Network upgrade" - to be interpreted as described in ZIP 200. [2]

“Block Subsidy” - to be interpreted as described in the Zcash Protocol
Specification (TODO ZIP Editors: link from comment).
"Block Subsidy” - the algorithmic issuance of ZEC on block creation. Part of the
consensus rules. Split between the miner and the Dev Fund. Also known as Block
Reward.

“Issuance” - the sum of Block Subsidies over time. (TODO ZIP Editors: work out
if this definition is correct or can be removed).

`ZsfBalanceAfter(h)`” is the total ZEC available in the Zcash Sustainability
Fund (ZSF) after the transactions in block `h`, described in ZIP draft-zsf.md.
In this ZIP, the Sustainability Fund is used to pay out Block Subsidies from
unmined ZEC, and other fund deposits.
"Issuance" - The method by which ZEC becomes available for circulation on the
network.

Let `PostBlossomHalvingInterval` be as defined in [#protocol-diffadjustment]_.

"Money Reserve" - `MAX_MONEY - ChainValue`, where `ChainValue` includes all ZEC
available on the network, across all value pools.

# Abstract

This ZIP proposes a change to how nodes calculate the block subsidy.

Instead of following a step function around the 4-year halving intervals
inherited from Bitcoin, we propose a slow exponential “smoothing” of the curve.
The new issuance scheme would approximate the current issuance over 4-year
intervals.
inherited from Bitcoin, we propose a smooth logarithmic curve, defined as a
fixed portion of the current value of the Money Reserve at a given block height.

This ZIP depends on the ZIP introducing the Zcash Sustainability Fund
(ZIP-XXX).
The new issuance scheme would approximate the current issuance over 4-year
intervals, assuming no ZEC is burned during that time, and retains the overall
supply cap of `MAX_MONEY`.

# Motivation

Key Objectives:

1. We want to introduce an automated mechanism that allows users of the network
to contribute to the long-term sustainability of the network.
2. We want to enable ZEC that has been burned to be recreated in the future to
benefit network sustainability.
3. We want to retain the existing ZEC supply cap of 21 million.
4. We want the issuance rate to remain similar to the historical rate for Zcash
(and before that, Bitcoin).
5. We want issuance to be easy for all network users to understand and predict.
6. We want the new issuance to activate at a block with as minimal a delta from
the current issuance as possible.

The current Zcash economic model, inherited from Bitcoin, includes a halving
mechanism which dictates the issuance of new coins. While this has been
mechanism that dictates the issuance of new coins. While this has been
foundational, halvings can lead to abrupt changes in the rate of new coins
being introduced to the market. Such sudden shifts can potentially disrupt the
network's economic model, potentially impacting its security and stability.
Furthermore, the halvings schedule is fixed and does not provide any way to
"recycle" funds into future issuance.

To address this, we propose issuing a fixed portion of the pending
funds-to-be-issued in each block. This has the effect of smoothing out the
issuance curve of ZEC, ensuring a more consistent and predictable rate of coin
issuance, while still preserving the overall supply cap of 21,000,000 coins.
This mechanism by itself (without other anticipated changes) seeks to preserve
the core aspects of Zcash's issuance policy and aims to enhance predictability
and avoid sudden changes. By making this shift, the average block subsidy over
time will remain predictable with very gradual changes.

However, we anticipate schemes proposed in [#draft-zsf]_ where the amount of
funds-to-be-issued may increase. In that scenario, this issuance mechanism
would distribute that increase starting in the immediately following block and
subsequent blocks. Because this distribution mechanism has an exponential
decay, such increases will be spread out in miniscule amounts to future blocks
over a long time period. This issuance mechanism thus provides a way for
potential increases or decreases of issuance while constraining those changes
to be small on a short time scale to avoid unexpected disruptions.

Additionally, the current Bitcoin-style issuance does not take into account the
current balance of `ZsfBalanceAfter(h)`. If [#draft-zsf]_ were to activate
without a change to the issuance mechanism, then some funds would never be
disbursed after they are deposited back into the ZSF.
This new NSM-based issuance scheme solves these problems by ensuring a more
consistent and predictable rate of coin issuance, while preserving the core
aspects of Zcash's issuance policy and the 21 million coin cap. At the same
time, it introduces the first mechanism to recreate and distribute ZEC that has
been removed from circulation, as well as unclaimed transaction fees, across
future block subsidies.

# Requirements

Smoothing the issuance curve is possible using an exponential decay formula
that satisfies the following requirements:

## Issuance Requirements

1. The issuance can be summarised into a reasonably simple explanation
1. The issuance can be summarized into a reasonably simple explanation
2. Block subsidies approximate a continuous function
3. If there are funds in the ZSF, then the block subsidy must be non-zero,
preventing any final unmined zatoshis
3. If the Money Reserve is greater than 0, then the block subsidy must be
non-zero, preventing any final "unmined" zatoshis
4. For any 4 year period, all paid out block subsidies are approximately equal
to half of the ZSF at the beginning of that 4 year period, if there are no
deposits into the ZSF during those 4 years
to half of the Money Reserve at the beginning of that 4 year period, if no
ZEC is burned during those 4 years
5. Decrease the short-term impact of the deployment of this ZIP on block reward
recipients, and minimize the potential reputation risk to Zcash of changing
the block reward amount.

TODO daira: add a requirement that makes the initial total issuance match the previous total issuance
TODO daira: add a requirement that makes the initial total issuance match the previous total issuance

# Specification

## Goals

We want to decrease the short-term impact of the deployment of this ZIP on
block reward recipients, and minimise the potential reputational risk to Zcash
of changing the block reward amount.

## Constants

Define constants:

`BLOCK_SUBSIDY_FRACTION`” = 4126 / 10,000,000,000 or `0.0000004126`

"`DEPLOYMENT_BLOCK_HEIGHT`" = 2726400
## Parameters

`BLOCK_SUBSIDY_FRACTION` = 4126 / 10,000,000,000 or `0.0000004126`

`DEPLOYMENT_BLOCK_HEIGHT` = `TBD`

The block height will be chosen by the following criteria:

- It is after NU7 activation height.
- It is calculated to be the lowest height after the the second halving at
which the NSM issuance would be less than the current BTC-style issuance
_neglecting_ any burnt ZEC (ie. assuming the amount of ZEC burnt is exactly 0).

This selection is intended to achieve Key Objective 6 while still being a
constant height. An alternative would be to have a dynamic "latch" style
activation which would calculate the activation height by testing the "less
than" conditional with every block after the second halving. We prefer the
pre-defined constant height parameter to give everyone more _time_ certainty at
the cost of _issuance level_ certainty. The difference in up-front calculation
versus dynamic calculation is whether or not burns are accounted for (since
future burns cannot be calculated up-front). This means with the pre-defined
constant parameter approach, issuance will jump _up_ some amount at activation.
This amount should be equivalent to all ZEC burnt prior to that height times
`BLOCK_SUBSIDY_FRACTION`. For example, if a total of 100,000 ZEC were burnt
prior to the pre-defined constant activation height, then at activation the
issuance would be larger than BTC-style issuance by `100_000 ZEC *
BLOCK_SUBSIDY_FRACTION` which we calculate equals `0.04126 ZEC`. This example
is chosen to demonstrate that a very large burn amount (much larger than
expected) would elevate issuance by a relatively small amount. For this reason,
we believe a pre-defined constant is a better approach to achieving Key
Objective 6 than a "dynamic latch" logic because it is so much simpler to
implement and reason about.

`MoneyReserveAfter(block_height)` = The value of the Money Reserve after the
specified block height.

## Issuance Calculation

At the `DEPLOYMENT_BLOCK_HEIGHT`, nodes should switch from the current issuance
calculation, to the following:

Given the block height `h` define a function **BlockSubsidy(h)**, such that:

**BlockSubsidy(h)** = Block subsidy for a given `h`, that satisfies above
requirements.

Using an exponential decay function for **BlockSubsidy** satisfies requirements
**R1** and **R2** above:

`BlockSubsidy(h) = BLOCK_SUBSIDY_FRACTION * ZsfBalanceAfter(h - 1)`

Finally, to satisfy **R3** above we always round up to the next zatoshi.

`BlockSubsidy(h) = ceiling(BLOCK_SUBSIDY_FRACTION * ZsfBalanceAfter(h - 1))`
`BlockSubsidy(block_height) = ceiling(BLOCK_SUBSIDY_FRACTION * MoneyReserveAfter(block_height - 1))`

# Rationale

* Using an exponential decay function satisfies **Requirements 1** and **2** above.
* We round up to the next zatoshi to satisfy **Requirement 3** above.

## `BLOCK_SUBSIDY_FRACTION`

Let `IntendedZSFFractionRemainingAfterFourYears` = 0.5.
Let `IntendedMoneyReserveFractionRemainingAfterFourYears` = 0.5.

The value `4126 / 10_000_000_000` satisfies the approximation within +0.002%:

`(1 - BLOCK_SUBSIDY_FRACTION)^PostBlossomHalvingInterval ≈ IntendedZSFFractionRemainingAfterFourYears`
`(1 - BLOCK_SUBSIDY_FRACTION)^PostBlossomHalvingInterval ≈ IntendedMoneyReserveFractionRemainingAfterFourYears`

Meaning after a period of 4 years around half of `ZSF_BALANCE` will be paid out
as block subsidies, thus satisfying **R4**.
Meaning after a period of 4 years around half of Money Reserve will be issued as
block subsidies, thus satisfying **Requirement 4**.

The largest possible amount in the ZSF is MAX_MONEY, in the theoretically
possible case that all issued funds are deposited back into the ZSF. If this
happened, the largest interim sum in the block subsidy calculation would be
MAX_MONEY * 4126 + 10000000000.
The largest possible value in the Money Reserve is `MAX_MONEY`, in the
theoretically possible case that all issued funds are burned. If this happened,
the largest interim sum in the block subsidy calculation would be `MAX_MONEY *
4126 / 10000000000`.

This uses 62.91 bits, which is just under the 63 bit limit for 64-bit signed
two's-complement integer amount types.
Expand All @@ -158,64 +169,58 @@ chose a power-of-10 denominator for simplicity.

TODO for ZIP owners: How many ZEC per day?

## `DEPLOYMENT_BLOCK_HEIGHT`

The deployment should happen at the next halving, which is block `2726400`.

Since there is a planned halving at this point, there will already be a
significant "shock" caused by the drop in issuance caused by the halving. This
reduces surprise and thus increases security. Also, due to the nature of the
smoothed curve having a portion of the curve above the respective step function
line at times, this will maximally _reduce_ the issuance shock at the
`DEPLOYMENT_BLOCK_HEIGHT`.

## Visualization of the Smoothed Curve

The following graph illustrates compares issuance for the current halving-based
step function vs the smoothed curve.
The following graph compares issuance for the current halving-based step
function vs the smoothed curve.

![A graph showing a comparison of the halving-based step function vs the smoothed curve](../rendered/assets/images/zip-0234-block_subsidy.png)

The graph below shows the balance of the ZSF assuming smooth issuance is
implemented.
The graph below shows the balance of the Money Reserve assuming smooth issuance
is implemented.

![A graph showing the balance of the ZSF assuming smooth issuance is implemented](../rendered/assets/images/zip-0234-balance.png)
![A graph showing the balance of the Money Reserve assuming smooth issuance is implemented](../rendered/assets/images/zip-0234-balance.png)

# Deployment

The implementation of this ZIP MUST be deployed at the same time or after the
Zcash Sustainability Fund is established (ZIP-XXX).
Network Sustainability Mechanism Burning function is deployed (ZIP-0233).

# Appendix: Simulation

The [ZSF simulator](https://github.com/eigerco/zsf-simulator) allows us to
simulate the effects of this ZIP on the ZSF balance and the block subsidy, as
The [NSM Simulator](https://github.com/eigerco/zsf-simulator) allows us to
simulate the effects of this ZIP on the Money Reserve and the block subsidy, as
well as generate plots like the ones above. Its output:

```
Last block is 47917869 in ~113.88 years
```

indicates that, assuming no ZEC is ever deposited to the ZSF, its balance will
be depleted after 113.88 years, and the block subsidy will be 0 ZEC after that
indicates that, assuming that no ZEC is ever burned, the Money Reserve will be
depleted after 113.88 years, and the block subsidy will be 0 ZEC after that
point.

This fragment of the output
This fragment of the output:

```
Halving 1 at block 1680000:
ZSF subsidies: 262523884819889 (~ 2625238.848 ZEC, 1.563 ZEC per block)
NSM subsidies: 262523884819889 (~ 2625238.848 ZEC, 1.563 ZEC per block)
legacy subsidies: 262500000000000 (~ 2625000.000 ZEC, 1.562 ZEC per block)
difference: 23884819889 (~ 238 ZEC), ZSF/legacy: 1.0001
difference: 23884819889 (~ 238 ZEC), NSM/legacy: 1.0001
```

shows that the difference between the smoothed out and the current issuance
schemes is 238 ZEC after 1680000 blocks (aroound 4 years).
schemes is 238 ZEC after 1680000 blocks (around 4 years).

# Appendix: Considerations for the Future

Future protocol changes may not increase the payout rate to a reasonable
approximation beyond the four year half-life constraint.

# References

[1] RFC-2119: https://datatracker.ietf.org/doc/html/rfc2119

[2] ZIP-200: https://zips.z.cash/zip-0200
[2] [ZIP-200: Network Upgrade Mechanism](zip-0200.rst)

[3] ZIP-XXX: Placeholder for the ZSF ZIP
[3] [ZIP_233: Network Sustainability Mechanism: Burning](zip-0233.md)

0 comments on commit 34c2194

Please sign in to comment.