**Draft** motion for currency burning

Sorry, the mechanism mentioned in my previous post is not thoughtful. Just as Chronos point out, my objective is find a way to let some exact amounts of NBTs to quit circulation.

Doesn’t this mean it only shifts the dump-risk of one week in the future?

I think using the excess fees as the burned amount will makes the code complex and error prone. It will be even more complex when the fee becomes dynamic. I’d rather use the standard burning mechanism we already use: provably unspendable output with OP_RETURN. And it would allow us to add meta-data.

Right now the unit (NBT or NSR) of a transaction is recorded at transaction level, not at output level. That means that we cannot take NBT and output the change in NBT and the shares in NSR in the same transaction. That was a design choice and I’d rather not change that just to allow this burning process.

Instead we could use 2 transactions: 1 to burn NBT and 1 to generate NSR. The 1st one would make the network accept the 2nd one.

A burning transaction would take some NBT inputs and output the burned NBT to an unspendable script that also provides the NSR address that will be allowed to generate the NSR. The change would be sent to another output as usual and the same fees as in other transactions would be required.

The NSR generation transaction would take the burned NBT as input (without any signature) and output the generated NSR. The network would verify that:

  • the input is a burning transaction (and it’s the only input)
  • the input has not already been used to generate NSR
  • the output address is the one recorded in the burning transaction (split outputs would be allowed, but all to the same address)
  • the total output amount is equal or less than the NSR rate multiplied by the amount burnt (the NSR rate being the vote result in the 60th block before the one that confirmed the burning transaction)

This would be the only situation where a cross unit transaction is allowed (input in (burnt) NBT and output in NSR).

I think both transactions could be confirmed inside the same block, but I’d have to verify that.

All the amounts are expressed as signed or unsigned 64 bits integer so the theoretical limit is 9 223 372 036 854 775 807 satoshis (9e18). But there’s an extra MAX_MONEY constant used at many places that limits most amounts used in the protocol. I think it exists to avoid mistakes and overflow errors. This limit is 2 billion coins right now (20 trillion satoshis). That means you cannot sent or receive more than 2 billions in a transaction. That applies to both NBT and NSR. We can change this value easily (although it’s still a protocol change).

But these limits only apply to individual or transactional amount, not to the total supply. The total supply is not recorded as a value in the blockchain, it’s just the sum of the generated units. The client does record that data in an int64 but it’s only used to display it in the getinfo RPC. Having a total supply above the int64 limit would not break the network, it would just make getinfo return a negative supply.

If we plan to use the total supply as protocol data (to change the reward for example) and expect it to overflow then we can store it in a BigNum (an integer of arbitrary size). But we would also have to do that with many other values (the wallet balance for example). But I think the current limit (9e18) is large enough.

One way to do that would be to vote for a burnable amount with an identifier like we vote for custodians with an address. Once a burn amount has been granted people would be allowed to burn NBT with this identifier until the burned amount on this identifier reach the voted amount.

For example a shareholder could vote to burn 1 million NBT at rate 0.003 with identifier “1”. If the majority of shareholders vote for the same amount and rate on this identifier, then this burn vote passes and is recorded in the blockchain.

The network would then allow burning transactions that mention the identifier “1”, but only until the total burned amount on this identifier reach 1 million. After that any burn with this identifier would be rejected by the network.

There may be multiple burn identifiers allowed at the same time.

1 Like

That’s much different than using a rolling median. However, it seems that the identifier-quantity feature could be used with the 10000-block median vote outlined by Jordan. Is this correct?

Assuming the cause of the trouble in maintaining the peg is that there are too many NBT in circulation (Nb) compared to the networth of Nunet in dollars (call it V for value), then the amount of NBT burned (x) to restore equilibrium can be calculated. The euqation is Nb - x = V + Rb * x * (V/Ns), where Ns is the total number of Nushares, Rb is the burn rate (Nushares per Nubit), and (V/Ns) the Ns price per net value of Nunet. If we use market price of NSR/USD for (V/Ns), then x can be calculated with a given Rb.

A special solution is Rb=0, which means someone holding NBT burns NBTs without getting any NSR in return, until all excess NBT is gone.

V is a combination of how many USD in NuNet reserve, how much liquade asset NuNet has, and profit earning prospect. The price of NuShares (V/Ns) and the ending of the NuNet is tied to these three factors.

Yes we could have the rate voted separately with a median. The other vote would only allow a certain quantity to be converted.

