-
Notifications
You must be signed in to change notification settings - Fork 76
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
Feature request: decentralised interest rate application #148
Comments
This has been a topic of discussion for some time at Ivno Towers, so some points that may or may not be helpful:
Just a jumbled brain dump as I don't have a great deal of time - I'll try to expand on these thoughts a bit more eloquently when possible. Overall I think this is an exceptional start, and thanks for starting the discussion Mike! |
I guess you can't end up with negative token amounts, that'd be an obligation wouldn't it. The contract should prevent that from happening: the tx would be invalid if there aren't enough tokens to make the payment after interest rates are applied. However you don't want to discover that at tx verification time, so the vault/SDK needs some notion of balance with rates applied. I think if there's a getter method like this on token states, it could be used:
But of course software has to know to use it in preference to the current value, and there has to be a way to actually get the interest rate history easily. Perhaps the SDK should provide canned vault queries for that. WRT requesting reference states - good question. How people get informed about rate changes in undefined, but the ref states work we did offers an answer: you have to do wrap your spend inside a loop that catches the notary exception thrown when a ref state is invalid, fetches the latest version from the issuer and then retries. There's a system provided flow that handles this for you: https://docs.corda.net/api/kotlin/corda/net.corda.core.flows/-with-referenced-states-flow/index.html This design does indeed mean the provider could be slammed with requests for the new data the moment it starts to apply. Good point and good catch. Corda isn't really designed for HFT so we have a cheap-ass "get out clause", but, it'd be nice to have a better solution. This feels like an incremental sub-unit of work on the path to implementing full DDGs. One possible solution is to for the issuer to pre-push the new rate state changing tx to known high priority customers. This won't work today because that tx wouldn't have a notary signature, but with some vault work we could store such an invalid tx such that when it does get notarised, the notary can just provide its signature that the tx has been committed in the error response saying the ref state was consumed. The node can then apply that sig to its local copy of the tx and send it down the usual Of course that takes us to the direction of duplicate copies of the same reference data on each notary, which the API doesn't assist with today. More work would be useful there to flesh out the multi-notary+ref states story. None of this is actually much coding work. It's all very incremental and just needs careful design. Thanks for the feedback! |
This is a draft design document for interest rates support in the tokens SDK.
Overview
Some users want to apply interest rates to their tokens.
This feature can be used to implement different kinds of monetary policy. For instance, an unbacked token with a positive interest rate that decreases to zero over time could be used to implement a form of monetary distribution similar to what Satoshi implemented for Bitcoin, but without the special privileges awarded to miners. Such coins would just grow in your hands until the total monetary limit is reached.
More conventionally, commercial banks may use the feature to share investment returns with users, or even share investment failures with users by applying a negative interest rate. And central bank issued tokens may attempt to socially engineer particular outcomes, typically GDP growth, by forcing people to spend their savings or lose them. Charging negative interest is a more direct and thus more easily measured and understood mechanism than inflating the currency, which inherently creates distortions in the economy.
Problem statement. The tokens SDK does not implement interest rates. An oft-proposed approach is to periodically bring tokens back to the issuer for value adjustment. This creates problematic privacy, scaling, availability and incentive problems. In particular holders of tokens are not incentivised to return to the issuer if they'd face a negative interest rate, even if they're using tokens where they previously agreed to such negative rates e.g. because the token represents a share in an investment fund. We'd like a better approach.
Commentary. Negative interest rates have historically been seen as impossible or obviously absurd, due partly to lack of enforcement ability. They are deeply controversial and unpopular. We are not unaware of this unpopularity (in fact Switzerland has -0.75% rates today). But even in a world where everyone used Tokens SDK tokens as a replacement for cash, Corda is a general platform. An attempt to force people to use tokens with negative rates would result in people creating their own tokens, and building purely digital FX/OTC markets for them, as we've seen in the cryptocurrency world. Negative rates are most often talked about as a way to force people to spend money, given the apparent contemporary difficulty of creating inflation, thus boosting GDP. As GDP is the primary metric by which economists and politicians are judged this is seen as inherently good. But economic activity for the sake of gaming the measurement criteria of certain social classes is the fallacy of a planned economy. Policymakers who want to use them should consider campaigning for political leadership to be judged by other metrics instead. A focus on GDP growth at any cost will lead to either abandonment of CB managed currencies in favour of privately issued tokens e.g. Libra, or the totalitarianism required to avoid it.
Goals
Non-goals
Design
Design outline
The core idea is to make tokens self-inflating or deflating via the contract logic. Currently the smart contract enforces that during a payment the outputs sum to the value of the inputs. There's no requirement this be so, which is why the contract has to enforce it in the first place.
A new type of linear state can be defined which contains a list of interest rate changes over time (this is the source of the "no constant rate changes" non-goal). Only the issuer of the token may update this state. The rates state is included as a reference state into all transactions that spend the tokens, this is enforced by the token contract.
Each token state contains a timestamp of when the token last had interest applied.
The token contract then examines the timestamp window in the transaction header and takes the start of the time window (NOT the midpoint, as that'd allow arbitrary inflation). It then walks back through the history of rate changes in the ref state, from the tx timestamp until the "last applied" timestamp. It thus obtains a record of what rates were in force during the time this token was static, and can then apply the calculations to verify the final value.
Using tokens from other apps
The token state object should expose a utility method to do this calculation. This logic is of course used in the payment flows, which can invoke it to calculate the expected value during token movement. It should also be used by any other app that wishes to inspect the value of a token state and calculate its "true" value, e.g. if another app allows tokens to be used as reference states as a proof of solvency. Failure to use the interest-applied rate would be a critical bug in the other apps, so, as part of this feature, it may be desirable to make the "true" value of the token private and expose only a getter as a way to calculate the value of the token, however, this would probably be API incompatible. It's possible a new token type should be created, but, the details of that are left for the real design doc (this GitHub issue is only a starting point).
Calculating the monetary base
If the issuer wants to know how many tokens are in circulation at a given moment it can just apply the rate history to all issued tokens to arrive at how much would exist, if all tokens moved at that instant. From an economics perspective this should be sufficient as it's not the historical amount on the ledger that matters but rather how much is actually available to spend.
Time-varying balances in the API
The current Corda API doesn't directly expose any notion of balance. The Tokens SDK should expose such a notion but add support for querying "my expected balance at time T" which would use the new code on the state to apply the rates.
Dust limits
A negative rate erodes tokens such that their value trends to zero without ever actually hitting it.
At some point the value of a token is so low that it doesn't really make sense to store or work with it anymore. This is especially true if there are transaction fees of any sort. In the Bitcoin world we called this "dust" and it could be a significant problem. With time-varying transaction fees, the dust limit is itself variable.
Solving the problem of dust is a non-goal for three reasons:
Conclusion
This issue lays out a design for applying interest rates to tokens in a decentralised, privacy-preserving manner. Tokens never need to be returned to the issuer for value adjustment, yielding large scaling and availability benefits. Tokens representing shared investments may distribute the gains or losses in equally privacy preserving and decentralised manners.
With this power comes responsibility. Tokens that force people to spend them, in order to generate artificial activity for political/marketing reasons, can and should find themselves outcompeted in the market. Corda's transaction and multi-app interop features enable low trust discovery and OTC trading of tokens, and the cryptocurrency community has done many experiments with building truly decentralised trading venues. Such venues would be much easier to build with the facilities of the flow framework.
The text was updated successfully, but these errors were encountered: