-
Notifications
You must be signed in to change notification settings - Fork 179
[ZIP 234] Smooth Out The Block Subsidy Issuance #706
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 42 commits
3e4ca01
753d180
b0c142f
54317ed
2d691eb
66dab1e
907fe1c
8b725d8
087f7b9
e3a28eb
609a3c6
5e6c367
013dcc1
bf090f4
dca1174
de30fea
45ff587
8cc6f92
9f4e7fd
c2a591a
8ea2ecc
4983a32
c5f83c1
1e977ba
74649db
2448c6c
e1aa108
f603576
5d5bc35
31d05c5
4b6d62c
44d5b95
3f77205
732e65a
d5ea3da
44fc779
212244f
fedfd9e
54e349d
7c64666
900b868
3f6eb54
776295c
c315670
86049bb
b580625
0c42f7b
f5224f8
be2140a
7133f29
f4d84e9
20a12da
96169eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| <p><code>ZIP: | ||
| Title: Smooth Out The Block Subsidy Issuance | ||
| Owners: Jason McGee <jason@shieldedlabs.com> | ||
| Mark Henderson <mark@equilibrium.co> | ||
| Tomek Piotrowski <tomek@eiger.co> | ||
| Mariusz Pilarek <mariusz@eiger.co> | ||
| Original-Authors: Nathan Wilcox | ||
| Credits: | ||
| Status: Draft | ||
| Category: Consensus | ||
| Created: 2023-08-23 | ||
| License: BSD-2-Clause</code></p> | ||
| <h1>Terminology</h1> | ||
| <p>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]</p> | ||
| <p>"Network upgrade" - to be interpreted as described in ZIP 200. [2]</p> | ||
| <p>“Block Subsidy” - to be interpreted as described in the Zcash Protocol Specification (TODO ZIP Editors: link from comment).</p> | ||
| <p>“Issuance” - the sum of Block Subsidies over time. (TODO ZIP Editors: work out if this definition is correct or can be removed).</p> | ||
| <p>“<code>ZsfBalanceAfter(h)</code>” is the total ZEC available in the Zcash Sustainability Fund (ZSF) after the transactions | ||
| in block <code>h</code>, 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.</p> | ||
| <p>Let <code>PostBlossomHalvingInterval</code> be as defined in [#protocol-diffadjustment]_.</p> | ||
| <h1>Abstract</h1> | ||
| <p>This ZIP proposes a change to how nodes calculate the block subsidy.</p> | ||
| <p>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.</p> | ||
| <h1>Motivation</h1> | ||
| <p>The current Zcash economic model, inherited from Bitcoin, includes a halving mechanism which 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.</p> | ||
| <p>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.</p> | ||
| <p>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. </p> | ||
| <p>Additionally, the current Bitcoin-style issuance does not take into account the current balance of <code>ZsfBalanceAfter(h)</code>. 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.</p> | ||
| <p>In summary, by introducing a smoother emissions curve, we: | ||
| - maintain the economic viability of Zcash | ||
| - provide predictability of the issuance rate, allowing only miniscule changes over short time ranges | ||
| - enhance Zcash's stability as the network evolves.</p> | ||
| <h1>Requirements</h1> | ||
| <p>Smoothing the issuance curve is possible using an exponential decay formula that | ||
| satisfies the following requirements:</p> | ||
| <h2>Issuance Requirements</h2> | ||
| <ol> | ||
| <li>The issuance can be summarised into a reasonably simple explanation</li> | ||
| <li>Block subsidies approximate a continuous function</li> | ||
| <li>If there are funds in the ZSF, then the block subsidy must be non-zero, preventing any final “unmined” zatoshis</li> | ||
| <li>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 | ||
| TODO daira: add a requirement that makes the initial total issuance match the previous total issuance </li> | ||
| <li>This functionality MUST be introduced as part of a network upgrade</li> | ||
| </ol> | ||
| <h1>Specification</h1> | ||
| <h2>Goals</h2> | ||
| <p>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.</p> | ||
| <h2>Constants</h2> | ||
| <p>Define constants:</p> | ||
| <p>“<code>BLOCK_SUBSIDY_FRACTION</code>” = 4126 / 100,000,000 or <code>0.0000004126</code></p> | ||
| <p>"<code>DEPLOYMENT_BLOCK_HEIGHT</code>" = 2726400</p> | ||
| <h2>Issuance Calculation</h2> | ||
| <p>At the <code>DEPLOYMENT_BLOCK_HEIGHT</code>, nodes should switch from the current issuance calculation, to the following:</p> | ||
| <p>Given the block height <code>h</code> define a function <strong>BlockSubsidy(h)</strong>, such that:</p> | ||
| <p><strong>BlockSubsidy(h)</strong> = Block subsidy for a given <code>h</code>, that satisfies above requirements.</p> | ||
| <p>Using an exponential decay function for <strong>BlockSubsidy</strong> satisfies requirements <strong>R1</strong> and <strong>R2</strong> above:</p> | ||
| <p><code>BlockSubsidy(h) = BLOCK_SUBSIDY_FRACTION * ZsfBalanceAfter(h - 1)</code></p> | ||
| <p>Finally, to satisfy <strong>R3</strong> above we always round up to the next zatoshi.</p> | ||
| <p><code>BlockSubsidy(h) = ceiling(BLOCK_SUBSIDY_FRACTION * ZsfBalanceAfter(h - 1))</code></p> | ||
| <h2>Deployment</h2> | ||
| <p>TBD</p> | ||
| <h1>Rationale</h1> | ||
| <h2><code>BLOCK_SUBSIDY_FRACTION</code></h2> | ||
| <p>Let <code>IntendedZSFFractionRemainingAfterFourYears</code> = 0.5.</p> | ||
| <p>The value <code>4126 / 100_000_000</code> satisfies the approximation within +0.002%:</p> | ||
| <p><code>(1 - BLOCK_SUBSIDY_FRACTION)^PostBlossomHalvingInterval ≈ IntendedZSFFractionRemainingAfterFourYears</code></p> | ||
| <p>Meaning after a period of 4 years around half of <code>ZSF_BALANCE</code> will be paid out | ||
| as block subsidies, thus satisfying <strong>R4</strong>.</p> | ||
| <p>TODO for ZIP owners: How many ZEC per day?</p> | ||
| <h2><code>DEPLOYMENT_BLOCK_HEIGHT</code></h2> | ||
| <p>The deployment should happen at the next halving, which is block <code>2726400</code>.</p> | ||
| <p>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 <em>reduce</em> the issuance shock at the <code>DEPLOYMENT_BLOCK_HEIGHT</code>.</p> | ||
| <h2>Visualization of the Smoothed Curve</h2> | ||
| <p>The following graph, taken from the ECC blog post, illustrates the smoothed curve. Note that depending on when the network upgrade takes place the disbursement may temporarily <em>increase</em>.</p> | ||
| <p><img alt="A graph showing a comparison of the halving-based step function vs the smoothed curve" src="./draft-zip-smoothed-issuance-curve.png" /></p> | ||
| <p>[TODO: We should update this graph now showing the deployment at <code>2726400</code>]</p> | ||
| <h2>Other Notes</h2> | ||
| <p>The suggested implementation avoids using float numbers. Rust and C++ will both round | ||
| the result of the final division up, satisfying <strong>R3</strong> above.</p> | ||
| <h1>Appendix: Simulation</h1> | ||
| <p>We encourage readers to run the following Rust code, which simulates block subsidies. | ||
| According to this simulation, assuming no deflationary action, block subsidies would | ||
| last for approximately 113 years:</p> | ||
| <h2>Rust Code</h2> | ||
| <p>```rust | ||
| fn main() { | ||
| // approximate available subsidies in August of 2023 | ||
| let mut available_subsidies: i64 = 4671731 * 100_000_000; | ||
| let mut block: u32 = 0;</p> | ||
| <pre><code>while available_subsidies > 0 { | ||
| let block_subsidy = (available_subsidies * 41 + 99_999_999) / 100_000_000; | ||
| available_subsidies -= block_subsidy; | ||
|
|
||
| println!( | ||
| "{} ({} years): {}({} ZEC) {}({} ZEC)", | ||
| block, // current block | ||
| block / 420_768, // ~ current year | ||
| block_subsidy, // block subsidy in zatoshis | ||
| block_subsidy / 100_000_000, // block subsidy in ZEC | ||
| available_subsidies, // available subsidies in zatoshis | ||
| available_subsidies / 100_000_000 // available subsidies in ZEC | ||
| ); | ||
|
|
||
| block += 1; | ||
| } | ||
| </code></pre> | ||
| <p>} | ||
| ```</p> | ||
| <p>Last line of output of the above program is:</p> | ||
| <p><code>47699804 (113 years): 1(0 ZEC) 0(0 ZEC)</code></p> | ||
| <p>Note the addition of 99,999,999 before division to force rounding up of non-zero values.</p> | ||
| <h1>References</h1> | ||
| <p>[1] RFC-2119: https://datatracker.ietf.org/doc/html/rfc2119</p> | ||
| <p>[2] ZIP-200: https://zips.z.cash/zip-0200</p> | ||
| <p>[3] ZIP-XXX: Placeholder for the ZSF ZIP</p> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,195 @@ | ||
| ``` | ||
| ZIP: | ||
| Title: Smooth Out The Block Subsidy Issuance | ||
| Owners: Jason McGee <jason@shieldedlabs.com> | ||
| Mark Henderson <mark@equilibrium.co> | ||
| Tomek Piotrowski <tomek@eiger.co> | ||
| Mariusz Pilarek <mariusz@eiger.co> | ||
| Original-Authors: Nathan Wilcox | ||
| Credits: | ||
| Status: Draft | ||
| Category: Consensus | ||
| Created: 2023-08-23 | ||
| 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] | ||
|
|
||
| "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). | ||
|
|
||
| “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. | ||
|
aphelionz marked this conversation as resolved.
|
||
|
|
||
|
aphelionz marked this conversation as resolved.
|
||
| Let `PostBlossomHalvingInterval` be as defined in [#protocol-diffadjustment]_. | ||
|
|
||
|
|
||
| # 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. | ||
|
|
||
|
teor2345 marked this conversation as resolved.
|
||
| # Motivation | ||
|
|
||
| The current Zcash economic model, inherited from Bitcoin, includes a halving mechanism which 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. | ||
|
|
||
| In summary, by introducing a smoother emissions curve, we: | ||
| - maintain the economic viability of Zcash | ||
| - provide predictability of the issuance rate, allowing only miniscule changes over short time ranges | ||
| - enhance Zcash's stability as the network evolves. | ||
|
|
||
| # 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 | ||
| 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 | ||
| 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 | ||
| TODO daira: add a requirement that makes the initial total issuance match the previous total issuance | ||
| 5. This functionality MUST be introduced as part of a network upgrade | ||
|
tomekpiotrowski marked this conversation as resolved.
Outdated
|
||
|
|
||
|
|
||
| # 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 | ||
|
|
||
| ## Issuance Calculation | ||
|
aphelionz marked this conversation as resolved.
|
||
|
|
||
| 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))` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After the There will be some block height (that should be a constant in this specification section with either a known value or undefined for now) at which this issuance mechanism will first be applied, but that does not necessarily need to coincide with the network upgrade activation height (so e.g. if this were deployed in a NU that activated at height There should also be a section in the Rationale explaining why the (to-be-specified) choice was made.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nathan-at-least This is what we spoke about on our recent call - can you weigh in here?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @str4d I believe I've now addressed this in my latest commit(s) based on the discussion on the Oct 5 Arborist call - can you confirm? |
||
|
|
||
| ## Deployment | ||
|
tomekpiotrowski marked this conversation as resolved.
Outdated
|
||
|
|
||
| TBD | ||
|
teor2345 marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Rationale | ||
|
|
||
| ## `BLOCK_SUBSIDY_FRACTION` | ||
|
|
||
| Let `IntendedZSFFractionRemainingAfterFourYears` = 0.5. | ||
|
|
||
| The value `4126 / 10_000_000_000` satisfies the approximation within +0.002%: | ||
|
|
||
| `(1 - BLOCK_SUBSIDY_FRACTION)^PostBlossomHalvingInterval ≈ IntendedZSFFractionRemainingAfterFourYears` | ||
|
|
||
| Meaning after a period of 4 years around half of `ZSF_BALANCE` will be paid out | ||
| as block subsidies, thus satisfying **R4**. | ||
|
|
||
| TODO for ZIP owners: How many ZEC per day? | ||
|
tomekpiotrowski marked this conversation as resolved.
|
||
|
|
||
| ## `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, taken from the ECC blog post, illustrates the smoothed curve. Note that depending on when the network upgrade takes place the disbursement may temporarily _increase_. | ||
|
teor2345 marked this conversation as resolved.
Outdated
|
||
|
|
||
|  | ||
|
|
||
| [TODO: We should update this graph now showing the deployment at `2726400`] | ||
|
|
||
| # Appendix: Simulation | ||
|
|
||
| We encourage readers to run the following Rust code, which simulates block subsidies. | ||
| According to this simulation, assuming no deflationary action, block subsidies would | ||
| last for approximately 113 years: | ||
|
teor2345 marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Rust Code | ||
|
|
||
| ```rust | ||
| const BLOCKS_PER_YEAR: u32 = 420_768; | ||
|
teor2345 marked this conversation as resolved.
Outdated
|
||
| const ZATOSHIS_PER_ZEC: i64 = 100_000_000; | ||
| // predicted ZEC supply at the next halving (block 2726400) | ||
| const INITIAL_SUPPLY: i64 = 1_574_963_454_129_680; | ||
| const MAX_MONEY: i64 = 21_000_000; | ||
| const INITIAL_SUBSIDIES: i64 = MAX_MONEY * ZATOSHIS_PER_ZEC - INITIAL_SUPPLY; | ||
|
|
||
| const BLOCK_SUBSIDY_NUMERATOR: i64 = 4126; | ||
| const BLOCK_SUBSIDY_DENOMINATOR: i64 = 10_000_000_000; | ||
|
|
||
| fn main() { | ||
| let mut available_subsidies: i64 = INITIAL_SUBSIDIES; | ||
| let mut block: u32 = 0; | ||
|
|
||
| while available_subsidies > 0 { | ||
| let block_subsidy = (available_subsidies * BLOCK_SUBSIDY_NUMERATOR | ||
| + (BLOCK_SUBSIDY_DENOMINATOR - 1)) | ||
| / BLOCK_SUBSIDY_DENOMINATOR; | ||
| available_subsidies -= block_subsidy; | ||
|
|
||
| println!( | ||
| "Block {} (~{:.2} years): Subsidy: {} (~{} ZEC), ZSF: {} (~{} ZEC)", | ||
| block, // current block | ||
| block as f64 / BLOCKS_PER_YEAR as f64, // ~ current year | ||
| block_subsidy, // block subsidy in zatoshis | ||
| block_subsidy / ZATOSHIS_PER_ZEC, // block subsidy in ZEC | ||
| available_subsidies, // available subsidies in zatoshis | ||
| available_subsidies / ZATOSHIS_PER_ZEC // available subsidies in ZEC | ||
| ); | ||
|
|
||
| block += 1; | ||
| } | ||
| } | ||
|
|
||
| ``` | ||
|
|
||
| Last line of output of the above program is: | ||
|
|
||
| `Block 47917869 (~113.88 years): Subsidy: 1 (~0 ZEC), ZSF: 0 (~0 ZEC)` | ||
|
|
||
| Meaning that subsidies will last for 47917869 blocks after the next halving, which is approximately 113 years. | ||
|
|
||
| Note the addition of `BLOCK_SUBSIDY_DENOMINATOR-1` before division to force rounding up of non-zero values. | ||
|
|
||
|
|
||
| # References | ||
|
|
||
| [1] RFC-2119: https://datatracker.ietf.org/doc/html/rfc2119 | ||
|
|
||
| [2] ZIP-200: https://zips.z.cash/zip-0200 | ||
|
|
||
| [3] ZIP-XXX: Placeholder for the ZSF ZIP | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also needs
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @daira is that a note for the ZIP owners? If so, could you clarify? Do I just need to add the anchor to the URL? |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assigned ZIP 234.