My proposal was based on the premise that the currency marker was at the output level, not the transaction level, which means some modifications are needed.

I am hesitant to use two separate transactions because the two actions (currency burning and NSR creation) should either both fail or both succeed. Using separate transactions introduces an opportunity for one to succeed and the other to fail. We can be certain many efforts will be made to attempt to make the burning transaction fail while permiting the NSR creation to succeed. Having NSR created based on a separate zero confirmation burn transaction seems particularly open to exploit.

One option would be to define a special type of transaction specific to burning where it is understood that the currency marker applies to inputs but that the outputs are always NSR. This would mean the outputs would be restricted to NSR, and would not be permitted to be a mixture of NSR and currency as previously proposed. This transaction type would be just like the popular Pay to PubKey Hash except that the outputs would be handled as NSR instead of the currency specified at the transaction level and it would have the special validation described in my draft motion content.

The protocol provides a mechanism for currency placed in an OP_RETURN to be restored via unparking. Using the same approach for burning brings with it a risk that someone will figure out a way to unpark a currency burning transaction. In contrast, there is no mechanism to restore transaction fees.

I’m not only hesitant, I consider it unthinkable, after having read what you wrote about using two transactions. If this process isn’t atomic it is easier to exploit it - just like you pointed out.

I don’t see important technical drawbacks by doing it that way. Does anyone see any?
One needs to use a proper input value, sure. That is made easier by coin control, because you’re able to split transactions so that there is the right amount that shall be burned available in a single transaction. As far as I got it, integrating coin control in the wallet (for both NBT and NSR?) is on the road map. So it is only a matter of time until it is available.

And it is matter of education to explain what preparations need to be done to avoid accidentally burning “wrong” (read: way too large) amounts of NBT.

So the drawbacks might be mainly in the fields of human error.

As long as coin control is not available you can use different wallets to make sure you have the right amount of NBT in the transaction you want to use for burning. That is not very comfortable, but very safe, because you can’t burn more NBT than you have in your wallet :wink:

The option that you described sounds like a perfect way to make it as hard as possible to abuse this mechanism.
I understand that it’s expected to use the burn mechanism only in (hopefully!) very rare cases and that in “normal” times you receive 0 NSR for any amount of burned NBT.
But as a vote for burning is an action of last resort, it’s important that the shareholders can rely on the burning to not be exploited easily.

1 Like

masterOfDisaster helped me realize that not permitting change in currency is indeed less than user friendly, especially without coin control, which is currently planned for inclusion in version 0.5.1.

There is quite a bit we can do with the user interface to protect them from currency loss or converting a larger amount than intended to NSR. It might also be reasonable to use an ordinary transaction to create outputs of the perfect size to complete the user’s currency burning transaction. For instance, a user may wish to burn 100 NBT but he has an output of 140 NBT. An ordinary transaction could create an output of 100 NBT and place the rest in a change address. Then the 100 NBT output is used as the input for the currency burning transaction. From the user perspective, they are able to burn whatever quantity they want and the result is NBT in a change address and NSR in a specified address.

We would include a separate dialog for burning where the user can enter a quantity of currency to be converted, an NSR address and an optional currency change address (if not specified use one from the wallet). The interface would tell the user how many NSR they would receive and what their transaction fee would be.

In the background a preparatory transaction would be performed to create an output exactly the size the user specified for conversion. While this needs some verification, I believe the network would accept both transactions, but confirm them in different blocks.

@JordanLee Should voters consider the estimated cost to shareholders to have this feature implemented? The protocol and UI changes will take significant work that (I assume) will be paid out of the shareholder resources. Please correct me if this is not the case.

Thank you in advance for any details you can provide on this.

As is typical with software development, estimates of cost are difficult and subject to considerable inaccuracy. However, an uncertain estimate provides a better basis for decision making than not having any idea about the cost.

I’ll put forward an estimate of 8000 NBT for development and 12000 NBT for testing, which I will insist is quite extensive. So, I would estimate a total cost of 20,000 NBT.

Only vote for exchange rate is enough. When NBT works fine, we can vote for a very high rate to prevent exchange. But if sb. would like to exchange, these NBT could be profit immediately.

When NBT is over supplied, shareholders vote for a lower price to incentive NBT exchange to NSR.

1 Like

Only voting for exchange rate should be good enough. This rate would be variable and when shareholders are well-informed the rate would be adjusted when there are indicators that the money supply need to be decreased and large NBT bagholders are still interested in buying NSR.

