diff --git a/src/masternodes/rpc_accounts.cpp b/src/masternodes/rpc_accounts.cpp index 6cfec584c1..fa20337bd3 100644 --- a/src/masternodes/rpc_accounts.cpp +++ b/src/masternodes/rpc_accounts.cpp @@ -1904,7 +1904,7 @@ UniValue getburninfo(const JSONRPCRequest& request) { }; burnView->ForEachAccountHistory(calculateBurnAmounts); - + UniValue result(UniValue::VOBJ); result.pushKV("address", ScriptToString(burnAddress)); result.pushKV("amount", ValueFromAmount(burntDFI)); diff --git a/src/masternodes/rpc_vault.cpp b/src/masternodes/rpc_vault.cpp index 84f506dbb7..18b79db5a8 100644 --- a/src/masternodes/rpc_vault.cpp +++ b/src/masternodes/rpc_vault.cpp @@ -153,13 +153,15 @@ namespace { UniValue loanBalances{UniValue::VARR}; UniValue interestAmounts{UniValue::VARR}; UniValue interestsPerBlockBalances{UniValue::VARR}; + std::map> interestsPerBlockHighPrecision; + base_uint<128> interestsPerBlockValueHighPrecision{0}; + TAmounts interestsPerBlock{}; + CAmount totalInterestsPerBlock{0}; if (auto loanTokens = pcustomcsview->GetLoanTokens(vaultId)) { TAmounts totalBalances{}; TAmounts interestBalances{}; CAmount totalInterests{0}; - CAmount totalInterestsPerBlock{0}; - TAmounts interestsPerBlock{}; for (const auto& loan : loanTokens->balances) { auto token = pcustomcsview->GetLoanTokenByID(loan.first); @@ -173,9 +175,15 @@ namespace { auto price = priceFeed.val->priceRecord[0]; totalInterests += MultiplyAmounts(price, totalInterest); if (verbose) { - auto interestPerBlock = rate->interestPerBlock.GetLow64(); - interestsPerBlock.insert({loan.first, interestPerBlock}); - totalInterestsPerBlock += MultiplyAmounts(price, static_cast(interestPerBlock)); + if (height >= Params().GetConsensus().FortCanningHillHeight) { + auto currentInterestRate = rate->interestPerBlock; + interestsPerBlockValueHighPrecision += (static_cast>(price) * currentInterestRate / COIN); + interestsPerBlockHighPrecision[loan.first] += currentInterestRate; + } else { + auto interestPerBlock = rate->interestPerBlock.GetLow64(); + interestsPerBlock.insert({loan.first, interestPerBlock}); + totalInterestsPerBlock += MultiplyAmounts(price, static_cast(interestPerBlock)); + } } } @@ -188,10 +196,6 @@ namespace { interestValue = ValueFromAmount(totalInterests); loanBalances = AmountsToJSON(totalBalances); interestAmounts = AmountsToJSON(interestBalances); - if (verbose) { - interestsPerBlockBalances = AmountsToJSON(interestsPerBlock); - totalInterestsPerBlockValue = ValueFromAmount(totalInterestsPerBlock); - } } result.pushKV("vaultId", vaultId.GetHex()); @@ -208,6 +212,7 @@ namespace { ratioValue = -1; collateralRatio = -1; totalInterestsPerBlockValue = -1; + interestsPerBlockValueHighPrecision = -1; } result.pushKV("collateralValue", collValue); result.pushKV("loanValue", loanValue); @@ -221,7 +226,25 @@ namespace { nextCollateralRatio = int(rate.val->ratio()); result.pushKV("nextCollateralRatio", nextCollateralRatio); } - result.pushKV("interestPerBlockValue", totalInterestsPerBlockValue); + if (height >= Params().GetConsensus().FortCanningHillHeight) { + if(isVaultTokenLocked){ + result.pushKV("interestPerBlockValue", -1); + } else { + result.pushKV("interestPerBlockValue", GetInterestPerBlockHighPrecisionString(interestsPerBlockValueHighPrecision)); + for (auto it=interestsPerBlockHighPrecision.begin(); it != interestsPerBlockHighPrecision.end(); ++it) { + auto tokenId = it->first; + auto interestPerBlock = it->second; + auto token = pcustomcsview->GetToken(tokenId); + auto amountStr = GetInterestPerBlockHighPrecisionString(interestPerBlock); + auto tokenSymbol = token->CreateSymbolKey(tokenId); + interestsPerBlockBalances.push_back(amountStr + "@" + tokenSymbol); + } + } + } else { + interestsPerBlockBalances = AmountsToJSON(interestsPerBlock); + totalInterestsPerBlockValue = ValueFromAmount(totalInterestsPerBlock); + result.pushKV("interestPerBlockValue", totalInterestsPerBlockValue); + } result.pushKV("interestsPerBlock", interestsPerBlockBalances); } return result; diff --git a/test/functional/feature_loan_priceupdate.py b/test/functional/feature_loan_priceupdate.py index 3525952414..378eb9d033 100755 --- a/test/functional/feature_loan_priceupdate.py +++ b/test/functional/feature_loan_priceupdate.py @@ -7,7 +7,7 @@ from test_framework.authproxy import JSONRPCException from test_framework.test_framework import DefiTestFramework -from decimal import Decimal +from decimal import Decimal, ROUND_DOWN from test_framework.util import assert_equal @@ -18,9 +18,10 @@ class PriceUpdateTest (DefiTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True + self.FCH = 400 self.extra_args = [ - ['-txnotokens=0', '-amkheight=1', '-bayfrontheight=1', '-eunosheight=1', '-txindex=1', '-fortcanningheight=1'] - ] + ['-txnotokens=0', '-amkheight=1', '-bayfrontheight=1', '-eunosheight=1', '-txindex=1', '-fortcanningheight=1', f'-fortcanninghillheight={self.FCH}'] + ] def run_test(self): self.nodes[0].generate(300) @@ -346,5 +347,21 @@ def run_test(self): realInteresAfterOneBlock = Decimal(vaultAfterUpdate["interestAmounts"][0].split('@')[0]) assert_equal(realInteresAfterOneBlock, expectedInterestAfterOneBlock) + # Go after FCH for high precission interestPerBlock and interestPerBlockValue + self.nodes[0].generate(self.FCH - self.nodes[0].getblockcount()) + + vaultAfterUpdate = self.nodes[0].getvault(vaultId1, True) + assert_equal(vaultAfterUpdate["collateralRatio"], vaultBeforeUpdate["nextCollateralRatio"]) + assert_equal(vaultAfterUpdate["nextCollateralRatio"], 3213) + interestPerBlockTSLA = vaultAfterUpdate["interestsPerBlock"][0].split('@')[0] + amountInterestTSLA = vaultAfterUpdate["interestAmounts"][0].split('@')[0] + self.nodes[0].generate(1) + + # Check one block interest is added correctly + vaultAfterUpdate = self.nodes[0].getvault(vaultId1, True) + expectedInterestAfterOneBlock = Decimal(Decimal(amountInterestTSLA) + Decimal(interestPerBlockTSLA)).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + realInteresAfterOneBlock = Decimal(vaultAfterUpdate["interestAmounts"][0].split('@')[0]) + assert_equal(realInteresAfterOneBlock, expectedInterestAfterOneBlock) + if __name__ == '__main__': PriceUpdateTest().main()