LedgerHQ / ledger-nano-s

Ledger Nano S, a personal security device from Ledger (blockchain / bitcoin / ethereum / FIDO)
Apache License 2.0
278 stars 41 forks source link

KMD ledger does not accrue or spend interest #21

Open jl777 opened 7 years ago

jl777 commented 7 years ago

There are two parts to KMD 5% APR. Accruing and spending it. Accruing interest happens on the blockchain and even a paperwallet accrues interest by simply setting the nLockTime field in the transaction to a recent timestamp. This timestamp is needed to know how much time has elapsed when calculating how much interest can be spent. To have a bit of leeway, a wallet can just use the current unixtime - 777 seconds as the value of nLockTime. Basically we just want a locktime that will be accepted into the next block.

What this means is that funds sent to the ledger with nLockTime set, are already accruing interest. Any outgoing transaction should set the nLockTime so there is interest to be collected.

The collection side is a bit more complicated. It is done on a per utxo basis and for each utxo in a transaction's inputs the interest accrued for that utxo increases the effecting sum of inputs. this means it is not only possible but usual for a transaction spending interest to have the sum of vouts being more than the sum of the vins (not counting the interest). So wherever a transaction is being constructed in the wallet and you are calculating the equivalent of inputsum, also need to calculate the sum of interests and then pretend the total value of the inputs was actually (inputsum + interestsum)

The above logic is very wallet specific and it should be applied to all eligible utxo. To be eligible a utxo must be for 10 or more KMD and have nLockTime set and also be more than an hour old. It doesnt take long to do the calculation, so it is ok to just call the komodo_interest() function for every utxo.

The following komodo_interest() function will calculate the amount of accrued interest at the specified time for a utxo. So sum the return values from this function to calculate interestsum.

uint64_t komodo_interest(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime) { int32_t minutes; uint64_t interest = 0; if ( (minutes= (tiptime - nLockTime) / 60) >= 60 ) { if ( minutes > 365 24 60 ) minutes = 365 24 60; minutes -= 59; interest = ((nValue / 10512000) * minutes); } return(interest); }

You would want to call it from an if statement like:

if (  nLockTime >= LOCKTIME_THRESHOLD && tiptime != 0 && nLockTime < tiptime && nValue >= 10*COIN )
    interestsum += komodo_interestnew(nValue,nLockTime,tiptime);

nLockTime is the nLockTime of the utxo transaction where LOCKTIME_THRESHOLD is 500000 (so as to not use the blockheight usage of nLockTime!) nValue is the value of the utxo. tiptime being the time(NULL) - 777, basically a recent unix timestamp COIN is 100000000

I hope I explained this clearly enough, please ask if there are any questions.

Zeehenk commented 6 years ago

BUMP!

Anyone from LEDGER working on this...? Above code is provided by the lead dev of KOMODO and should be enough to solve the issue?

Would be great if this is worked on and solved from your end. Thanks!!

kilimchoi commented 6 years ago

what's the timeline for shipping this?

pinkolin commented 6 years ago

Hello, please, implement interest feature. Annoying.

Zeehenk commented 6 years ago

I believe this is solved: https://techloverhd.com/2017/12/claim-komodo-kmd-interest-ledger-nano-s/

You'll need 2 Ledgers, though.

pinkolin commented 6 years ago

This is not good solution. This is dirty hack (and unsecure hack).

rbaeumler commented 6 years ago

The 2 Ledger solution does not help a lot when you already have your KMDs along with other tokens on your Ledger. You don't want to expose your Nano PK and move all coins afterwards away from this Nano because of the exposed PK.

l0rb commented 6 years ago

The code in the original comment is no longer up to date, as there is now a cap of one month on the amount of interest that can be accrued. @jl777

jl777 commented 6 years ago

correct, but that doesnt activate till height 1 million

sidhujag commented 6 years ago

why is there a cap of 1 month, aren't you accruing a sum (accumulator) to be able to convert from time domain to block domain? Thats the way I do interest in syscoin. I don't want to deviate from the original topic but just curious as to why you are capping to 1 month as some people don't want to be or cannot be around to claim every month. By converting to the block domain you can calculate compounding interest per block and let them claim after any number of blocks (even every block if they want to).

My unit tests here: https://github.com/syscoin/syscoin/blob/master/src/test/syscoin_asset_tests.cpp#L348

The underlying implementation here:

https://github.com/syscoin/syscoin/blob/master/src/assetallocation.cpp#L226

Note in my case the owner of an asset may be configured to be able to actually adjust interest rate dynamically and so an averaging of the interest rate as well as the balance needs to be factored into the rate calculation formula.

jfyi im generally curious and actually care about whats happening as we happen to be in supernet so actively encourage and review work of our partners.

jl777 commented 6 years ago

the rewards system needs to reward the active users more than the passive users. If a monthly usage is too much work to bother with, then it seems they are not so active.

sidhujag commented 6 years ago

so its a demurrage system then effectively

jl777 commented 6 years ago

in a sense, I guess it can be viewed that way. I guess mathematically it is not negative interest and only positive, but has similar outcome if measured relative to overall coin supply. Psychologically, there is no "loss" of coins, so it seems more palatable

sidhujag commented 6 years ago

thanks.. will watch with interest to see how it plays out.