Maybe it should also be possible to burn NSR and get NBT against that same rate, that way it would be easier to maintain a balance as unintended transfers can be easily reversed. Although unlikely to happen a minimum number of shares (e.g. 0.5b) should be hardcoded otherwise the network might fail to create enough blocks.

Did we just invent a decentralised exchange for NSR<>NBT (or any future coins we may list) here?

No. Only burning NBT can exchange NSR, never burning NSR for NBT. Because this system’s value is NBT equal to 1 USD for ever. All effort we make aim to this goal. We mustn’t make anything else which give risk on this goal.

1 Like

The goal is right. But since the share owners are already capable of creating NBT by offering parking interest, so letting them allow NSR->NBT exchange isn’t a big impact on principle. But I do realize it’s a slippery slope. The solution should be well thought out and critically reviewed on system level.

If it’s an end-of-currency problem we are going to solve, we still have time – Nu is only one month old. If the problem is that not having a burn mechanism is hurting adoption evidently, then we should start to work out a solution right away. From what I understand, Jordan thinks that offering a solution to questions one is a solution to question two. I am having difficulty knowing all the factors for an end-of-currency scenario. A convincing profit/revenue model seems easier to think about at this point as a long-term solution to the NBT over-supply concern.

When the price of NSR going down, shareholder will exchange to NBT and sell NBT on market for NSR. This can impact the buy wall.

How is that different from creating NBT through custodians by shareholders?
I agree that this needs more thoughts, but might have some advantages.
But I don’t see shareholders selling NSR for NBT as a problem given they already have capability to create NBT.

But I’m digressing, I think we should focus on the scenarios for an end game as that might be a marketing/trust issue when not addressed somehow.

We can make sure that the NSR creation transaction is not possible without the currency burning transaction. That’s how everything works already (you can’t spend coins you haven’t received).

We can’t make sure there will be an NSR creation after a currency burning though, but we can’t prevent it either (unless the majority of minters makes the efforts to prevent it).

So the minimum requirement is filled: people will not be able to generate NSR without burning a currency.

It’s not based on a zero confirmation transaction. It’s based on a transaction confirmed either in the same block or in a previous one. To be accepted in a block a NSR creation transaction needs a corresponding NBT transaction in the same block or a previous one. So if the NBT burning transaction gets unconfirmed for any reason, the NSR transaction also becomes unconfirmed and cannot be put inside another block until the new chain also includes the NBT burning transaction. Like any spend.

But you also need the change in NBT.

Also, having an exception about the currency of an output means we have to change all the code for which the currency of an output matters. It introduces complexity and we can forget to change some code or introduce mistakes. The design choice to use units at transaction level was to keep things simple and to strongly reduce the risk of a bug allowing unit fungibility. If we’re going to leave this paradigm we’d probably better just move the unit to the output instead of adding an exception, to at least keep simplicity.

And note that adding an exception to the output unit makes it possible to be exploited too. If we make a mistake in the code someone may be able to convert some NBT to NSR outside the burning process.

The code allowing an OP_RETURN output to be spent is clearly isolated and has very strong requirements. Adding another exception with requirements that do not overlap is easy.

The transaction fees system is complex and involves a lot of code split in many places (from the blockchain to the GUI).

I feel much more confident the unparking mechanism can’t be exploited to restore other OP_RETURN outputs than our ability to add this new complexity without bugs inside the already complex fees system.

This seems overly complex to me. To avoid creating 2 almost standard transactions in 2 different units we would create a first transaction to split the coins and then another one with a exceptionally different input and output unit.

I think they should. But as Jordan said it’s hard to estimate. In general the simple designs cost less in coding, testing and maintenance.

I may be able to estimate the time I need to code some of the designs that were discussed here, but it also takes time to work on these estimates. And when the design is complex it may be hard or impossible to estimate. And I can’t estimate the time required in testing and maintenance.

1 Like

Actually we can certainly force the 2 transactions to be in the same block. The block would be rejected if it doesn’t include the 2 transactions. We would have to change the way memory pool transactions are included in a newly generated block but it shouldn’t be too hard.

I haven’t forgotten about this but it has been deprioritized just a bit. At the moment there is not agreement between sigmike and I on how to proceed. I suspect we can come to an agreement by researching the code and then discussing the advantages and disadvantages of each approach further, but that will need to wait.