Skip to content

Commit

Permalink
Fix interestPerBlock for high precision values (#1405)
Browse files Browse the repository at this point in the history
* Add high precission string for getvault verbose

* Fixes error, return -1 when there are locked tokens

* Minor refactors

Co-authored-by: dcorral <[email protected]>
  • Loading branch information
prasannavl and dcorral authored Aug 2, 2022
1 parent ced7b66 commit 3313a76
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/masternodes/rpc_accounts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
43 changes: 33 additions & 10 deletions src/masternodes/rpc_vault.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,15 @@ namespace {
UniValue loanBalances{UniValue::VARR};
UniValue interestAmounts{UniValue::VARR};
UniValue interestsPerBlockBalances{UniValue::VARR};
std::map<DCT_ID, base_uint<128>> 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);
Expand All @@ -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<CAmount>(interestPerBlock));
if (height >= Params().GetConsensus().FortCanningHillHeight) {
auto currentInterestRate = rate->interestPerBlock;
interestsPerBlockValueHighPrecision += (static_cast<base_uint<128>>(price) * currentInterestRate / COIN);
interestsPerBlockHighPrecision[loan.first] += currentInterestRate;
} else {
auto interestPerBlock = rate->interestPerBlock.GetLow64();
interestsPerBlock.insert({loan.first, interestPerBlock});
totalInterestsPerBlock += MultiplyAmounts(price, static_cast<CAmount>(interestPerBlock));
}
}
}

Expand All @@ -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());
Expand All @@ -208,6 +212,7 @@ namespace {
ratioValue = -1;
collateralRatio = -1;
totalInterestsPerBlockValue = -1;
interestsPerBlockValueHighPrecision = -1;
}
result.pushKV("collateralValue", collValue);
result.pushKV("loanValue", loanValue);
Expand All @@ -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;
Expand Down
23 changes: 20 additions & 3 deletions test/functional/feature_loan_priceupdate.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Expand Down Expand Up @@ -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()

0 comments on commit 3313a76

Please sign in to comment.